From: marshmellow42 Date: Wed, 18 Nov 2015 05:10:11 +0000 (-0500) Subject: lf demod cleanup nrz clock detect fixes X-Git-Tag: v2.3.0~13^2~11 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/6fe5c94bda4d272dc739b71ed5e54a8678f6065a lf demod cleanup nrz clock detect fixes slight adjustment to lf t55xx sampling code to start at the same spot more consistently reduce indala detection false positives lf t55xx commands heavily tested and seem to be stable and reliable on most modulations/bitrates (excluding Sequence Terminator configured cards). --- diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 3acecd6e..0691098b 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1078,7 +1078,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc) #define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc) #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 -#define READ_GAP 26*8 +#define READ_GAP 15*8 void TurnReadLFOn(int delay) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 7c541282..b6ca9209 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -255,7 +255,8 @@ uint32_t SnoopLF() **/ void doT55x7Acquisition(size_t sample_size) { - #define T55xx_READ_UPPER_THRESHOLD 128+40 // 40 grph + #define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph + #define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph #define T55xx_READ_TOL 5 uint8_t *dest = BigBuf_get_addr(); @@ -267,6 +268,7 @@ void doT55x7Acquisition(size_t sample_size) { uint16_t i = 0; bool startFound = false; bool highFound = false; + bool lowFound = false; uint8_t curSample = 0; uint8_t lastSample = 0; uint16_t skipCnt = 0; @@ -282,15 +284,26 @@ void doT55x7Acquisition(size_t sample_size) { // skip until the first high sample above threshold if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { - if (curSample > lastSample) - lastSample = curSample; + //if (curSample > lastSample) + // lastSample = curSample; highFound = true; } else if (!highFound) { skipCnt++; continue; } + // skip until the first Low sample below threshold + if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) { + //if (curSample > lastSample) + lastSample = curSample; + lowFound = true; + } else if (!lowFound) { + skipCnt++; + continue; + } + + // skip until first high samples begin to change - if (startFound || curSample < T55xx_READ_UPPER_THRESHOLD-T55xx_READ_TOL){ + if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD+T55xx_READ_TOL){ // if just found start - recover last sample if (!startFound) { dest[i++] = lastSample; diff --git a/client/cmddata.c b/client/cmddata.c index 4dd08008..d4dcf661 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1580,6 +1580,9 @@ int PSKDemod(const char *Cmd, bool verbose) //invalid carrier return 0; } + if (g_debugMode){ + PrintAndLog("Carrier: rf/%d",carrier); + } int errCnt=0; errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert); if (errCnt > maxErr){ @@ -1621,7 +1624,7 @@ int CmdIndalaDecode(const char *Cmd) uint8_t invert=0; size_t size = DemodBufferLen; size_t startIdx = indala26decode(DemodBuffer, &size, &invert); - if (startIdx < 1) { + if (startIdx < 1 || size > 224) { if (g_debugMode==1) PrintAndLog("Error2: %d",ans); return -1; diff --git a/client/cmdlf.c b/client/cmdlf.c index 602f1b9d..a310a075 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1128,13 +1128,6 @@ int CmdLFfind(const char *Cmd) return 1; } - //add psk and indala - ans=CmdIndalaDecode(""); - if (ans>0) { - PrintAndLog("\nValid Indala ID Found!"); - return 1; - } - ans=CmdAskEM410xDemod(""); if (ans>0) { PrintAndLog("\nValid EM410x ID Found!"); @@ -1165,6 +1158,12 @@ int CmdLFfind(const char *Cmd) return 1; } + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("\nValid Indala ID Found!"); + return 1; + } + ans=CmdPSKNexWatch(""); if (ans>0) { PrintAndLog("\nValid NexWatch ID Found!"); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index a12cffa2..d3d78c22 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -529,7 +529,8 @@ bool tryDetectModulation(){ } } // inverse waves does not affect this demod } - } + } + save_restoreGB(0); if ( hits == 1) { config.modulation = tests[0].modulation; config.bitrate = tests[0].bitrate; diff --git a/common/lfdemod.c b/common/lfdemod.c index 063c8a74..7297c4e6 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -11,6 +11,20 @@ #include #include #include "lfdemod.h" +#include "common.h" + +/* //un_comment to allow debug print calls when used not on device +void dummy(char *fmt, ...){} + +#ifndef ON_DEVICE +#include "ui.h" +#define prnt PrintAndLog +#else + +#define prnt dummy +#endif +*/ + uint8_t justNoise(uint8_t *BitStream, size_t size) { static const uint8_t THRESHOLD = 123; @@ -385,15 +399,15 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow // sync to first lo-hi transition, and threshold // Need to threshold first sample - - if(dest[0] < threshold_value) dest[0] = 0; + // skip 160 samples to allow antenna/samples to settle + if(dest[160] < threshold_value) dest[0] = 0; else dest[0] = 1; size_t numBits = 0; // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 - for(idx = 1; idx < size; idx++) { + for(idx = 161; idx < size-20; idx++) { // threshold current value if (dest[idx] < threshold_value) dest[idx] = 0; @@ -404,11 +418,11 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow preLastSample = LastSample; LastSample = currSample; currSample = idx-last_transition; - if (currSample < (fclow-2)){ //0-5 = garbage noise + if (currSample < (fclow-2)){ //0-5 = garbage noise (or 0-3) //do nothing with extra garbage - } else if (currSample < (fchigh-1)) { //6-8 = 8 sample waves + } else if (currSample < (fchigh-1)) { //6-8 = 8 sample waves or 3-6 = 5 if (LastSample > (fchigh-2) && (preLastSample < (fchigh-1) || preLastSample == 0 )){ - dest[numBits-1]=1; //correct last 9 wave surrounded by 8 waves + dest[numBits-1]=1; //correct previous 9 wave surrounded by 8 waves } dest[numBits++]=1; @@ -439,23 +453,8 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, //if lastval was 1, we have a 1->0 crossing if (dest[idx-1]==1) { - if (!numBits) { - if (n < rfLen/fclow) { - n=0; - lastval = dest[idx]; - continue; - } - n = (n * fclow + rfLen/4) / rfLen; - } else { - n = (n * fclow + rfLen/2) / rfLen; - } + n = (n * fclow + rfLen/2) / rfLen; } else {// 0->1 crossing - //test first bitsample too small - if (!numBits && n < rfLen/fchigh) { - n=0; - lastval = dest[idx]; - continue; - } n = (n * fchigh + rfLen/2) / rfLen; } if (n == 0) n = 1; @@ -477,6 +476,7 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, } return numBits; } + //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) @@ -686,7 +686,7 @@ int AWIDdemodFSK(uint8_t *dest, size_t *size) } // by marshmellow -// FSK Demod then try to locate an Farpointe Data (pyramid) ID +// FSK Demod then try to locate a Farpointe Data (pyramid) ID int PyramiddemodFSK(uint8_t *dest, size_t *size) { //make sure buffer has data @@ -707,35 +707,24 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) return (int)startIdx; } -/* -void dummy(char *fmt, ...){} - -#ifndef ON_DEVICE -#include "ui.h" -#define prnt PrintAndLog -#else - -#define prnt dummy -#endif -*/ // by marshmellow // to detect a wave that has heavily clipped (clean) samples uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) { - uint16_t allPeaks=1; + bool allArePeaks = true; uint16_t cntPeaks=0; size_t loopEnd = 512+160; if (loopEnd > size) loopEnd = size; for (size_t i=160; ilow && dest[i] 300) return 1; + if (!allArePeaks){ + if (cntPeaks > 300) return true; } - return allPeaks; + return allArePeaks; } // by marshmellow // to help detect clocks on heavily clipped samples @@ -983,26 +972,15 @@ int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low){ size_t i = 0; size_t transition1 = 0; int lowestTransition = 255; - uint8_t lastWasHigh=0; - //find first valid beginning of a high/low wave - if (dest[i] >= peak) { - for (; i < size; i++) { - if (dest[i] <= low) break; - } - lastWasHigh=0; - } else if (dest[i] <= low) { - for (; i < size; i++) { - if (dest[i] >= peak) break; - } - lastWasHigh=1; - } else { - for (; i < size; i++) { - if (dest[i] >= peak || dest[i] <= low) { - lastWasHigh = (dest[i] >= peak); - break; - } - } - } + bool lastWasHigh = false; + + //find first valid beginning of a high or low wave + while ((dest[i] >= peak || dest[i] <= low) && (i < size)) + ++i; + while ((dest[i] < peak && dest[i] > low) && (i < size)) + ++i; + lastWasHigh = (dest[i] >= peak); + if (i==size) return 0; transition1 = i; @@ -1013,6 +991,7 @@ int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low){ transition1 = i; } } + //prnt("DEBUG: LowestTrs: %d",lowestTransition); if (lowestTransition == 255) lowestTransition = 0; return lowestTransition; } @@ -1035,7 +1014,6 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return 0; int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low); - //prnt("DEBUG: peak: %d, low: %d",peak,low); size_t ii; uint8_t clkCnt; uint8_t tol = 0; @@ -1043,14 +1021,14 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) int16_t peakcnt = 0; int16_t peaksdet[] = {0,0,0,0,0,0,0,0}; uint16_t maxPeak = 255; - uint8_t firstpeak = 0; + bool firstpeak = false; //test for large clipped waves for (i=0; i= peak || dest[i] <= low){ if (!firstpeak) continue; smplCnt++; } else { - firstpeak=1; + firstpeak=true; if (smplCnt > 6 ){ if (maxPeak > smplCnt){ maxPeak = smplCnt; @@ -1062,8 +1040,12 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) } } } - uint8_t samePeak=0; - uint8_t errBitHigh=0; + bool errBitHigh = 0; + bool bitHigh = 0; + uint8_t ignoreCnt = 0; + uint8_t ignoreWindow = 4; + bool lastPeakHigh = 0; + int lastBit = 0; peakcnt=0; //test each valid clock from smallest to greatest to see which lines up for(clkCnt=0; clkCnt < 8; ++clkCnt){ @@ -1072,42 +1054,41 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) //try lining up the peaks by moving starting point (try first 256) for (ii=20; ii < loopCnt; ++ii){ if ((dest[ii] >= peak) || (dest[ii] <= low)){ - peakcnt=0; - uint8_t bitHigh =0; - uint8_t ignoreCnt = 0; - uint8_t ignoreWindow = 4; - int lastBit = ii-clk[clkCnt]; + peakcnt = 0; + bitHigh = false; + ignoreCnt = 0; + lastBit = ii-clk[clkCnt]; //loop through to see if this start location works for (i = ii; i < size-20; ++i) { - // if we are at a clock bit + //if we are at a clock bit if ((i >= lastBit + clk[clkCnt] - tol) && (i <= lastBit + clk[clkCnt] + tol)) { //test high/low if (dest[i] >= peak || dest[i] <= low) { - if (samePeak) peakcnt--; - bitHigh=1; - peakcnt++; - errBitHigh = 0; + //if same peak don't count it + if ((dest[i] >= peak && !lastPeakHigh) || (dest[i] <= low && lastPeakHigh)) { + peakcnt++; + } + lastPeakHigh = (dest[i] >= peak); + bitHigh = true; + errBitHigh = false; ignoreCnt = ignoreWindow; lastBit += clk[clkCnt]; - samePeak = 1; } else if (i == lastBit + clk[clkCnt] + tol) { lastBit += clk[clkCnt]; - samePeak = 0; } //else if not a clock bit and no peaks } else if (dest[i] < peak && dest[i] > low){ - samePeak = 0; if (ignoreCnt==0){ - bitHigh=0; - if (errBitHigh==1) peakcnt--; - errBitHigh=0; + bitHigh=false; + if (errBitHigh==true) peakcnt--; + errBitHigh=false; } else { ignoreCnt--; } // else if not a clock bit but we have a peak - } else if ((dest[i]>=peak || dest[i]<=low) && (bitHigh==0)) { + } else if ((dest[i]>=peak || dest[i]<=low) && (!bitHigh)) { //error bar found no clock... - errBitHigh=1; + errBitHigh=true; } } if(peakcnt>peaksdet[clkCnt]) { @@ -1119,12 +1100,12 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) int iii=7; uint8_t best=0; for (iii=7; iii > 0; iii--){ - if (peaksdet[iii] > peaksdet[best]){ - best = iii; - } else if (peaksdet[iii] == peaksdet[best] && lowestTransition){ - if (clk[iii] > (lowestTransition - (clk[iii]/8)) && clk[iii] < (lowestTransition + (clk[iii]/8))){ + if ((peaksdet[iii] >= (peaksdet[best]-1)) && (peaksdet[iii] <= peaksdet[best]+1) && lowestTransition) { + if (clk[iii] > (lowestTransition - (clk[iii]/8)) && clk[iii] < (lowestTransition + (clk[iii]/8))) { best = iii; } + } else if (peaksdet[iii] > peaksdet[best]){ + best = iii; } //prnt("DEBUG: Clk: %d, peaks: %d, maxPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],maxPeak, clk[best], lowestTransition); } @@ -1236,18 +1217,18 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc size_t i; if (size == 0) return 0; - uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); + uint8_t fcTol = ((fcHigh*100 - fcLow*100)/2 + 50)/100; //(uint8_t)(0.5+(float)(fcHigh-fcLow)/2); rfLensFnd=0; fcCounter=0; rfCounter=0; firstBitFnd=0; //PrintAndLog("DEBUG: fcTol: %d",fcTol); - // prime i to first up transition - for (i = 1; i < size-1; i++) + // prime i to first peak / up transition + for (i = 160; i < size-20; i++) if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1]) break; - for (; i < size-1; i++){ + for (; i < size-20; i++){ fcCounter++; rfCounter++; @@ -1265,7 +1246,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc //not the same size as the last wave - start of new bit sequence if (firstBitFnd > 1){ //skip first wave change - probably not a complete bit for (int ii=0; ii<15; ii++){ - if (rfLens[ii] == rfCounter){ + if (rfLens[ii] >= (rfCounter-4) && rfLens[ii] <= (rfCounter+4)){ rfCnts[ii]++; rfCounter = 0; break; @@ -1287,7 +1268,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15; for (i=0; i<15; i++){ - //PrintAndLog("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]); + //prnt("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]); //get highest 2 RF values (might need to get more values to compare or compare all?) if (rfCnts[i]>rfCnts[rfHighest]){ rfHighest3=rfHighest2; @@ -1304,12 +1285,13 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc // we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off uint8_t tol1 = fcHigh+1; - //PrintAndLog("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]); + //prnt("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]); // loop to find the highest clock that has a remainder less than the tolerance // compare samples counted divided by + // test 128 down to 32 (shouldn't be possible to have fc/10 & fc/8 and rf/16 or less) int ii=7; - for (; ii>=0; ii--){ + for (; ii>=2; ii--){ if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){ if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){ if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){ @@ -1330,8 +1312,8 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc //mainly used for FSK field clock detection uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) { - uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; - uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t fcLensFnd = 0; uint8_t lastFCcnt=0; uint8_t fcCounter = 0; @@ -1339,11 +1321,11 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) if (size == 0) return 0; // prime i to first up transition - for (i = 1; i < size-1; i++) + for (i = 160; i < size-20; i++) if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) break; - for (; i < size-1; i++){ + for (; i < size-20; i++){ if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ // new up transition fcCounter++; @@ -1356,14 +1338,14 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) lastFCcnt = fcCounter; } // find which fcLens to save it to: - for (int ii=0; ii<10; ii++){ + for (int ii=0; ii<15; ii++){ if (fcLens[ii]==fcCounter){ fcCnts[ii]++; fcCounter=0; break; } } - if (fcCounter>0 && fcLensFnd<10){ + if (fcCounter>0 && fcLensFnd<15){ //add new fc length fcCnts[fcLensFnd]++; fcLens[fcLensFnd++]=fcCounter; @@ -1375,11 +1357,11 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) } } - uint8_t best1=9, best2=9, best3=9; + uint8_t best1=14, best2=14, best3=14; uint16_t maxCnt1=0; // go through fclens and find which ones are bigest 2 - for (i=0; i<10; i++){ - // PrintAndLog("DEBUG: FC %d, Cnt %d, Errs %d",fcLens[i],fcCnts[i],errCnt); + for (i=0; i<15; i++){ + //prnt("DEBUG: FC %d, Cnt %d",fcLens[i],fcCnts[i]); // get the 3 best FC values if (fcCnts[i]>maxCnt1) { best3=best2; @@ -1393,6 +1375,7 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) best3=i; } } + if (fcLens[best1]==0) return 0; uint8_t fcH=0, fcL=0; if (fcLens[best1]>fcLens[best2]){ fcH=fcLens[best1]; @@ -1401,11 +1384,13 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) fcH=fcLens[best2]; fcL=fcLens[best1]; } + //prnt("DEBUG: dd %d > %d",(size-180)/fcH/3,fcCnts[best1]+fcCnts[best2]); + if ((size-180)/fcH/3 > fcCnts[best1]+fcCnts[best2]) return 0; //lots of waves not psk or fsk // TODO: take top 3 answers and compare to known Field clocks to get top 2 uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; - // PrintAndLog("DEBUG: Best %d best2 %d best3 %d",fcLens[best1],fcLens[best2],fcLens[best3]); + //prnt("DEBUG: Best %d best2 %d best3 %d",fcLens[best1],fcLens[best2],fcLens[best3]); if (fskAdj) return fcs; return fcLens[best1]; }