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

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 tsChannel->assertPacketSize(count, false);
39 // this method is invoked too often to print any debug information
40 uint8_t * scratchBuffer = (uint8_t *)tsChannel->scratchBuffer;
41 /**
42 * collect data from all models
43 */
44 copyRange(scratchBuffer + 3, getLiveDataFragments(), offset, count);
45
46 tsChannel->crcAndWriteBuffer(TS_RESPONSE_OK, count);
47}
TunerStudioOutputChannels outputChannels
Definition engine.h:109
void crcAndWriteBuffer(const uint8_t responseCode, const size_t size)
char scratchBuffer[scratchBuffer_SIZE+30]
void assertPacketSize(size_t size, bool allowLongPackets)
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code, const char *msg="")
static EngineAccessor engine
Definition engine.h:413
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 349 of file tunerstudio.cpp.

349 {
351
352 // Ensure we are reading from in bounds
353 if (validateOffsetCount(page, offset, count, tsChannel)) {
354 tunerStudioError(tsChannel, "ERROR: CRC out of range");
355 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
356 return;
357 }
358
359 const uint8_t* start = getWorkingPageAddr(tsChannel, page, offset);
360 if (start == nullptr) {
361 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: CRC invalid page");
362 return;
363 }
364
365 uint32_t crc = SWAP_UINT32(crc32(start, count));
366 tsChannel->sendResponse(TS_CRC, (const uint8_t *) &crc, 4);
367 efiPrintf("TS <- Get CRC page %d offset %d count %d result %08x", page, offset, count, (unsigned int)crc);
368}
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 809 of file tunerstudio.cpp.

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

798 {
799 data[incomingPacketSize] = 0;
800 char *trimmed = efiTrim(data);
801#if EFI_SIMULATOR
802 logMsg("execute [%s]\r\n", trimmed);
803#endif // EFI_SIMULATOR
804 (console_line_callback)(trimmed);
805
806 tsChannel->writeCrcResponse(TS_RESPONSE_OK);
807}
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 417 of file tunerstudio.cpp.

417 {
419 efiPrintf("TS <- Page %d read chunk offset %d count %d", page, offset, count);
420
421 if (validateOffsetCount(page, offset, count, tsChannel)) {
422 tunerStudioError(tsChannel, "ERROR: RD out of range");
423 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
424 return;
425 }
426
427 uint8_t* addr = getWorkingPageAddr(tsChannel, page, offset);
428 if (page == TS_PAGE_SETTINGS) {
429 if (isLockedFromUser()) {
430 // to have rusEFI console happy just send all zeros within a valid packet
431 addr = (uint8_t*)&tsChannel->scratchBuffer + TS_PACKET_HEADER_SIZE;
432 memset(addr, 0, count);
433 }
434 }
435
436 if (addr == nullptr) {
437 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: RD invalid page");
438 return;
439 }
440
441 tsChannel->sendResponse(TS_CRC, addr, count);
442#if EFI_TUNER_STUDIO_VERBOSE
443// efiPrintf("Sending %d done", count);
444#endif
445}
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 575 of file tunerstudio.cpp.

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

562 {
564 const char *signature = getTsSignature();
565
566 efiPrintf("TS <- Query signature: %s", signature);
567 tsChannel->sendResponse(mode, (const uint8_t *)signature, strlen(signature) + 1);
568}
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 371 of file tunerstudio.cpp.

371 {
373
374 int totalResponseSize = 0;
375 for (size_t i = 0; i < TS_SCATTER_OFFSETS_COUNT; i++) {
376 uint16_t packed = tsChannel->page1.highSpeedOffsets[i];
377 uint16_t type = packed >> 13;
378
379 size_t size = type == 0 ? 0 : 1 << (type - 1);
380#if EFI_SIMULATOR
381// printf("handleScatteredReadCommand 0x%x %d %d\n", packed, size, offset);
382#endif /* EFI_SIMULATOR */
383 totalResponseSize += size;
384 }
385#if EFI_SIMULATOR
386// printf("totalResponseSize %d\n", totalResponseSize);
387#endif /* EFI_SIMULATOR */
388
389 // Command part of CRC
390 uint32_t crc = tsChannel->writePacketHeader(TS_RESPONSE_OK, totalResponseSize);
391
392 uint8_t dataBuffer[8];
393 for (size_t i = 0; i < TS_SCATTER_OFFSETS_COUNT; i++) {
394 uint16_t packed = tsChannel->page1.highSpeedOffsets[i];
395 uint16_t type = packed >> 13;
396 uint16_t offset = packed & 0x1FFF;
397
398 if (type == 0)
399 continue;
400 size_t size = 1 << (type - 1);
401
402 // write each data point and CRC incrementally
403 copyRange(dataBuffer, getLiveDataFragments(), offset, size);
404 tsChannel->write(dataBuffer, size, false);
405 crc = crc32inc((void*)dataBuffer, crc, size);
406 }
407#if EFI_SIMULATOR
408// printf("CRC %x\n", crc);
409#endif /* EFI_SIMULATOR */
410 // now write total CRC
411 *(uint32_t*)dataBuffer = SWAP_UINT32(crc);
412 tsChannel->write(dataBuffer, 4, true);
413 tsChannel->flush();
414}
uint32_t writePacketHeader(const uint8_t responseCode, const size_t size)
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 298 of file tunerstudio.cpp.

299 {
301
302 efiPrintf("TS -> Page %d write chunk offset %d count %d (output_count=%d)",
304
305
306 if (validateOffsetCount(page, offset, count, tsChannel)) {
307 tunerStudioError(tsChannel, "ERROR: WR out of range");
308 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
309 return;
310 }
311
312 uint8_t * addr = getWorkingPageAddr(tsChannel, page, offset);
313 if (addr == nullptr) {
314 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, "ERROR: WR invalid page");
315 return;
316 }
317
319
320 // Special case
321 if (page == TS_PAGE_SETTINGS) {
322 if (isLockedFromUser()) {
323 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND, "locked");
324 return;
325 }
326
327 // Skip the write if a preset was just loaded - we don't want to overwrite it
328 // [tag:popular_vehicle]
329 if (!needToTriggerTsRefresh()) {
330 memcpy(addr, content, count);
331 } else {
332 efiPrintf("Ignoring TS -> Page %d write chunk offset %d count %d (output_count=%d)",
333 page,
334 offset,
335 count,
337 );
338 }
339 // Force any board configuration options that humans shouldn't be able to change
340 // huh, why is this NOT within above 'needToTriggerTsRefresh()' condition?
342 } else {
343 memcpy(addr, content, count);
344 }
345
346 sendOkResponse(tsChannel);
347}
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 256 of file tunerstudio.cpp.

256 {
257 ::sendErrorCode(tsChannel, code, msg);
258}
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: