rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions
TunerStudio Class Reference

#include <tunerstudio_impl.h>

Inheritance diagram for TunerStudio:
Inheritance graph
[legend]
Collaboration diagram for TunerStudio:
Collaboration graph
[legend]

Public Member Functions

int handleCrcCommand (TsChannelBase *tsChannel, char *data, int incomingPacketSize)
 
bool handlePlainCommand (TsChannelBase *tsChannel, uint8_t command)
 
void cmdOutputChannels (TsChannelBase *tsChannel, uint16_t offset, uint16_t count) override
 'Output' command sends out a snapshot of current values Gauges refresh
 
void handleQueryCommand (TsChannelBase *tsChannel, ts_response_format_e mode)
 
void handleExecuteCommand (TsChannelBase *tsChannel, char *data, int incomingPacketSize)
 
void handleWriteChunkCommand (TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count, void *content)
 
void handleCrc32Check (TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count)
 
void handlePageReadCommand (TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count)
 
void handleScatteredReadCommand (TsChannelBase *tsChannel)
 

Private Member Functions

void sendErrorCode (TsChannelBase *tsChannel, uint8_t code, const char *msg="")
 

Additional Inherited Members

Detailed Description

Definition at line 23 of file tunerstudio_impl.h.

Member Function Documentation

◆ cmdOutputChannels()

void TunerStudio::cmdOutputChannels ( TsChannelBase tsChannel,
uint16_t  offset,
uint16_t  count 
)
overridevirtual

'Output' command sends out a snapshot of current values Gauges refresh

collect data from all models

collect data from all models

Implements TunerStudioBase.

Definition at line 23 of file tunerstudio_commands.cpp.

23 {
24 if (offset + count > TS_TOTAL_OUTPUT_SIZE) {
25 efiPrintf("TS: Version Mismatch? Too much outputs requested offset=%d + count=%d/total=%d", offset, count,
26 TS_TOTAL_OUTPUT_SIZE);
27 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "cmd_size");
28 return;
29 }
30
31 if (offset < BLOCKING_FACTOR) {
34 }
35
38 // this method is invoked too often to print any debug information
39 uint8_t * scratchBuffer = (uint8_t *)tsChannel->scratchBuffer;
40 /**
41 * collect data from all models
42 */
43 FragmentList list = getLiveDataFragments();
44
45 uint32_t crc = tsChannel->writePacketHeader(TS_RESPONSE_OK, count);
46
47 while (count) {
48 size_t chunkSize = minI(count, sizeof(tsChannel->scratchBuffer));
49 /**
50 * collect data from all models
51 */
52 size_t actualSize = copyRange(scratchBuffer, list, offset, chunkSize);
53 crc = tsChannel->writePacketBody(scratchBuffer, actualSize, crc);
54
55 count -= chunkSize;
56 offset += chunkSize;
57 }
58
59 tsChannel->writeCrcPacketTail(crc);
60}
TunerStudioOutputChannels outputChannels
Definition engine.h:113
char scratchBuffer[scratchBuffer_SIZE+30]
uint32_t writePacketHeader(const uint8_t responseCode, const size_t size)
uint32_t writePacketBody(const uint8_t *buf, const size_t size, uint32_t crc)
void writeCrcPacketTail(uint32_t crc)
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code, const char *msg="")
static EngineAccessor engine
Definition engine.h:421
FragmentList getLiveDataFragments()
tunerstudio_counters_s tsState
void updateTunerStudioState()
uint16_t offset
Definition tunerstudio.h:0
uint16_t count
Definition tunerstudio.h:1
static Timer channelsRequestTimer

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCrc32Check()

void TunerStudio::handleCrc32Check ( TsChannelBase tsChannel,
uint16_t  page,
uint16_t  offset,
uint16_t  count 
)

Definition at line 358 of file tunerstudio.cpp.

