X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6ff6ade2f5f24ffb52a9f90238ee7b8c77edc89c..d3a22c7dfa87bf5e21d228849a602194be4a0895:/common/lfdemod.c diff --git a/common/lfdemod.c b/common/lfdemod.c index d30262f3..eb5a4d95 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -8,389 +8,418 @@ // Low frequency commands //----------------------------------------------------------------------------- +#include #include #include #include "lfdemod.h" //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream, uint32_t BitLen) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high = 0, low = 128; + uint64_t lo = 0; + uint32_t i = 0; + uint32_t initLoopMax = 65; + + if (initLoopMax > BitLen) + initLoopMax = BitLen; + + for (; i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; + } - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + return 0; + } + + uint8_t parityTest = 0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t j = 0; + uint8_t resetCnt = 0; + while( (idx + 64) < BitLen) { + + restart: - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { - restart: // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; - } - } - return 0; + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { + // frame marker found + idx += 9;//sizeof(frame_marker_mask); + for ( i = 0; i < 10; ++i){ + for( j = 0; j < 5; ++j){ + parityTest += BitStream[(i*5) + j + idx]; + } + if (parityTest == ( (parityTest >> 1) << 1)){ + parityTest = 0; + for (j = 0; j < 4; ++j){ + lo = ( lo << 1LL)|( BitStream[( i * 5 ) + j + idx]); + } + } else { + //parity failed + parityTest = 0; + idx -= 8; + if (resetCnt > 5) return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + } else { + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) +int askmandemod(uint8_t *BinStream, uint32_t *BitLen, int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default - - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 1) *invert=0; + int i; + int high = 0, low = 128; + *clk = DetectASKClock(BinStream, (size_t)*BitLen, *clk); //clock default + + if (*clk < 8 ) *clk = 64; + if (*clk < 32 ) *clk = 32; + if (*invert != 1) *invert = 0; + + uint32_t initLoopMax = 200; + if (initLoopMax > *BitLen) + initLoopMax = *BitLen; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; + // Detect high and lows + // 200 samples should be enough to find high and low values + for (i = 0; i < initLoopMax; ++i) { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + //throw away static + if ((high < 158) ) + return -2; + + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high = (int)(high * .75); + low = (int)(low+128 * .25); - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - if (*clk==32)tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); + int lastBit = 0; // set first clock check + uint32_t bitnum = 0; // output counter + + // clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + int tol = ( *clk == 32 ) ? 1 : 0; + + int j = 0; + uint32_t gLen = *BitLen; + + if (gLen > 3000) gLen = 3000; + + uint8_t errCnt = 0; + uint32_t bestStart = *BitLen; + uint32_t bestErrCnt = (*BitLen/1000); + uint32_t maxErr = bestErrCnt; //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; + for (j=0; j < gLen; ++j){ + + if ((BinStream[j] >= high)||(BinStream[j] <= low)){ + lastBit = j - *clk; + errCnt = 0; + //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { + for (i = j; i < *BitLen; ++i) { if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; + lastBit += *clk; } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ //low found and we are expecting a bar - lastBit+=*clk; + lastBit += *clk; } else { //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ + if ((i-lastBit) > (*clk + tol)){ //should have hit a high or low based on clock!! errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over + lastBit += *clk;//skip over until hit too many errors + if (errCnt > maxErr) break; //allow 1 error for every 1000 samples else start over } } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits + if ((i-j) >(400 * *clk)) break; //got plenty of bits } //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt (64 + errCnt)) && (errCnt < maxErr)) { //possible good read - if (errCnt==0){ - bestStart=iii; - bestErrCnt=errCnt; + if (errCnt == 0){ + bestStart = j; + bestErrCnt = errCnt; break; //great read - finish } - if (errCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - if (bitnum > 0){ - BinStream[bitnum]=77; - bitnum++; - } - - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; - } - *BitLen=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; - } + j = bestStart; + lastBit = bestStart - *clk; + bitnum = 0; + for (i = j; i < *BitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit += *clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit += *clk; + BinStream[bitnum] = 1 - *invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit) > (*clk+tol)){ + //should have hit a high or low based on clock!! + if (bitnum > 0){ + BinStream[bitnum] = 77; + bitnum++; + } + lastBit += *clk;//skip over error + } + } + if (bitnum >= 400) break; + } + *BitLen = bitnum; + } else { + *invert = bestStart; + *clk = j; + return -1; + } return bestErrCnt; } //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * BitStream, int *bitLen) +int manrawdecode(uint8_t * bits, int *bitlen) { - int bitnum=0; - int errCnt =0; - int i=1; + int bitnum = 0; + int errCnt = 0; int bestErr = 1000; int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; + int i = 1; + int j = 1; + + for (; j < 3; ++j){ + i = 1; + for ( i = i + j; i < *bitlen-2; i += 2){ + if ( bits[i]==1 && (bits[i+1]==0)){ + } else if ((bits[i]==0)&& bits[i+1]==1){ + } else { + errCnt++; + } + if(bitnum > 300) break; } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; + if (bestErr > errCnt){ + bestErr = errCnt; + bestRun = j; } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - BitStream[bitnum++]=0; - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - BitStream[bitnum++]=1; - } else { - BitStream[bitnum++]=77; - //errCnt++; - } - if(bitnum>300) break; + errCnt = 0; + } + errCnt = bestErr; + if (errCnt < 20){ + j = bestRun; + i = 1; + for ( i = i+j; i < *bitlen-2; i += 2){ + if ( bits[i] == 1 && bits[i + 1] == 0 ){ + bits[bitnum++] = 0; + } else if ( bits[i] == 0 && bits[i + 1] == 1 ){ + bits[bitnum++] = 1; + } else { + bits[bitnum++] = 77; + } + if ( bitnum > 300 ) break; } - *bitLen=bitnum; + *bitlen = bitnum; } - return errCnt; + return errCnt; } //by marshmellow //take 01 or 10 = 0 and 11 or 00 = 1 -int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) +int BiphaseRawDecode(uint8_t * bits, int *bitlen, int offset) { - uint8_t bitnum = 0; - uint32_t errCnt = 0; - uint32_t i = 1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; - } - if(bitnum>250) break; + uint8_t bitnum = 0; + uint32_t errCnt = 0; + uint32_t i = offset; + + for (; i < *bitlen-2; i += 2 ){ + if ( (bits[i]==1 && bits[i+1]==0)|| + (bits[i]==0 && bits[i+1]==1)){ + bits[bitnum++] = 1; + } else if ( (bits[i]==0 && bits[i+1]==0)|| + (bits[i]==1 && bits[i+1]==1)){ + bits[bitnum++] = 0; + } else { + bits[bitnum++] = 77; + errCnt++; + } + if ( bitnum > 250) break; } - *bitLen=bitnum; - return errCnt; + *bitlen = bitnum; + return errCnt; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, int *bitLen, int *clk, int *invert) { uint32_t i; - // int invert=0; //invert default + uint32_t initLoopMax = 200; int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; - - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; + uint8_t BitStream[502] = {0x00}; + + *clk = DetectASKClock(BinStream, *bitLen, *clk); //clock default + + if (*clk < 8) *clk = 64; + if (*clk < 32) *clk = 32; if (*invert != 1) *invert = 0; + + if (initLoopMax > *bitLen) + initLoopMax = *bitLen; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; // Detect high and lows for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values { if (BinStream[i] > high) - high = BinStream[i]; + high = BinStream[i]; else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - return -2; + low = BinStream[i]; } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; - - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - if (*clk==32) tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - uint32_t iii = 0; + + //throw away static + if ((high < 158)){ + return -2; + } + + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high = (int)(high * .75); + low = (int)(low+128 * .25); + + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + + uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + if (*clk==32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; + if (gLen > 500) gLen = 500; + uint32_t j = 0; + uint8_t errCnt = 0; + uint32_t bestStart = *bitLen; + uint32_t bestErrCnt = (*bitLen / 1000); + uint32_t errCntLimit = bestErrCnt; + uint8_t midBit = 0; + //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; + for (j = 0; j < gLen; ++j){ + + if ((BinStream[j] >= high)||(BinStream[j] <= low)){ + lastBit = j - *clk; //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { + for (i = j; i < *bitLen; ++i) { if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; + lastBit += *clk; BitStream[bitnum] = *invert; bitnum++; - midBit=0; + midBit = 0; } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ //low found and we are expecting a bar - lastBit+=*clk; + lastBit += *clk; BitStream[bitnum] = 1-*invert; bitnum++; midBit=0; } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; + midBit = 1; + BitStream[bitnum] = 1 - *invert; bitnum++; } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ //mid bar? - midBit=1; - BitStream[bitnum]= *invert; + midBit = 1; + BitStream[bitnum] = *invert; bitnum++; } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; + midBit = 1; + BitStream[bitnum] = BitStream[bitnum-1]; bitnum++; } else { //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ + if (( i - lastBit) > ( *clk + tol)){ //should have hit a high or low based on clock!! if (bitnum > 0){ - BitStream[bitnum]=77; + BitStream[bitnum] = 77; bitnum++; } errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over + lastBit += *clk;//skip over until hit too many errors + if (errCnt > errCntLimit){ //allow 1 error for every 1000 samples else start over + errCnt = 0; + bitnum = 0;//start over break; } } } - if (bitnum>500) break; + if (bitnum > 500) break; } //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt (64 + errCnt)) && (errCnt < errCntLimit)) { + + //great read - finish + if (errCnt == 0) break; + + //if current run == bestErrCnt run (after exhausted testing) then finish + if (bestStart == j) break; + + //set this as new best run + if (errCnt < bestErrCnt){ + bestErrCnt = errCnt; + bestStart = j; } } } - if (iii>=gLen){ //exhausted test + if (j >= gLen){ //exhausted test //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; + if (bestErrCnt < errCntLimit) + j = bestStart; } } - if (bitnum>16){ + if (bitnum > 16){ - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; + for (i = 0; i < bitnum; ++i){ + BinStream[i] = BitStream[i]; } *bitLen = bitnum; } else { @@ -403,43 +432,49 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow { uint32_t last_transition = 0; uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; + uint32_t maxVal = 0; + + if (fchigh == 0) fchigh = 10; + if (fclow == 0) fclow = 8; + // we do care about the actual theshold value as sometimes near the center of the // wave we may get static that changes direction of wave for one value // if our value is too low it might affect the read. and if our tag or // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + if ( ( idx - last_transition ) <( fclow - 2 ) ) { //0-5 = garbage noise //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + } else if ((idx - last_transition) < ( fchigh - 1 )) { //6-8 = 8 waves dest[numBits]=1; } else { //9+ = 10 waves dest[numBits]=0; @@ -448,7 +483,8 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow numBits++; } } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + //it returns the number of bytes, but each byte represents a bit: 1 or 0 + return numBits; } uint32_t myround2(float f) @@ -458,87 +494,90 @@ uint32_t myround2(float f) } //translate 11111100000 to 10 -size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, +size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert, uint8_t fchigh, uint8_t fclow ) { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval = dest[0]; + uint32_t idx = 0; + uint32_t n = 1; + size_t numBits = 0; - for( idx=1; idx < size; idx++) { + for( idx = 1; idx < size; idx++) { - if (dest[idx]==lastval) { + if (dest[idx] == lastval) { n++; continue; } //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; + if ( dest[idx-1] == 1 ) { + n = myround2( (float)( n + 1 ) / ((float)(rfLen)/(float)fclow)); + } else { // 0->1 crossing + n = myround2( (float)( n + 1 ) / ((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor } if (n == 0) n = 1; if(n < maxConsequtiveBits) //Consecutive { - if(invert==0){ //invert bits + if(invert == 0){ //invert bits memset(dest+numBits, dest[idx-1] , n); }else{ memset(dest+numBits, dest[idx-1]^1 , n); } numBits += n; } - n=0; - lastval=dest[idx]; + n = 0; + lastval = dest[idx]; }//end for 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) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + if ( size > 0 ) + size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow); + return size; } + // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - - size_t idx=0; //, found=0; //size=0, + size_t idx = 0; + int numshifts = 0; + // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); + size = fskdemod(dest, size, 50, 0, 10, 8); // final loop, go over previously decoded manchester data and decode into usable tag ID // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; + + uint8_t mask_len = sizeof frame_marker_mask / sizeof frame_marker_mask[0]; + //one scan - while( idx + sizeof(frame_marker_mask) < size) { + while( idx + mask_len < size) { // search for a start of frame marker if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { // frame marker found - idx+=sizeof(frame_marker_mask); + idx += mask_len; while(dest[idx] != dest[idx+1] && idx < size-2) { // Keep going until next frame marker (or error) // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); + *hi2 = ( *hi2 << 1 ) | ( *hi >> 31 ); + *hi = ( *hi << 1 ) | ( *lo >> 31 ); //Then, shift in a 0 or one into low if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; + *lo = ( *lo << 1 ) | 0; else // 0 1 - *lo=(*lo<<1)|1; + *lo = ( *lo << 1 ) | 1; numshifts++; idx += 2; } // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) + if(idx + mask_len < size) { if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { @@ -556,10 +595,12 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_ return -1; } -uint32_t bytebits_to_byte(uint8_t* src, int numbits) +uint32_t bytebits_to_byte(uint8_t *src, int numbits) { + //HACK: potential overflow in numbits is larger then uint32 bits. + uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) { + for(int i = 0 ; i < numbits ; ++i) { num = (num << 1) | (*src); src++; } @@ -568,41 +609,54 @@ uint32_t bytebits_to_byte(uint8_t* src, int numbits) int IOdemodFSK(uint8_t *dest, size_t size) { - uint32_t idx=0; //make sure buffer has data - if (size < 66) return -1; + if (size < 100) return -1; + + uint32_t idx = 0; + uint8_t testMax = 0; + //test samples are not just noise - uint8_t testMax=0; - for(idx=0;idx<65;idx++){ - if (testMax170){ - // FSK demodulator - size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert - if (size < 65) return -1; //did we get a good demod? - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - for( idx=0; idx < (size - 65); idx++) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ - //confirmed proper separator bits found - //return start position - return (int) idx; - } - } - } - } return 0; } @@ -611,67 +665,86 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt] peak) + peak = dest[i]; + if(dest[i] < low) + low = dest[i]; + } + + peak = (int)(peak * .75); + low = (int)(low+128 * .25); + + int ii, cnt, bestErr, tol = 0; + int errCnt[clkLen]; + memset(errCnt, 0x00, clkLen); + + int tmpIndex, tmphigh, tmplow; + + //test each valid clock from smallest to greatest to see which lines up + for( cnt = 0; cnt < clkLen; ++cnt ){ + + tol = (clk[cnt] == 32) ? 1 : 0; + bestErr = 1000; + tmpIndex = tmphigh = tmplow = 0; + + //try lining up the peaks by moving starting point (try first 256) + for (ii=0; ii < loopCnt; ++ii){ + + // not a peak? continue + if ( (dest[ii] < peak) && (dest[ii] > low)) + continue; + + errCnt[cnt] = 0; + + // now that we have the first one lined up test rest of wave array + for ( i = 0; i < ((int)(size / clk[cnt]) - 1); ++i){ + + tmpIndex = ii + (i * clk[cnt] ); + tmplow = dest[ tmpIndex - tol]; + tmphigh = dest[ tmpIndex + tol]; + + if ( dest[tmpIndex] >= peak || dest[tmpIndex] <= low ) { + } + else if ( tmplow >= peak || tmplow <= low){ + } + else if ( tmphigh >= peak || tmphigh <= low){ + } + else + errCnt[cnt]++; //error no peak detected + } + + //if we found no errors this is correct one - return this clock + if ( errCnt[cnt] == 0 ) + return clk[cnt]; + + if ( errCnt[cnt] < bestErr) + bestErr = errCnt[cnt]; + } + // save the least error. + errCnt[cnt] = bestErr; + } + // find best clock which has lowest number of errors + int j = 0, bestIndex = 0; + for (; j < clkLen; ++j){ + if ( errCnt[j] < errCnt[bestIndex] ) + bestIndex = j; + } + return clk[bestIndex]; }