fix: askdemod - enhances which solves some viking demod errors

This commit is contained in:
iceman1001 2019-05-25 13:27:43 -04:00
commit 37c30c0395
5 changed files with 55 additions and 45 deletions

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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);