From 37c30c039547523178b5c2eb0b4b952c76a76c22 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 May 2019 13:27:43 -0400 Subject: [PATCH] fix: askdemod - enhances which solves some viking demod errors --- client/cmddata.c | 5 +++-- client/cmdlfcotag.c | 20 ++++++++++---------- client/cmdlfviking.c | 34 +++++++++++++++++----------------- common/lfdemod.c | 39 ++++++++++++++++++++++++--------------- common/lfdemod.h | 2 +- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index fb8e2be2f..59558c621 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -584,7 +584,8 @@ static int Cmdmandecoderaw(const char *Cmd) { size_t size = 0; int high = 0, low = 0; size_t i = 0; - int errCnt = 0, invert = 0, maxErr = 20; + uint16_t errCnt = 0; + int invert = 0, maxErr = 20; char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) > 5 || cmdp == 'h') return usage_data_manrawdecode(); @@ -610,7 +611,7 @@ static int Cmdmandecoderaw(const char *Cmd) { uint8_t alignPos = 0; errCnt = manrawdecode(bits, &size, invert, &alignPos); if (errCnt >= maxErr) { - PrintAndLogEx(WARNING, "Too many errors: %d", errCnt); + PrintAndLogEx(WARNING, "Too many errors: %u", errCnt); return PM3_ESOFT; } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 45de81aff..d7c6eff7a 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -22,7 +22,7 @@ static int usage_lf_cotag_read(void) { PrintAndLogEx(NORMAL, "Example:"); PrintAndLogEx(NORMAL, " lf cotag read 0"); PrintAndLogEx(NORMAL, " lf cotag read 1"); - return 0; + return PM3_SUCCESS; } // COTAG demod should be able to use GraphBuffer, @@ -35,10 +35,10 @@ static int CmdCOTAGDemod(const char *Cmd) { memcpy(bits, DemodBuffer, COTAG_BITS); uint8_t alignPos = 0; - int err = manrawdecode(bits, &bitlen, 1, &alignPos); - if (err) { + uint16_t err = manrawdecode(bits, &bitlen, 1, &alignPos); + if (err == 0xFFFF) { if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - COTAG too many errors: %d", err); - return -1; + return PM3_ESOFT; } setDemodBuff(bits, bitlen, 0); @@ -60,7 +60,7 @@ static int CmdCOTAGDemod(const char *Cmd) { 1001 1100 1100 0001 10000101 */ PrintAndLogEx(SUCCESS, "COTAG Found: FC %u, CN: %u Raw: %08X%08X%08X%08X", fc, cn, raw1, raw2, raw3, raw4); - return 1; + return PM3_SUCCESS; } // When reading a COTAG. @@ -78,7 +78,7 @@ static int CmdCOTAGRead(const char *Cmd) { SendCommandMIX(CMD_COTAG, rawsignal, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, NULL, 7000)) { PrintAndLogEx(WARNING, "command execution time out"); - return -1; + return PM3_ETIMEOUT; } switch (rawsignal) { @@ -93,13 +93,13 @@ static int CmdCOTAGRead(const char *Cmd) { if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0, NULL, 1000, false)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return -1; + return PM3_ETIMEOUT; } DemodBufferLen = COTAG_BITS; return CmdCOTAGDemod(""); } } - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -112,7 +112,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdLFCOTAG(const char *Cmd) { @@ -125,5 +125,5 @@ int demodCOTAG(void) { } int readCOTAGUid(void) { - return CmdCOTAGRead("") > 0; + return (CmdCOTAGRead("") == PM3_SUCCESS); } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index bc22a0b66..750070a34 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -45,10 +45,9 @@ static int CmdVikingDemod(const char *Cmd) { return PM3_ESOFT; } size_t size = DemodBufferLen; - int ans = detectViking(DemodBuffer, &size); if (ans < 0) { - PrintAndLogEx(DEBUG, "DEBUG: Error - Viking Demod %d %s", ans, (ans == -5) ? "[chksum error]" : ""); + PrintAndLogEx(DEBUG, "DEBUG: Error - Viking Demod %d %s", ans, (ans == -5) ? _RED_("[chksum error]") : ""); return PM3_ESOFT; } //got a good demod @@ -56,8 +55,8 @@ static int CmdVikingDemod(const char *Cmd) { uint32_t raw2 = bytebits_to_byte(DemodBuffer + ans + 32, 32); uint32_t cardid = bytebits_to_byte(DemodBuffer + ans + 24, 32); uint8_t checksum = bytebits_to_byte(DemodBuffer + ans + 32 + 24, 8); - PrintAndLogEx(SUCCESS, "Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum); - PrintAndLogEx(SUCCESS, "Raw: %08X%08X", raw1, raw2); + PrintAndLogEx(SUCCESS, "Viking Tag Found: Card ID " _YELLOW_("%08X")" checksum "_YELLOW_("%02X"), cardid, checksum); + PrintAndLogEx(SUCCESS, "Raw hex: %08X%08X", raw1, raw2); setDemodBuff(DemodBuffer, 64, ans); setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); return PM3_SUCCESS; @@ -86,7 +85,7 @@ static int CmdVikingClone(const char *Cmd) { rawID = getVikingBits(id); - PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID: %08X, Raw: %08X%08X", id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); + PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); clearCommandBuffer(); SendCommandMIX(CMD_VIKING_CLONE_TAG, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0); @@ -109,7 +108,7 @@ static int CmdVikingSim(const char *Cmd) { rawID = getVikingBits(id); - PrintAndLogEx(SUCCESS, "Simulating Viking - ID: %08X, Raw: %08X%08X", id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); + PrintAndLogEx(SUCCESS, "Simulating Viking - ID " _YELLOW_("%08X")" raw "_YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); uint8_t bs[64]; num_to_bytebits(rawID, sizeof(bs), bs); @@ -164,22 +163,23 @@ uint64_t getVikingBits(uint32_t id) { } // by marshmellow // find viking preamble 0xF200 in already demoded data -int detectViking(uint8_t *dest, size_t *size) { +int detectViking(uint8_t *src, size_t *size) { //make sure buffer has data - if (*size < 64 * 2) return -2; + if (*size < 64) return -2; size_t startIdx = 0; uint8_t preamble[] = {1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + if (!preambleSearch(src, preamble, sizeof(preamble), size, &startIdx)) return -4; //preamble not found - uint32_t checkCalc = bytebits_to_byte(dest + startIdx, 8) ^ - bytebits_to_byte(dest + startIdx + 8, 8) ^ - bytebits_to_byte(dest + startIdx + 16, 8) ^ - bytebits_to_byte(dest + startIdx + 24, 8) ^ - bytebits_to_byte(dest + startIdx + 32, 8) ^ - bytebits_to_byte(dest + startIdx + 40, 8) ^ - bytebits_to_byte(dest + startIdx + 48, 8) ^ - bytebits_to_byte(dest + startIdx + 56, 8); + uint32_t checkCalc = bytebits_to_byte(src + startIdx, 8) ^ + bytebits_to_byte(src + startIdx + 8, 8) ^ + bytebits_to_byte(src + startIdx + 16, 8) ^ + bytebits_to_byte(src + startIdx + 24, 8) ^ + bytebits_to_byte(src + startIdx + 32, 8) ^ + bytebits_to_byte(src + startIdx + 40, 8) ^ + bytebits_to_byte(src + startIdx + 48, 8) ^ + bytebits_to_byte(src + startIdx + 56, 8); + if (checkCalc != 0xA8) return -5; if (*size != 64) return -6; //return start position diff --git a/common/lfdemod.c b/common/lfdemod.c index a581198fa..f7cc0fc31 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -315,10 +315,10 @@ static int getClosestClock(int testclk) { uint16_t clocks[] = {8, 16, 32, 40, 50, 64, 100, 128, 256, 384}; uint8_t limit[] = {1, 2, 4, 4, 5, 8, 8, 8, 8, 8}; - for (uint8_t i = 0; i < 10; i++) + for (uint8_t i = 0; i < 10; i++) { if (testclk >= clocks[i] - limit[i] && testclk <= clocks[i] + limit[i]) return clocks[i]; - + } return 0; } @@ -480,17 +480,19 @@ bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) { // by marshmellow // to help detect clocks on heavily clipped samples // based on count of low to low -int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clock) { +int DetectStrongAskClock(uint8_t *src, size_t size, int high, int low, int *clock) { size_t i = 100; size_t minClk = 512; uint16_t shortestWaveIdx = 0; // get to first full low to prime loop and skip incomplete first pulse - getNextHigh(dest, size, high, &i); - getNextLow(dest, size, low, &i); + getNextHigh(src, size, high, &i); + getNextLow(src, size, low, &i); if (i == size) return -1; + if (size < 512) + return -2; // clock, numoftimes, first idx uint16_t tmpclk[10][3] = { @@ -507,12 +509,12 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo }; // loop through all samples (well, we don't want to go out-of-bounds) - while (i < size - 512) { + while (i < (size - 512)) { // measure from low to low size_t startwave = i; - getNextHigh(dest, size, high, &i); - getNextLow(dest, size, low, &i); + getNextHigh(src, size, high, &i); + getNextLow(src, size, low, &i); //get minimum measured distance if (i - startwave < minClk && i < size) { @@ -1401,17 +1403,18 @@ int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert) { //take 10 and 01 and manchester decode //run through 2 times and take least errCnt // "," indicates 00 or 11 wrong bit -int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) { +uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) { // sanity check - if (*size < 16) return -1; + if (*size < 16) return 0xFFFF; int errCnt = 0, bestErr = 1000; uint16_t bitnum = 0, maxBits = 512, bestRun = 0; size_t i, k; //find correct start position [alignment] - for (k = 0; k < 2; ++k) { + for (k = 0; k < 2; k++) { + for (i = k; i < *size - 1; i += 2) { if (bits[i] == bits[i + 1]) @@ -1431,7 +1434,7 @@ int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) *alignPos = bestRun; //decode - for (i = bestRun; i < *size - 1; i += 2) { + for (i = bestRun; i < *size; i += 2) { if (bits[i] == 1 && (bits[i + 1] == 0)) { bits[bitnum++] = invert; } else if ((bits[i] == 0) && bits[i + 1] == 1) { @@ -1448,7 +1451,7 @@ int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) //by marshmellow //demodulates strong heavily clipped samples //RETURN: num of errors. if 0, is ok. -static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, int high, int low, int *startIdx) { +static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, int high, int low, int *startIdx) { *startIdx = 0; size_t bitCnt = 0, smplCnt = 1, errCnt = 0, pos = 0; uint8_t cl_4 = clk / 4; @@ -1463,7 +1466,8 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in smplCnt++; } else if (bits[i] <= low && !waveHigh) { smplCnt++; - } else { //transition + } else { + //transition if ((bits[i] >= high && !waveHigh) || (bits[i] <= low && waveHigh)) { // 8 :: 8-2-1 = 5 8+2+1 = 11 @@ -1472,7 +1476,8 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in // 64 :: 64-16-1 = 47 64+16+1 = 81 if (smplCnt > clk - cl_4 - 1) { //full clock - if (smplCnt > clk + cl_4 + 1) { //too many samples + if (smplCnt > clk + cl_4 + 1) { + //too many samples errCnt++; if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %u [%u > %u]", i, smplCnt, clk + cl_4 + 1); bits[bitCnt++] = 7; @@ -1515,6 +1520,7 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in } } } + *size = bitCnt; if (*startIdx < 0) @@ -1823,6 +1829,7 @@ static size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t clk, uint8_t in } memset(dest + numBits, dest[i - 1] ^ invert, n); numBits += n; + if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) extra bits in the end"); } return numBits; } @@ -1833,7 +1840,9 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8 if (signalprop.isnoise) return 0; // FSK demodulator size = fsk_wave_demod(dest, size, fchigh, fclow, start_idx); + if (g_debugMode == 2) prnt("DEBUG (fskdemod) got %zu bits", size); size = aggregate_bits(dest, size, rfLen, invert, fchigh, fclow, start_idx); + if (g_debugMode == 2) prnt("DEBUG (fskdemod) got %zu bits", size); return size; } diff --git a/common/lfdemod.h b/common/lfdemod.h index a9fe3f70b..47a0c4e5e 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -66,7 +66,7 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uin void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); uint32_t manchesterEncode2Bytes(uint16_t datain); int ManchesterEncode(uint8_t *bits, size_t size); -int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos); +uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos); int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx); bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);