358 {
360
361 // Ensure we are reading from in bounds
362 if (validateOffsetCount(page, offset, count, tsChannel)) {
363 tunerStudioError(tsChannel, "ERROR: CRC out of range");
364 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
365 return;
366 }
367
368 const uint8_t* start = getWorkingPageAddr(tsChannel, page, offset);
369 if (start == nullptr) {
370 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: CRC invalid page");
371 return;
372 }
373
374 uint32_t crc = SWAP_UINT32(crc32(start, count));
375 tsChannel->sendResponse(TS_CRC, (const uint8_t *) &crc, 4);
376 // todo: rename to onConfigCrc?
378}
static void onConfigOnStartUpOrBurn(bool isRunningOnBurn)
void sendResponse(ts_response_format_e mode, const uint8_t *buffer, int size, bool allowLongPackets=false)
uint32_t SWAP_UINT32(uint32_t x)
Definition efilib.h:27
static uint8_t * getWorkingPageAddr(TsChannelBase *tsChannel, size_t page, size_t offset)
static bool validateOffsetCount(size_t page, size_t offset, size_t count, TsChannelBase *tsChannel)
void tunerStudioError(TsChannelBase *tsChannel, const char *msg)
uint16_t page
Definition tunerstudio.h:0
@ TS_CRC

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCrcCommand()

int TunerStudio::handleCrcCommand ( TsChannelBase tsChannel,
char data,
int  incomingPacketSize 
)

Definition at line 816 of file tunerstudio.cpp.

