X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/8ad1e731c8561ba050db2e80daff7b1e97e575ca..a9eeb576983f932ee622554ccd4e08be10e695b5:/common/lfdemod.c diff --git a/common/lfdemod.c b/common/lfdemod.c index 21695ec1..58b843e2 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -74,7 +74,7 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p parityWd = (parityWd << 1) | BitStream[startIdx+word+bit]; BitStream[j++] = (BitStream[startIdx+word+bit]); } - if (word+pLen >= bLen) break; + if (word+pLen > bLen) break; j--; // overwrite parity with next data // if parity fails then return 0 @@ -158,7 +158,7 @@ bool preambleSearchEx(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t uint8_t foundCnt = 0; for (int idx = 0; idx < *size - pLen; idx++){ if (memcmp(BitStream+idx, preamble, pLen) == 0){ - if (g_debugMode) prnt("DEBUG: preamble found at %u", idx); + if (g_debugMode) prnt("DEBUG: preamble found at %i", idx); //first index found foundCnt++; if (foundCnt == 1){ @@ -203,45 +203,50 @@ size_t findModStart(uint8_t dest[], size_t size, uint8_t threshold_value, uint8_ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID // actually, no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future -uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo) +int Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo) { - //allow only 1s and 0s - // only checking first bitvalue?! - if (BitStream[1] > 1) return 0; + // sanity check + if (*size < 64) return -3; + if (BitStream[1] > 1) return -1; - uint32_t i = 0, idx = 0, parityBits = 0; - uint8_t fmtlen = 0; + uint8_t fmtlen; *startIdx = 0; // preamble 0111111111 // include 0 in front to help get start pos uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1}; - if (!preambleSearch(BitStream, preamble, sizeof(preamble), size, startIdx)) - return 0; - if (*size < 64) return 0; + if (!preambleSearch(BitStream, preamble, sizeof(preamble), size, startIdx)) + return -2; + + //XL and normal size. + if (*size != 64 && *size != 128) return -3; - fmtlen = (*size > 64) ? 22 : 10; + fmtlen = (*size == 128) ? 22 : 10; - idx = *startIdx + sizeof(preamble); + //skip last 4bit parity row for simplicity + *size = removeParity(BitStream, *startIdx + sizeof(preamble), 5, 0, fmtlen * 5); - //loop through 10 or 22 sets of 5 bits (50-10p = 40 bits or 88 bits) - for (i=0; i < fmtlen; i++){ - parityBits = bytebits_to_byte(BitStream + (i*5) + idx, 5); - //check even parity - if (parityTest(parityBits, 5, 0) == 0) return 0; - //set uint64 with ID from BitStream - for (uint8_t j = 0; j < 4; j++){ - *hi = (*hi << 1) | (*lo >> 63); - *lo = (*lo << 1) | (BitStream[(i*5) + j + idx]); - } + switch (*size) { + case 40: { + // std em410x format + *hi = 0; + *lo = ((uint64_t)(bytebits_to_byte(BitStream, 8)) << 32) | (bytebits_to_byte(BitStream + 8, 32)); + break; + } + case 88: { + // long em format + *hi = (bytebits_to_byte(BitStream, 24)); + *lo = ((uint64_t)(bytebits_to_byte(BitStream + 24, 32)) << 32) | (bytebits_to_byte(BitStream + 24 + 32, 32)); + break; + } + default: return -4; } - //skip last 5 bit parity test for simplicity. - // *size = 64 | 128; return 1; } //by marshmellow //demodulates strong heavily clipped samples +//RETURN: num of errors. if 0, is ok. int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low) { size_t bitCnt=0, smplCnt=0, errCnt=0; @@ -385,25 +390,30 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert){ +int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert){ + + // sanity check + if (*size < 16) return -1; + int errCnt = 0, bestErr = 1000; uint16_t bitnum = 0, MaxBits = 512, bestRun = 0; size_t i, k; - if (*size < 16) return -1; + //find correct start position [alignment] - for (k=0; k < 2; ++k){ - for (i=k; i<*size-3; i += 2) + for (k = 0; k < 2; ++k){ + for (i = k; i < *size-3; i += 2) { if (BitStream[i] == BitStream[i+1]) errCnt++; - + } if (bestErr > errCnt){ bestErr = errCnt; bestRun = k; } - errCnt=0; + errCnt = 0; } + //decode - for (i=bestRun; i < *size-3; i += 2){ + for (i = bestRun; i < *size-3; i += 2){ if (BitStream[i] == 1 && (BitStream[i+1] == 0)){ BitStream[bitnum++] = invert; } else if ((BitStream[i] == 0) && BitStream[i+1] == 1){ @@ -411,9 +421,9 @@ int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert){ } else { BitStream[bitnum++] = 7; } - if (bitnum>MaxBits) break; + if (bitnum > MaxBits) break; } - *size=bitnum; + *size = bitnum; return bestErr; } @@ -1673,9 +1683,14 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) return errCnt; } +bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) { + size_t ststart = 0, stend = 0; + return DetectST_ext(buffer, size, foundclock, &ststart, &stend); +} + //by marshmellow //attempt to identify a Sequence Terminator in ASK modulated raw wave -bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) { +bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststart, size_t *stend) { size_t bufsize = *size; //need to loop through all samples and identify our clock, look for the ST pattern uint8_t fndClk[] = {8,16,32,40,50,64,128}; @@ -1830,7 +1845,7 @@ bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) { size_t newloc = 0; i=0; if (g_debugMode==2) prnt("DEBUG STT: Starting STT trim - start: %d, datalen: %d ",dataloc, datalen); - + bool firstrun = true; // warning - overwriting buffer given with raw wave data with ST removed... while ( dataloc < bufsize-(clk/2) ) { //compensate for long high at end of ST not being high due to signal loss... (and we cut out the start of wave high part) @@ -1838,6 +1853,15 @@ bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) { for(i=0; i < clk/2-tol; ++i) { buffer[dataloc+i] = high+5; } + } //test for single sample outlier (high between two lows) in the case of very strong waves + if (buffer[dataloc] >= high && buffer[dataloc+2] <= low) { + buffer[dataloc] = buffer[dataloc+2]; + buffer[dataloc+1] = buffer[dataloc+2]; + } + if (firstrun) { + *stend = dataloc; + *ststart = dataloc-(clk*4); + firstrun=false; } for (i=0; i