From 791f02209d16bb614dbf10373be88d98cfda8f44 Mon Sep 17 00:00:00 2001 From: jlitewski Date: Sat, 20 Apr 2024 12:19:16 -0400 Subject: [PATCH 1/2] Implemented Buffer SaveStates --- CHANGELOG.md | 4 +- client/src/cmddata.c | 202 ++++++++++++++++++++++++++++++++----- client/src/cmddata.h | 1 - client/src/cmdlf.c | 13 ++- client/src/cmdlft55xx.c | 4 +- client/src/cmdlfti.c | 4 +- client/src/cmdlfvisa2000.c | 10 +- client/src/cmdlfzx8211.c | 6 +- client/src/cmdparser.c | 4 + client/src/cmdparser.h | 1 + client/src/graph.c | 124 +++++++++++++++++++---- client/src/graph.h | 20 +++- client/src/proxguiqt.cpp | 4 +- 13 files changed, 328 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 537b0a721..8394e4ffd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Removed `save_restoreDB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2) +- Removed `save_restoreGB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2) - Changed `hf mfp info` to identify Ev2 (@iceman1001) - Updated Graph Markers implementation to include temporary markers and marker labels (@HACKhalo2) - Updated to SWIG 4.2.1 (@iceman1001) @@ -12,7 +14,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed waiting for device loops. More stable experience (@iceman1001) - Changed client now handles CTRL-C and saves history if using READLINE (@iceman1001) - Changed `hf mf *` - printing of keys if MFC EV1 added extra explaination (@iceman1001) -- Changed `hf mf ginfo - now supports decoding of user supplied configuration block (@iceman1001) +- Changed `hf mf ginfo` - now supports decoding of user supplied configuration block (@iceman1001) - Changed `data load` - now shows loaded number as comma printed. (@iceman1001) - Updated `/tools/hitag2crack/common/OpenCL-Headers/CL` with latest from KhronosGroup github page (@iceman1001) - Fixed `lf hitag list` - improved HITAG2 protocol annotation (@iceman1001) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index eba8b32be..7689fb26c 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -193,30 +193,6 @@ static double compute_autoc(const int *data, size_t n, int lag) { } */ -// option '1' to save g_DemodBuffer any other to restore -void save_restoreDB(uint8_t saveOpt) { - static uint8_t SavedDB[MAX_DEMOD_BUF_LEN]; - static size_t SavedDBlen; - static bool DB_Saved = false; - static size_t savedDemodStartIdx = 0; - static int savedDemodClock = 0; - - if (saveOpt == GRAPH_SAVE) { //save - - memcpy(SavedDB, g_DemodBuffer, sizeof(g_DemodBuffer)); - SavedDBlen = g_DemodBufferLen; - DB_Saved = true; - savedDemodStartIdx = g_DemodStartIdx; - savedDemodClock = g_DemodClock; - } else if (DB_Saved) { //restore - - memcpy(g_DemodBuffer, SavedDB, sizeof(g_DemodBuffer)); - g_DemodBufferLen = SavedDBlen; - g_DemodClock = savedDemodClock; - g_DemodStartIdx = savedDemodStartIdx; - } -} - static int CmdSetDebugMode(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data setdebugmode", @@ -2734,7 +2710,7 @@ static int try_detect_modulation(void) { clk = GetPskClock("", false); if (clk > 0) { // allow undo - save_restoreGB(GRAPH_SAVE); + buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) CmdLtrim("-i 160"); if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS)) { @@ -2746,7 +2722,7 @@ static int try_detect_modulation(void) { tests[hits].carrier = GetPskCarrier(false); } //undo trim samples - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); } } @@ -3702,6 +3678,174 @@ static int CmdXor(const char *Cmd) { return PM3_SUCCESS; } +static int CmdTestSaveState8(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "data test_ss8", + "Tests the implementation of Buffer Save States (8-bit buffer)", + "data test_ss8"); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + srand(time(NULL)); + + size_t length = 64; + uint8_t *srcBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); + + //Set up the source buffer with random data + for(int i = 0; i < length; i++) { + srcBuffer[i] = (rand() % 256); + } + + buffer_savestate_t test8 = save_buffer8(srcBuffer, length); + PrintAndLogEx(DEBUG, "Save State created, length=%llu, type=%i", test8.bufferSize, test8.type); + + test8.clock = rand(); + test8.offset = rand(); + PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test8.clock, test8.offset); + + uint8_t *destBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); + size_t returnedLength = restore_buffer8(test8, destBuffer); + + if(returnedLength != length) { + PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); + + for(size_t i = 0; i < length; i++) { + if(srcBuffer[i] != destBuffer[i]) { + PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, "Index %lu matches: %u", i, destBuffer[i]); + } + PrintAndLogEx(SUCCESS, _GREEN_("Save State (8-bit) test success!") "\n"); + + free(srcBuffer); + free(destBuffer); + return PM3_SUCCESS; +} + +static int CmdTestSaveState32(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "data test_ss32", + "Tests the implementation of Buffer Save States (32-bit buffer)", + "data test_ss32"); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + srand(time(NULL)); + + size_t length = 64; + uint32_t *srcBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + + //Set up the source buffer with random data + for(size_t i = 0; i < length; i++) { + srcBuffer[i] = (rand()); + } + + buffer_savestate_t test32 = save_buffer32(srcBuffer, length); + PrintAndLogEx(DEBUG, "Save State created, length=%llu, type=%i", test32.bufferSize, test32.type); + + test32.clock = rand(); + test32.offset = rand(); + PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test32.clock, test32.offset); + + uint32_t *destBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + size_t returnedLength = restore_buffer32(test32, destBuffer); + + if(returnedLength != length) { + PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); + + for(size_t i = 0; i < length; i++) { + if(srcBuffer[i] != destBuffer[i]) { + PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, "Index %lu matches: %i", i, destBuffer[i]); + } + PrintAndLogEx(SUCCESS, _GREEN_("Save State (32-bit) test success!") "\n"); + + free(srcBuffer); + free(destBuffer); + return PM3_SUCCESS; +} + +static int CmdTestSaveState32S(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "data test_ss32s", + "Tests the implementation of Buffer Save States (32-bit signed buffer)", + "data test_ss32s"); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + srand(time(NULL)); + + size_t length = 64; + int32_t *srcBuffer = (int32_t*)calloc(length, sizeof(int32_t)); + + //Set up the source buffer with random data + for(int i = 0; i < length; i++) { + srcBuffer[i] = (rand() - 4294967296); + } + + buffer_savestate_t test32 = save_bufferS32(srcBuffer, length); + PrintAndLogEx(DEBUG, "Save State created, length=%llu, type=%i", test32.bufferSize, test32.type); + + test32.clock = rand(); + test32.offset = rand(); + PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test32.clock, test32.offset); + + int32_t *destBuffer = (int32_t*)calloc(length, sizeof(int32_t)); + size_t returnedLength = restore_bufferS32(test32, destBuffer); + + if(returnedLength != length) { + PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); + + for(int i = 0; i < length; i++) { + if(srcBuffer[i] != destBuffer[i]) { + PrintAndLogEx(FAILED, "Buffers don't match at index %i!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); + free(srcBuffer); + free(destBuffer); + return PM3_EFAILED; + } + PrintAndLogEx(DEBUG, "Index %i matches: %i", i, destBuffer[i]); + } + PrintAndLogEx(SUCCESS, _GREEN_("Save State (signed 32-bit) test success!") "\n"); + + free(srcBuffer); + free(destBuffer); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"-----------", CmdHelp, AlwaysAvailable, "------------------------- " _CYAN_("General") "-------------------------"}, @@ -3754,6 +3898,12 @@ static command_t CommandTable[] = { {"diff", CmdDiff, AlwaysAvailable, "Diff of input files"}, {"hexsamples", CmdHexsamples, IfPm3Present, "Dump big buffer as hex bytes"}, {"samples", CmdSamples, IfPm3Present, "Get raw samples for graph window ( GraphBuffer )"}, + + {"-----------", CmdHelp, IfClientDebugEnabled, "------------------------- " _CYAN_("Debug") "-------------------------"}, + {"test_ss8", CmdTestSaveState8, IfClientDebugEnabled, "Test the implementation of Buffer Save States (8-bit buffer)"}, + {"test_ss32", CmdTestSaveState32, IfClientDebugEnabled, "Test the implementation of Buffer Save States (32-bit buffer)"}, + {"test_ss32s", CmdTestSaveState32S, IfClientDebugEnabled, "Test the implementation of Buffer Save States (32-bit signed buffer)"}, + {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmddata.h b/client/src/cmddata.h index 0767412cb..5b19b0f4e 100644 --- a/client/src/cmddata.h +++ b/client/src/cmddata.h @@ -81,7 +81,6 @@ int printDemodBuff(uint8_t offset, bool strip_leading, bool invert, bool print_h void setDemodBuff(const uint8_t *buff, size_t size, size_t start_idx); bool getDemodBuff(uint8_t *buff, size_t *size); -void save_restoreDB(uint8_t saveOpt);// option '1' to save g_DemodBuffer any other to restore int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveGrph, bool verbose); int getSamples(uint32_t n, bool verbose); diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 7a50c7f8e..efbf23a39 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -1535,8 +1535,11 @@ static bool check_chiptype(bool getDeviceData) { if (!getDeviceData) return retval; - save_restoreGB(GRAPH_SAVE); - save_restoreDB(GRAPH_SAVE); + //Save the state of the Graph and Demod Buffers + buffer_savestate_t saveState_gb = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + buffer_savestate_t saveState_db = save_buffer8(g_DemodBuffer, g_DemodBufferLen); + saveState_db.clock = g_DemodClock; + saveState_db.offset = g_DemodStartIdx; //check for em4x05/em4x69 chips first uint32_t word = 0; @@ -1575,8 +1578,10 @@ static bool check_chiptype(bool getDeviceData) { PrintAndLogEx(INFO, "Couldn't identify a chipset"); out: - save_restoreGB(GRAPH_RESTORE); - save_restoreDB(GRAPH_RESTORE); + restore_buffer8(saveState_db, g_DemodBuffer); + g_DemodClock = saveState_db.clock; + g_DemodStartIdx = saveState_db.offset; + restore_bufferS32(saveState_gb, g_GraphBuffer); return retval; } diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 16087be4a..dd91c4dd9 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1151,7 +1151,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 clk = GetPskClock("", false); if (clk > 0) { // allow undo - save_restoreGB(GRAPH_SAVE); + buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) CmdLtrim("-i 160"); if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -1200,7 +1200,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 } } // inverse waves does not affect this demod //undo trim samples - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); } } if (hits == 1) { diff --git a/client/src/cmdlfti.c b/client/src/cmdlfti.c index f4d6d79ee..8cdc315d2 100644 --- a/client/src/cmdlfti.c +++ b/client/src/cmdlfti.c @@ -89,7 +89,7 @@ int demodTI(bool verbose) { 1, 1, 1, 1, 1, 1, 1, 1 }; - save_restoreGB(GRAPH_SAVE); + buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); int lowLen = ARRAYLEN(LowTone); int highLen = ARRAYLEN(HighTone); @@ -277,7 +277,7 @@ int demodTI(bool verbose) { out: if (retval != PM3_SUCCESS) - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return retval; } diff --git a/client/src/cmdlfvisa2000.c b/client/src/cmdlfvisa2000.c index 681598c69..4b981ecfe 100644 --- a/client/src/cmdlfvisa2000.c +++ b/client/src/cmdlfvisa2000.c @@ -84,7 +84,7 @@ static uint8_t visa_parity(uint32_t id) { //see ASKDemod for what args are accepted int demodVisa2k(bool verbose) { (void) verbose; // unused so far - save_restoreGB(GRAPH_SAVE); + buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); //CmdAskEdgeDetect(""); @@ -92,7 +92,7 @@ int demodVisa2k(bool verbose) { bool st = true; if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ASK/Manchester Demod failed"); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } size_t size = g_DemodBufferLen; @@ -107,7 +107,7 @@ int demodVisa2k(bool verbose) { else PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ans: %d", ans); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } setDemodBuff(g_DemodBuffer, 96, ans); @@ -125,7 +125,7 @@ int demodVisa2k(bool verbose) { // test checksums if (chk != calc) { PrintAndLogEx(DEBUG, "DEBUG: error: Visa2000 checksum (%s) %x - %x\n", _RED_("fail"), chk, calc); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } // parity @@ -133,7 +133,7 @@ int demodVisa2k(bool verbose) { uint8_t chk_par = (raw3 & 0xFF0) >> 4; if (calc_par != chk_par) { PrintAndLogEx(DEBUG, "DEBUG: error: Visa2000 parity (%s) %x - %x\n", _RED_("fail"), chk_par, calc_par); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "Visa2000 - Card " _GREEN_("%u") ", Raw: %08X%08X%08X", raw2, raw1, raw2, raw3); diff --git a/client/src/cmdlfzx8211.c b/client/src/cmdlfzx8211.c index 92c674d06..72f0ab2d9 100644 --- a/client/src/cmdlfzx8211.c +++ b/client/src/cmdlfzx8211.c @@ -41,7 +41,7 @@ static int CmdHelp(const char *Cmd); // see ASKDemod for what args are accepted int demodzx(bool verbose) { (void) verbose; // unused so far - save_restoreGB(GRAPH_SAVE); + buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); // CmdAskEdgeDetect(""); @@ -49,7 +49,7 @@ int demodzx(bool verbose) { bool st = true; if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ASK/Manchester Demod failed"); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } size_t size = g_DemodBufferLen; @@ -64,7 +64,7 @@ int demodzx(bool verbose) { else PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ans: %d", ans); - save_restoreGB(GRAPH_RESTORE); + restore_bufferS32(saveState, g_GraphBuffer); return PM3_ESOFT; } setDemodBuff(g_DemodBuffer, 96, ans); diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index feafb2a4f..7421b3f58 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -32,6 +32,10 @@ bool AlwaysAvailable(void) { return true; } +bool IfClientDebugEnabled(void) { + return g_debugMode; +} + bool IfPm3Present(void) { if (g_session.help_dump_mode) return false; diff --git a/client/src/cmdparser.h b/client/src/cmdparser.h index 8ccd8d7ab..34eee8bd5 100644 --- a/client/src/cmdparser.h +++ b/client/src/cmdparser.h @@ -31,6 +31,7 @@ typedef struct command_s { // helpers for command_t IsAvailable bool AlwaysAvailable(void); +bool IfClientDebugEnabled(void); bool IfPm3Present(void); bool IfPm3Rdv4Fw(void); bool IfPm3Flash(void); diff --git a/client/src/graph.c b/client/src/graph.c index 22541aa82..72640c730 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -30,6 +30,7 @@ int32_t g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; bool g_useOverlays = false; size_t g_GraphTraceLen; +buffer_savestate_t g_saveState_gb; /* write a manchester bit to the graph */ @@ -94,27 +95,6 @@ size_t ClearGraph(bool redraw) { return gtl; } -// option '1' to save g_GraphBuffer any other to restore -void save_restoreGB(uint8_t saveOpt) { - static int savedBuffer[MAX_GRAPH_TRACE_LEN]; - static size_t savedBufferLen = 0; - static bool bufferSaved = false; - static int savedOffset = 0; - - if (saveOpt == GRAPH_SAVE) { //save - memcpy(savedBuffer, g_GraphBuffer, sizeof(g_GraphBuffer)); - savedBufferLen = g_GraphTraceLen; - bufferSaved = true; - savedOffset = g_GridOffset; - } else if (bufferSaved) { //restore - memcpy(g_GraphBuffer, savedBuffer, sizeof(g_GraphBuffer)); - memcpy(g_OperationBuffer, savedBuffer, sizeof(g_OperationBuffer)); - g_GraphTraceLen = savedBufferLen; - g_GridOffset = savedOffset; - RepaintGraphWindow(); - } -} - void setGraphBuffer(const uint8_t *src, size_t size) { if (src == NULL) return; @@ -441,3 +421,105 @@ bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge) { } return true; } + +buffer_savestate_t save_buffer32(uint32_t *src, size_t length) { + //calloc the memory needed + uint32_t* savedBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + + //Make a copy of the source buffer + memcpy(savedBuffer, src, (length * sizeof(uint32_t))); + + buffer_savestate_t tommy = { + .type = sizeof(uint32_t), + .bufferSize = length, + .buffer = savedBuffer + }; + + return tommy; +} + +buffer_savestate_t save_bufferS32(int32_t *src, size_t length) { + //calloc the memory needed + uint32_t* savedBuffer = (uint32_t*)calloc(length, (sizeof(uint32_t))); + + //Make a copy of the source buffer + memcpy(savedBuffer, src, (length * sizeof(uint32_t))); + + buffer_savestate_t billy = { + .type = (sizeof(int32_t) >> 8), + .bufferSize = length, + .buffer = savedBuffer + }; + + return billy; +} + +buffer_savestate_t save_buffer8(uint8_t *src, size_t length) { + // We are going to be packing the 8-bit source buffer into + // the 32-bit backing buffer, so the input length is going to be + // 1/4 of the size needed + size_t buffSize = (length/4); + + //calloc the memory needed + uint32_t* savedBuffer = (uint32_t*)calloc(buffSize, sizeof(uint32_t)); + size_t index = 0; + + //Pack the source array into the backing array + for(size_t i = 0; i < length; i += 4) { + savedBuffer[index] = (uint32_t)src[i] | ((uint32_t)src[i+1] << 8) | + ((uint32_t)src[i+2] << 16) | ((uint32_t)src[i+3] << 24); + index++; + } + + buffer_savestate_t timmy = { + .type = sizeof(uint8_t), + .bufferSize = buffSize, + .buffer = savedBuffer + }; + + return timmy; +} + +size_t restore_buffer32(buffer_savestate_t saveState, uint32_t *dest) { + if(saveState.type != sizeof(uint32_t)) { + PrintAndLogEx(WARNING, "Invalid Save State type! Expected uint32_t!"); + PrintAndLogEx(WARNING, "Buffer not modified!\n"); + return 0; + } + + memcpy(dest, saveState.buffer, (saveState.bufferSize * sizeof(uint32_t))); + + return saveState.bufferSize; +} + +size_t restore_bufferS32(buffer_savestate_t saveState, int32_t *dest) { + if(saveState.type != (sizeof(int32_t) >> 8)) { + PrintAndLogEx(WARNING, "Invalid Save State type! Expected int32_t"); + PrintAndLogEx(WARNING, "Buffer not modified!\n"); + return 0; + } + + memcpy(dest, saveState.buffer, (saveState.bufferSize * sizeof(int32_t))); + + return saveState.bufferSize; +} + +size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest) { + if(saveState.type != sizeof(uint8_t)) { + PrintAndLogEx(WARNING, "Invalid Save State type! Expected uint8_t!"); + PrintAndLogEx(WARNING, "Buffer not modified!\n"); + return 0; + } + + size_t index = 0; + + // Unpack the array + for(size_t i = 0; i < saveState.bufferSize; i++) { + dest[index++] = (uint8_t)(saveState.buffer[i] & 0xFF); + dest[index++] = (uint8_t)((saveState.buffer[i] >> 8) & 0xFF); + dest[index++] = (uint8_t)((saveState.buffer[i] >> 16) & 0xFF); + dest[index++] = (uint8_t)((saveState.buffer[i] >> 24) & 0xFF); + } + + return index; +} diff --git a/client/src/graph.h b/client/src/graph.h index 58a05ed9b..4db94064d 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -25,11 +25,18 @@ extern "C" { #endif +typedef struct { + const uint8_t type; //Used for sanity checks + const uint32_t *buffer; + const size_t bufferSize; + uint32_t offset; + uint32_t clock; //Not used by all buffers +} buffer_savestate_t; + void AppendGraph(bool redraw, uint16_t clock, int bit); size_t ClearGraph(bool redraw); bool HasGraphData(void); void setGraphBuffer(const uint8_t *src, size_t size); -void save_restoreGB(uint8_t saveOpt); size_t getFromGraphBuffer(uint8_t *dest); size_t getFromGraphBufferEx(uint8_t *dest, size_t maxLen); size_t getGraphBufferChunk(uint8_t *dest, size_t start, size_t end); @@ -44,6 +51,13 @@ int GetNrzClock(const char *str, bool verbose); int GetFskClock(const char *str, bool verbose); bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge); +buffer_savestate_t save_buffer32(uint32_t *src, size_t length); +buffer_savestate_t save_bufferS32(int32_t *src, size_t length); +buffer_savestate_t save_buffer8(uint8_t *src, size_t length); +size_t restore_buffer32(buffer_savestate_t saveState, uint32_t *dest); +size_t restore_bufferS32(buffer_savestate_t saveState, int32_t *dest); +size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest); + #define MAX_GRAPH_TRACE_LEN (40000 * 32) #define GRAPH_SAVE 1 #define GRAPH_RESTORE 0 @@ -52,7 +66,9 @@ extern int32_t g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern int32_t g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; extern int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; extern bool g_useOverlays; -extern size_t g_GraphTraceLen; +extern size_t g_GraphTraceLen; + +extern buffer_savestate_t g_saveState_gb; #ifdef __cplusplus } diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 376ec23f1..3d7b23fc4 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -337,12 +337,12 @@ void SliderWidget::moveEvent(QMoveEvent *event) { //-------------------- void ProxWidget::applyOperation() { //printf("ApplyOperation()"); - save_restoreGB(GRAPH_SAVE); + //g_saveState_gb = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); memcpy(g_GraphBuffer, g_OverlayBuffer, sizeof(int) * g_GraphTraceLen); RepaintGraphWindow(); } void ProxWidget::stickOperation() { - save_restoreGB(GRAPH_RESTORE); + //restore_bufferS32(g_saveState_gb, g_GraphBuffer); //printf("stickOperation()"); } void ProxWidget::vchange_autocorr(int v) { From 2d0bc5100a86622d201fb55828b4c6db0a80d156 Mon Sep 17 00:00:00 2001 From: jlitewski Date: Sat, 20 Apr 2024 22:47:42 -0400 Subject: [PATCH 2/2] Forgot about resetting the grid offsets --- client/src/cmddata.c | 2 ++ client/src/cmdlf.c | 4 ++++ client/src/cmdlft55xx.c | 2 ++ client/src/cmdlfti.c | 5 ++++- client/src/cmdlfvisa2000.c | 5 +++++ client/src/cmdlfzx8211.c | 3 +++ client/src/graph.h | 2 ++ client/src/proxgui.h | 5 +---- 8 files changed, 23 insertions(+), 5 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 7689fb26c..19f217c50 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2711,6 +2711,7 @@ static int try_detect_modulation(void) { if (clk > 0) { // allow undo buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState.offset = g_GridOffset; // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) CmdLtrim("-i 160"); if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS)) { @@ -2723,6 +2724,7 @@ static int try_detect_modulation(void) { } //undo trim samples restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; } } diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index efbf23a39..bf4fa1cb1 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -1537,6 +1537,7 @@ static bool check_chiptype(bool getDeviceData) { //Save the state of the Graph and Demod Buffers buffer_savestate_t saveState_gb = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState_gb.offset = g_GridOffset; buffer_savestate_t saveState_db = save_buffer8(g_DemodBuffer, g_DemodBufferLen); saveState_db.clock = g_DemodClock; saveState_db.offset = g_DemodStartIdx; @@ -1581,7 +1582,10 @@ out: restore_buffer8(saveState_db, g_DemodBuffer); g_DemodClock = saveState_db.clock; g_DemodStartIdx = saveState_db.offset; + restore_bufferS32(saveState_gb, g_GraphBuffer); + g_GridOffset = saveState_gb.offset; + return retval; } diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index dd91c4dd9..76cec033c 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1152,6 +1152,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 if (clk > 0) { // allow undo buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState.offset = g_GridOffset; // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) CmdLtrim("-i 160"); if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -1201,6 +1202,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 } // inverse waves does not affect this demod //undo trim samples restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; } } if (hits == 1) { diff --git a/client/src/cmdlfti.c b/client/src/cmdlfti.c index 8cdc315d2..4a5dcc18a 100644 --- a/client/src/cmdlfti.c +++ b/client/src/cmdlfti.c @@ -90,6 +90,7 @@ int demodTI(bool verbose) { }; buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState.offset = g_GridOffset; int lowLen = ARRAYLEN(LowTone); int highLen = ARRAYLEN(HighTone); @@ -276,8 +277,10 @@ int demodTI(bool verbose) { } out: - if (retval != PM3_SUCCESS) + if (retval != PM3_SUCCESS) { restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; + } return retval; } diff --git a/client/src/cmdlfvisa2000.c b/client/src/cmdlfvisa2000.c index 4b981ecfe..5e473fcf3 100644 --- a/client/src/cmdlfvisa2000.c +++ b/client/src/cmdlfvisa2000.c @@ -85,6 +85,7 @@ static uint8_t visa_parity(uint32_t id) { int demodVisa2k(bool verbose) { (void) verbose; // unused so far buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState.offset = g_GridOffset; //CmdAskEdgeDetect(""); @@ -93,6 +94,7 @@ int demodVisa2k(bool verbose) { if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ASK/Manchester Demod failed"); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } size_t size = g_DemodBufferLen; @@ -108,6 +110,7 @@ int demodVisa2k(bool verbose) { PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ans: %d", ans); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } setDemodBuff(g_DemodBuffer, 96, ans); @@ -126,6 +129,7 @@ int demodVisa2k(bool verbose) { if (chk != calc) { PrintAndLogEx(DEBUG, "DEBUG: error: Visa2000 checksum (%s) %x - %x\n", _RED_("fail"), chk, calc); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } // parity @@ -134,6 +138,7 @@ int demodVisa2k(bool verbose) { if (calc_par != chk_par) { PrintAndLogEx(DEBUG, "DEBUG: error: Visa2000 parity (%s) %x - %x\n", _RED_("fail"), chk_par, calc_par); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "Visa2000 - Card " _GREEN_("%u") ", Raw: %08X%08X%08X", raw2, raw1, raw2, raw3); diff --git a/client/src/cmdlfzx8211.c b/client/src/cmdlfzx8211.c index 72f0ab2d9..03fcd6053 100644 --- a/client/src/cmdlfzx8211.c +++ b/client/src/cmdlfzx8211.c @@ -42,6 +42,7 @@ static int CmdHelp(const char *Cmd); int demodzx(bool verbose) { (void) verbose; // unused so far buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); + saveState.offset = g_GridOffset; // CmdAskEdgeDetect(""); @@ -50,6 +51,7 @@ int demodzx(bool verbose) { if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ASK/Manchester Demod failed"); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } size_t size = g_DemodBufferLen; @@ -65,6 +67,7 @@ int demodzx(bool verbose) { PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ans: %d", ans); restore_bufferS32(saveState, g_GraphBuffer); + g_GridOffset = saveState.offset; return PM3_ESOFT; } setDemodBuff(g_DemodBuffer, 96, ans); diff --git a/client/src/graph.h b/client/src/graph.h index 4db94064d..5c51481f2 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -68,6 +68,8 @@ extern int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; extern bool g_useOverlays; extern size_t g_GraphTraceLen; +extern double g_GridOffset; + extern buffer_savestate_t g_saveState_gb; #ifdef __cplusplus diff --git a/client/src/proxgui.h b/client/src/proxgui.h index 4190eea4e..daeed30b6 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -52,7 +52,7 @@ extern void remove_temporary_markers(void); extern double g_CursorScaleFactor; extern char g_CursorScaleFactorUnit[11]; -extern double g_PlotGridX, g_PlotGridY, g_DefaultGridX, g_DefaultGridY, g_GridOffset; +extern double g_PlotGridX, g_PlotGridY, g_DefaultGridX, g_DefaultGridY; extern marker_t g_MarkerA, g_MarkerB, g_MarkerC, g_MarkerD; extern marker_t *g_TempMarkers; extern uint8_t g_TempMarkerSize; @@ -61,9 +61,6 @@ extern int CommandFinished; extern int offline; extern bool g_GridLocked; -#define GRAPH_SAVE 1 -#define GRAPH_RESTORE 0 - #ifndef FILE_PATH_SIZE #define FILE_PATH_SIZE 1000 #endif