816 {
818
819 char command = data[0];
820 data++;
821
822 const uint16_t* data16 = reinterpret_cast<uint16_t*>(data);
823
824 // only few command have page argument, default page is 0
825 uint16_t page = 0;
826 uint16_t offset = 0;
827 uint16_t count = 0;
828
829 // command may not have offset field - keep safe default value
830 // not used by .ini at the moment TODO actually use that version of the command in the .ini
831 if (incomingPacketSize >= 3) {
832 offset = data16[0];
833 }
834 // command may not have count/size filed - keep safe default value
835 if (incomingPacketSize >= 5) {
836 count = data16[1];
837 }
838
839 switch(command)
840 {
841 case TS_OUTPUT_COMMAND:
842 if (incomingPacketSize == 1) {
843 // Read command with no offset and size - read whole livedata
844 count = TS_TOTAL_OUTPUT_SIZE;
845 }
846 cmdOutputChannels(tsChannel, offset, count);
847 break;
848 case TS_OUTPUT_ALL_COMMAND:
849 offset = 0;
850 count = TS_TOTAL_OUTPUT_SIZE;
851 // TS will not use this command until ochBlockSize is bigger than blockingFactor and prefer ochGetCommand :(
852 cmdOutputChannels(tsChannel, offset, count);
853 break;
854 case TS_GET_SCATTERED_GET_COMMAND:
855#if EFI_TS_SCATTER
857#else
858 criticalError("Slow/wireless mode not supported");
859#endif // EFI_TS_SCATTER
860 break;
861 case TS_HELLO_COMMAND:
862 handleQueryCommand(tsChannel, TS_CRC);
863 break;
864 case TS_GET_FIRMWARE_VERSION:
865 handleGetVersion(tsChannel);
866 break;
867#if EFI_TEXT_LOGGING
868 case TS_GET_TEXT:
869 handleGetText(tsChannel);
870 break;
871#endif // EFI_TEXT_LOGGING
872 case TS_EXECUTE:
873 handleExecuteCommand(tsChannel, data, incomingPacketSize - 1);
874 break;
875 case TS_CHUNK_WRITE_COMMAND:
876 /* command with page argument */
877 page = data16[0];
878 offset = data16[1];
879 count = data16[2];
881 break;
882 case TS_CRC_CHECK_COMMAND:
883 /* command with page argument */
884 page = data16[0];
885 offset = data16[1];
886 count = data16[2];
887 handleCrc32Check(tsChannel, page, offset, count);
888 break;
889 case TS_BURN_COMMAND:
890 /* command with page argument */
891 page = data16[0];
892 handleBurnCommand(tsChannel, page);
893 break;
894 case TS_READ_COMMAND:
895 /* command with page argument */
896 page = data16[0];
897 offset = data16[1];
898 count = data16[2];
900 break;
901 case TS_TEST_COMMAND:
902 [[fallthrough]];
903 case 'T':
904 handleTestCommand(tsChannel);
905 break;
906 case TS_GET_CONFIG_ERROR:
907 handleGetConfigErorr(tsChannel);
908 break;
909#if EFI_SIMULATOR
910 case TS_SIMULATE_CAN:
911 void handleWrapCan(TsChannelBase* tsChannel, char *data, int incomingPacketSize);
912 handleWrapCan(tsChannel, data, incomingPacketSize - 1);
913 break;
914#endif // EFI_SIMULATOR
915 case TS_IO_TEST_COMMAND:
916#if EFI_SIMULATOR || EFI_PROD_CODE
917 //TODO: Why did we process `TS_IO_TEST_COMMAND` only in prod code? I've just turned it on for simulator as well, because
918 // I need test this functionality with simulator as well. We need to review the cases when we really need to turn off
919 // `TS_IO_TEST_COMMAND` processing. Do we really need guards below?
920 {
921 uint16_t subsystem = SWAP_UINT16(data16[0]);
922 uint16_t index = SWAP_UINT16(data16[1]);
923
924 executeTSCommand(subsystem, index);
925 }
926#endif /* EFI_SIMULATOR || EFI_PROD_CODE */
927 sendOkResponse(tsChannel);
928 break;
929#if EFI_TOOTH_LOGGER
930 case TS_SET_LOGGER_SWITCH:
931 switch(data[0]) {
932 case TS_COMPOSITE_ENABLE:
934 break;
935 case TS_COMPOSITE_DISABLE:
937 break;
938 case TS_COMPOSITE_READ:
939 {
940 auto toothBuffer = GetToothLoggerBufferNonblocking();
941
942 if (toothBuffer) {
943 tsChannel->sendResponse(TS_CRC, reinterpret_cast<const uint8_t*>(toothBuffer->buffer), toothBuffer->nextIdx * sizeof(composite_logger_s), true);
944
945 ReturnToothLoggerBuffer(toothBuffer);
946 } else {
947 // TS asked for a tooth logger buffer, but we don't have one to give it.
948 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
949 }
950 }
951 break;
952#ifdef TRIGGER_SCOPE
953 case TS_TRIGGER_SCOPE_ENABLE:
955 break;
956 case TS_TRIGGER_SCOPE_DISABLE:
958 break;
959 case TS_TRIGGER_SCOPE_READ:
960 {
961 const auto& buffer = triggerScopeGetBuffer();
962
963 if (buffer) {
964 tsChannel->sendResponse(TS_CRC, buffer.get<uint8_t>(), buffer.size(), true);
965 } else {
966 // TS asked for a tooth logger buffer, but we don't have one to give it.
967 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
968 }
969 }
970 break;
971#endif // TRIGGER_SCOPE
972 default:
973 // dunno what that was, send NAK
974 return false;
975 }
976
977 sendOkResponse(tsChannel);
978
979 break;
980 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
981 {
983
984 auto toothBuffer = GetToothLoggerBufferNonblocking();
985
986 if (toothBuffer) {
987 tsChannel->sendResponse(TS_CRC, reinterpret_cast<const uint8_t*>(toothBuffer->buffer), toothBuffer->nextIdx * sizeof(composite_logger_s), true);
988
989 ReturnToothLoggerBuffer(toothBuffer);
990 } else {
991 // TS asked for a tooth logger buffer, but we don't have one to give it.
992 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
993 }
994 }
995
996 break;
997#else // EFI_TOOTH_LOGGER
998 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
999 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
1000 break;
1001#endif /* EFI_TOOTH_LOGGER */
1002#if ENABLE_PERF_TRACE
1003 case TS_PERF_TRACE_BEGIN:
1005 sendOkResponse(tsChannel);
1006 break;
1007 case TS_PERF_TRACE_GET_BUFFER:
1008 {
1009 auto trace = perfTraceGetBuffer();
1010 tsChannel->sendResponse(TS_CRC, trace.get<uint8_t>(), trace.size(), true);
1011 }
1012
1013 break;
1014#else
1015 case TS_PERF_TRACE_BEGIN:
1016 criticalError("TS_PERF_TRACE not supported");
1017 break;
1018 case TS_PERF_TRACE_GET_BUFFER:
1019 criticalError("TS_PERF_TRACE_GET_BUFFER not supported");
1020 break;
1021#endif /* ENABLE_PERF_TRACE */
1022 case TS_QUERY_BOOTLOADER: {
1023 uint8_t bldata = TS_QUERY_BOOTLOADER_NONE;
1024#if EFI_USE_OPENBLT
1025 bldata = TS_QUERY_BOOTLOADER_OPENBLT;
1026#endif
1027
1028 tsChannel->sendResponse(TS_CRC, &bldata, 1, false);
1029 break;
1030 }
1031 default:
1032 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND, "unknown_command");
1033static char tsErrorBuff[80];
1034 chsnprintf(tsErrorBuff, sizeof(tsErrorBuff), "ERROR: ignoring unexpected command %d [%c]", command, command);
1035 tunerStudioError(tsChannel, tsErrorBuff);
1036 return false;
1037 }
1038
1039 return true;
1040}
void executeTSCommand(uint16_t subsystem, uint16_t index)
size_t size() const
Definition big_buffer.h:43
const TBuffer * get() const
Definition big_buffer.h:34
void handleScatteredReadCommand(TsChannelBase *tsChannel)
void handleCrc32Check(TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count)
void handleQueryCommand(TsChannelBase *tsChannel, ts_response_format_e mode)
void cmdOutputChannels(TsChannelBase *tsChannel, uint16_t offset, uint16_t count) override
'Output' command sends out a snapshot of current values Gauges refresh
void handlePageReadCommand(TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count)
void handleWriteChunkCommand(TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count, void *content)
void handleExecuteCommand(TsChannelBase *tsChannel, char *data, int incomingPacketSize)
uint16_t SWAP_UINT16(uint16_t x)
Definition efilib.h:22
const BigBufferHandle perfTraceGetBuffer()
void perfTraceEnable()
@ TunerStudioHandleCrcCommand
void DisableToothLogger()
void EnableToothLogger()
CompositeBuffer * GetToothLoggerBufferNonblocking()
void ReturnToothLoggerBuffer(CompositeBuffer *buffer)
void EnableToothLoggerIfNotEnabled()
composite_logger_s
void triggerScopeEnable()
const BigBufferHandle & triggerScopeGetBuffer()
static BigBufferHandle buffer
void triggerScopeDisable()
static void handleGetVersion(TsChannelBase *tsChannel)
static void handleGetConfigErorr(TsChannelBase *tsChannel)
static void handleGetText(TsChannelBase *tsChannel)
static void sendOkResponse(TsChannelBase *tsChannel)
static void handleTestCommand(TsChannelBase *tsChannel)
static void handleBurnCommand(TsChannelBase *tsChannel, uint16_t page)

Referenced by tsProcessOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleExecuteCommand()

void TunerStudio::handleExecuteCommand ( TsChannelBase tsChannel,
char data,
int  incomingPacketSize 
)

Definition at line 805 of file tunerstudio.cpp.

805 {
806 data[incomingPacketSize] = 0;
807 char *trimmed = efiTrim(data);
808#if EFI_SIMULATOR
809 logMsg("execute [%s]\r\n", trimmed);
810#endif // EFI_SIMULATOR
811 (console_line_callback)(trimmed);
812
813 tsChannel->writeCrcResponse(TS_RESPONSE_OK);
814}
void writeCrcResponse(uint8_t responseCode)
char * efiTrim(char *param)
Definition efilib.cpp:40
CommandHandler console_line_callback

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handlePageReadCommand()

void TunerStudio::handlePageReadCommand ( TsChannelBase tsChannel,
uint16_t  page,
uint16_t  offset,
uint16_t  count 
)

Definition at line 427 of file tunerstudio.cpp.

427 {
429
430 if (validateOffsetCount(page, offset, count, tsChannel)) {
431 tunerStudioError(tsChannel, "ERROR: RD out of range");
432 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
433 return;
434 }
435
436 uint8_t* addr = getWorkingPageAddr(tsChannel, page, offset);
437 if (page == TS_PAGE_SETTINGS) {
438 if (isLockedFromUser()) {
439 // to have rusEFI console happy just send all zeros within a valid packet
440 addr = (uint8_t*)&tsChannel->scratchBuffer + TS_PACKET_HEADER_SIZE;
441 memset(addr, 0, count);
442 }
443 }
444
445 if (addr == nullptr) {
446 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: RD invalid page");
447 return;
448 }
449
450 tsChannel->sendResponse(TS_CRC, addr, count);
451#if EFI_TUNER_STUDIO_VERBOSE
452// efiPrintf("Sending %d done", count);
453#endif
454}
constexpr uint8_t addr
Definition ads1015.cpp:14
bool isLockedFromUser()
Definition engine2.cpp:311

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handlePlainCommand()

bool TunerStudio::handlePlainCommand ( TsChannelBase tsChannel,
uint8_t  command 
)

handle non CRC wrapped command

Returns
true if legacy command was processed, false otherwise

http://www.msextra.com/forums/viewtopic.php?f=122&t=48327 Response from TS support: This is an optional command * "The F command is used to find what ini. file needs to be loaded in TunerStudio to match the controller. If you are able to just make your firmware ignore the command that would work. Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."

Definition at line 582 of file tunerstudio.cpp.

582 {
583 // Bail fast if guaranteed not to be a plain command
584 if (command == 0) {
585 return false;
586 } else if (command == TS_HELLO_COMMAND || command == TS_QUERY_COMMAND) {
587 // We interpret 'Q' as TS_HELLO_COMMAND, since TS uses hardcoded 'Q' during ECU detection (scan all serial ports)
588 efiPrintf("Got naked Query command");
589 handleQueryCommand(tsChannel, TS_PLAIN);
590 return true;
591 } else if (command == TS_TEST_COMMAND || command == 'T') {
592 handleTestCommand(tsChannel);
593 return true;
594 } else if (command == TS_COMMAND_F) {
595 /**
596 * http://www.msextra.com/forums/viewtopic.php?f=122&t=48327
597 * Response from TS support: This is an optional command *
598 * "The F command is used to find what ini. file needs to be loaded in TunerStudio to match the controller.
599 * If you are able to just make your firmware ignore the command that would work.
600 * Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."
601 */
602
603 tunerStudioDebug(tsChannel, "not ignoring F");
604 tsChannel->write((const uint8_t *)TS_PROTOCOL, strlen(TS_PROTOCOL));
605 tsChannel->flush();
606 return true;
607 } else {
608 // This wasn't a valid command
609 return false;
610 }
611}
virtual void flush()
virtual void write(const uint8_t *buffer, size_t size, bool isEndOfPacket=false)=0
void tunerStudioDebug(TsChannelBase *tsChannel, const char *msg)
@ TS_PLAIN

Referenced by tsProcessOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleQueryCommand()

void TunerStudio::handleQueryCommand ( TsChannelBase tsChannel,
ts_response_format_e  mode 
)

this command is part of protocol initialization

this command is part of protocol initialization

Query with CRC takes place while re-establishing connection Query without CRC takes place on TunerStudio startup

Definition at line 570 of file tunerstudio.cpp.

570 {
572 const char *signature = getTsSignature();
573
574 tsChannel->sendResponse(mode, (const uint8_t *)signature, strlen(signature) + 1);
575}
const char * getTsSignature()
Definition signature.cpp:31

Referenced by handleCrcCommand(), and handlePlainCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleScatteredReadCommand()

void TunerStudio::handleScatteredReadCommand ( TsChannelBase tsChannel)

Definition at line 381 of file tunerstudio.cpp.

381 {
383
384 int totalResponseSize = 0;
385 for (size_t i = 0; i < TS_SCATTER_OFFSETS_COUNT; i++) {
386 uint16_t packed = tsChannel->page1.highSpeedOffsets[i];
387 uint16_t type = packed >> 13;
388
389 size_t size = type == 0 ? 0 : 1 << (type - 1);
390#if EFI_SIMULATOR
391// printf("handleScatteredReadCommand 0x%x %d %d\n", packed, size, offset);
392#endif /* EFI_SIMULATOR */
393 totalResponseSize += size;
394 }
395#if EFI_SIMULATOR
396// printf("totalResponseSize %d\n", totalResponseSize);
397#endif /* EFI_SIMULATOR */
398
399 // Command part of CRC
400 uint32_t crc = tsChannel->writePacketHeader(TS_RESPONSE_OK, totalResponseSize);
401
402 uint8_t dataBuffer[8];
403 for (size_t i = 0; i < TS_SCATTER_OFFSETS_COUNT; i++) {
404 uint16_t packed = tsChannel->page1.highSpeedOffsets[i];
405 uint16_t type = packed >> 13;
406 uint16_t offset = packed & 0x1FFF;
407
408 if (type == 0)
409 continue;
410 size_t size = 1 << (type - 1);
411
412 // write each data point and CRC incrementally
413 copyRange(dataBuffer, getLiveDataFragments(), offset, size);
414 tsChannel->write(dataBuffer, size, false);
415 crc = crc32inc((void*)dataBuffer, crc, size);
416 }
417#if EFI_SIMULATOR
418// printf("CRC %x\n", crc);
419#endif /* EFI_SIMULATOR */
420 // now write total CRC
421 *(uint32_t*)dataBuffer = SWAP_UINT32(crc);
422 tsChannel->write(dataBuffer, 4, true);
423 tsChannel->flush();
424}
uint16_t highSpeedOffsets[TS_SCATTER_OFFSETS_COUNT]
composite packet size

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleWriteChunkCommand()

void TunerStudio::handleWriteChunkCommand ( TsChannelBase tsChannel,
uint16_t  page,
uint16_t  offset,
uint16_t  count,
void *  content 
)

This command is needed to make the whole transfer a bit faster

Definition at line 307 of file tunerstudio.cpp.

308 {
310
311 efiPrintf("TS -> Page %d write chunk offset %d count %d (output_count=%d)",
313
314
315 if (validateOffsetCount(page, offset, count, tsChannel)) {
316 tunerStudioError(tsChannel, "ERROR: WR out of range");
317 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
318 return;
319 }
320
321 uint8_t * addr = getWorkingPageAddr(tsChannel, page, offset);
322 if (addr == nullptr) {
323 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: WR invalid page");
324 return;
325 }
326
328
329 // Special case
330 if (page == TS_PAGE_SETTINGS) {
331 if (isLockedFromUser()) {
332 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND, "locked");
333 return;
334 }
335
336 // Skip the write if a preset was just loaded - we don't want to overwrite it
337 // [tag:popular_vehicle]
338 if (!needToTriggerTsRefresh()) {
339 memcpy(addr, content, count);
340 } else {
341 efiPrintf("Ignoring TS -> Page %d write chunk offset %d count %d (output_count=%d)",
342 page,
343 offset,
344 count,
346 );
347 }
348 // Force any board configuration options that humans shouldn't be able to change
349 // huh, why is this NOT within above 'needToTriggerTsRefresh()' condition?
351 } else {
352 memcpy(addr, content, count);
353 }
354
355 sendOkResponse(tsChannel);
356}
static bool call_board_override(std::optional< FuncType > board_override, Args &&... args)
std::optional< setup_custom_board_overrides_type > custom_board_ConfigOverrides
bool needToTriggerTsRefresh()
static void onCalibrationWrite(uint16_t page, uint16_t offset, uint16_t count)

Referenced by handleCrcCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendErrorCode()

void TunerStudio::sendErrorCode ( TsChannelBase tsChannel,
uint8_t  code,
const char msg = "" 
)
private

Definition at line 265 of file tunerstudio.cpp.

265 {
266 ::sendErrorCode(tsChannel, code, msg);
267}
uint8_t code
Definition bluetooth.cpp:40

Referenced by cmdOutputChannels(), handleCrc32Check(), handleCrcCommand(), handlePageReadCommand(), handleWriteChunkCommand(), and sendErrorCode().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: