From: marshmellow42 Date: Fri, 19 Dec 2014 17:14:27 +0000 (-0500) Subject: Final touches on IO prox and HID prox demod X-Git-Tag: v2.0.0-rc1~75^2~18 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/b3b706693bedcdece33c4b189a993cbe54bd3612?ds=sidebyside Final touches on IO prox and HID prox demod makes both more robust and handles various error situations. --- diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 95a9fcf6..94d9d1fb 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -630,17 +630,32 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) LED_A_OFF(); } +//translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_demod(uint8_t * dest, size_t size) { uint32_t last_transition = 0; uint32_t idx = 1; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - uint8_t threshold_value = 127; + uint32_t maxVal=0; + // // we don't care about actual value, only if it's more or less than a + // // threshold essentially we capture zero crossings for later analysis + + // we do care about the actual 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 size; + for(idx=1; idx<100; idx++){ + if(maxVal1 transition if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - - if (idx-last_transition < 9) { - dest[numBits]=1; + if (idx-last_transition<6){ + //do nothing with extra garbage + } else if (idx-last_transition < 9) { + dest[numBits]=1; } else { - dest[numBits]=0; + dest[numBits]=0; } last_transition = idx; numBits++; @@ -668,8 +684,14 @@ size_t fsk_demod(uint8_t * dest, size_t size) return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } +uint32_t myround(float f) +{ + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); +} -size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits, uint8_t invert ) +//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 h2l_crossing_value,uint8_t l2h_crossing_value, { uint8_t lastval=dest[0]; uint32_t idx=0; @@ -684,9 +706,11 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint } //if lastval was 1, we have a 1->0 crossing if ( dest[idx-1]==1 ) { - n=(n+1) / h2l_crossing_value; + n=myround((float)(n+1)/((float)(rfLen)/(float)8)); + //n=(n+1) / h2l_crossing_value; } else {// 0->1 crossing - n=(n+1) / l2h_crossing_value; + n=myround((float)(n+1)/((float)(rfLen-2)/(float)10)); + //n=(n+1) / l2h_crossing_value; } if (n == 0) n = 1; @@ -696,8 +720,7 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint memset(dest+numBits, dest[idx-1] , n); }else{ memset(dest+numBits, dest[idx-1]^1 , n); - } - + } numBits += n; } n=0; @@ -705,7 +728,7 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint }//end for return numBits; } -// loop to capture raw HID waveform then FSK demodulate the TAG ID from it +// loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = (uint8_t *)BigBuf; @@ -723,7 +746,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition125k_internal(-1,true); size = sizeof(BigBuf); - + if (size < 2000) continue; // FSK demodulator size = fsk_demod(dest, size); @@ -731,7 +754,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // 1->0 : fc/8 in sets of 6 (RF/50 / 8 = 6.25) // 0->1 : fc/10 in sets of 5 (RF/50 / 10= 5) // do not invert - size = aggregate_bits(dest,size, 6,5,5,0); + size = aggregate_bits(dest,size, 50,5,0); //6,5,5,0 WDT_HIT(); @@ -740,8 +763,11 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; int numshifts = 0; idx = 0; + //one scan + uint8_t sameCardCount =0; while( idx + sizeof(frame_marker_mask) < size) { // search for a start of frame marker + if (sameCardCount>2) break; //only up to 2 valid sets of data for the same read of looping card data if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { // frame marker found idx+=sizeof(frame_marker_mask); @@ -818,6 +844,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); } + sameCardCount++; if (findone){ if (ledcontrol) LED_A_OFF(); return; @@ -864,51 +891,68 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_ON(); DoAcquisition125k_internal(-1,true); size = sizeof(BigBuf); - - // FSK demodulator - size = fsk_demod(dest, size); - // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns - // 1->0 : fc/8 in sets of 7 (RF/64 / 8 = 8) - // 0->1 : fc/10 in sets of 6 (RF/64 / 10 = 6.4) - size = aggregate_bits(dest, size, 7,6,13,1); //13 max Consecutive should be ok as most 0s in row should be 10 for init seq - invert bits - WDT_HIT(); - //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 - 64); idx++) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - short version = bytebits_to_byte(dest+idx+28,8); //14,4 - char facilitycode = bytebits_to_byte(dest+idx+19,8) ; - uint16_t number = (bytebits_to_byte(dest+idx+37,8)<<8)|(bytebits_to_byte(dest+idx+46,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - } + //make sure buffer has data + if (size < 64) return; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<64;idx++){ + if (testMax170){ + //Dbprintf("testMax: %d",testMax); + // FSK demodulator + size = fsk_demod(dest, size); + // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns + // 1->0 : fc/8 in sets of 7 (RF/64 / 8 = 8) + // 0->1 : fc/10 in sets of 6 (RF/64 / 10 = 6.4) + size = aggregate_bits(dest, size, 64, 13, 1); //13 max Consecutive should be ok as most 0s in row should be 10 for init seq - invert bits + WDT_HIT(); + //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 sameCardCount=0; + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 74); idx++) { + if (sameCardCount>2) break; + 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 + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + short version = bytebits_to_byte(dest+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(dest+idx+19,8) ; + uint16_t number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + + Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + sameCardCount++; + } + } + } + } WDT_HIT(); } DbpString("Stopped"); diff --git a/client/cmddata.c b/client/cmddata.c index b34ed8e0..93aaf953 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -69,6 +69,9 @@ int CmdAmp(const char *Cmd) * Arguments: * c : 0 or 1 */ + //this method is dependant on all highs and lows to be the same(or clipped) this could be an issue[marshmellow] + //might be able to use clock to help identify highs and lows with some more tolerance + //but for now I will try a fuzz factor int Cmdaskdemod(const char *Cmd) { int i; @@ -79,7 +82,7 @@ int Cmdaskdemod(const char *Cmd) sscanf(Cmd, "%i", &c); /* Detect high and lows and clock */ - // (AL - clock???) + // (AL - clock???) for (i = 0; i < GraphTraceLen; ++i) { if (GraphBuffer[i] > high) @@ -91,12 +94,15 @@ int Cmdaskdemod(const char *Cmd) PrintAndLog("Invalid argument: %s", Cmd); return 0; } - + //prime loop if (GraphBuffer[0] > 0) { GraphBuffer[0] = 1-c; } else { GraphBuffer[0] = c; } + //20% fuzz [marshmellow] + high=(int)(.8*high); + low=(int)(.8*low); for (i = 1; i < GraphTraceLen; ++i) { /* Transitions are detected at each peak * Transitions are either: @@ -106,9 +112,10 @@ int Cmdaskdemod(const char *Cmd) * low for long periods, others just reach the peak and go * down) */ - if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { + //[marhsmellow] changed == to >= for high and <= for low + if ((GraphBuffer[i] >= high) && (GraphBuffer[i - 1] == c)) { GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ + } else if ((GraphBuffer[i] <= low) && (GraphBuffer[i - 1] == (1 - c))){ GraphBuffer[i] = c; } else { /* No transition */ @@ -264,7 +271,421 @@ int CmdDetectClockRate(const char *Cmd) return 0; } +//demod GraphBuffer wave to 0s and 1s for each wave - 0s for short waves 1s for long waves +size_t fsk_wave_demod(int size) +{ + uint32_t last_transition = 0; + uint32_t idx = 1; + uint32_t maxVal = 0; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + for(idx=1; idx1 transition + if (GraphBuffer[idx-1] < GraphBuffer[idx]) { // 0 -> 1 transition + if (idx-last_transition<6){ + // do nothing with extra garbage (shouldn't be any) noise tolerance? + } else if(idx-last_transition < 9) { + GraphBuffer[numBits]=1; + // Other fsk demods reverse this making the short waves 1 and long waves 0 + // this is really backwards... smaller waves will typically be 0 and larger 1 [marshmellow] + // but will leave as is and invert when needed later + } else{ + GraphBuffer[numBits]=0; + } + last_transition = idx; + numBits++; + // PrintAndLog("numbits %d",numBits); + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 +} +uint32_t myround(float f) +{ + if (f >= UINT_MAX) return UINT_MAX; + return (uint32_t) (f + (float)0.5); +} +//translate 11111100000 to 10 +size_t aggregate_bits(int size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert) //,uint8_t l2h_crossing_value +{ + int lastval=GraphBuffer[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; + uint32_t n2=0; + for( idx=1; idx < size; idx++) { + + if (GraphBuffer[idx]==lastval) { + n++; + continue; + } + // if lastval was 1, we have a 1->0 crossing + if ( GraphBuffer[idx-1]==1 ) { + n=myround((float)(n+1)/((float)(rfLen)/(float)8)); //-2 noise tolerance + + // n=(n+1) / h2l_crossing_value; + //truncating could get us into trouble + //now we will try with actual clock (RF/64 or RF/50) variable instead + //then devide with float casting then truncate after more acurate division + //and round to nearest int + //like n = (((float)n)/(float)rfLen/(float)10); + } else {// 0->1 crossing + n=myround((float)(n+1)/((float)(rfLen-2)/(float)10)); // as int 120/6 = 20 as float 120/(64/10) = 18 (18.75) + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; //this should never happen... should we error if it does? + + if (n < maxConsequtiveBits) // Consecutive //when the consecutive bits are low - the noise tolerance can be high + //if it is high then we must be careful how much noise tolerance we allow + { + if (invert==0){ // do not invert bits + for (n2=0; n20 && strlen(Cmd)<=2) { + rfLen=param_get8(Cmd, 0); //if rfLen option only is used + if (rfLen==1){ + invert=1; //if invert option only is used + rfLen = 50; + } else if(rfLen==0) rfLen=50; + } + if (strlen(Cmd)>2) { + rfLen=param_get8(Cmd, 0); //if both options are used + invert=param_get8(Cmd,1); + } + PrintAndLog("Args invert: %d \nClock:%d",invert,rfLen); + + size_t size = fskdemod(rfLen,invert); + + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (7*32)+2) size = (7*32)+2; //only output a max of 7 blocks of 32 bits most tags will have full bit stream inside that sample size + + for (int i = 2; i < (size-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + GraphBuffer[i], + GraphBuffer[i+1], + GraphBuffer[i+2], + GraphBuffer[i+3], + GraphBuffer[i+4], + GraphBuffer[i+5], + GraphBuffer[i+6], + GraphBuffer[i+7], + GraphBuffer[i+8], + GraphBuffer[i+9], + GraphBuffer[i+10], + GraphBuffer[i+11], + GraphBuffer[i+12], + GraphBuffer[i+13], + GraphBuffer[i+14], + GraphBuffer[i+15]); + } + ClearGraph(1); + return 0; +} + +int CmdFSKdemodHID(const char *Cmd) +{ + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + uint8_t rfLen = 50; + uint8_t invert=0;//param_get8(Cmd, 0); + size_t idx=0; + uint32_t hi2=0, hi=0, lo=0; + + //get binary from fsk wave + size_t size = fskdemod(rfLen,invert); + + // final loop, go over previously decoded fsk data and now manchester decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + int frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + while( idx + 6 < size) { + // search for a start of frame marker + + if ( memcmp(GraphBuffer+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=6;//sizeof(frame_marker_mask); //size of int is >6 + while(GraphBuffer[idx] != GraphBuffer[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); + //Then, shift in a 0 or one into low + if (GraphBuffer[idx] && !GraphBuffer[idx+1]) // 1 0 + lo=(lo<<1)|0; + else // 0 1 + lo=(lo<<1)|1; + numshifts++; + idx += 2; + } + + //PrintAndLog("Num shifts: %d ", numshifts); + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + 6 < size) + { + if ( memcmp(GraphBuffer+(idx), frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + if (hi2 != 0){ //extra large HID tags + PrintAndLog("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + } + else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + + PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + ClearGraph(1); + return 0; + } + } + } + // reset + hi2 = hi = lo = 0; + numshifts = 0; + }else + { + idx++; + } + } + if (idx + sizeof(frame_marker_mask) >= size){ + PrintAndLog("start bits for hid not found"); + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (7*32)+2) size = (7*32)+2; //only output a max of 7 blocks of 32 bits most tags will have full bit stream inside that sample size + + for (int i = 2; i < (size-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + GraphBuffer[i], + GraphBuffer[i+1], + GraphBuffer[i+2], + GraphBuffer[i+3], + GraphBuffer[i+4], + GraphBuffer[i+5], + GraphBuffer[i+6], + GraphBuffer[i+7], + GraphBuffer[i+8], + GraphBuffer[i+9], + GraphBuffer[i+10], + GraphBuffer[i+11], + GraphBuffer[i+12], + GraphBuffer[i+13], + GraphBuffer[i+14], + GraphBuffer[i+15]); + } + } + ClearGraph(1); + return 0; +} + + +int CmdFSKdemodIO(const char *Cmd) +{ + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + uint8_t rfLen = 64; + uint8_t invert=1; + size_t idx=0; + uint8_t testMax=0; + //test samples are not just noise + if (GraphTraceLen < 64) return 0; + for(idx=0;idx<64;idx++){ + if (testMax40){ + //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 (raw) + //Handle the data + int mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 74); idx++) { + if ( memcmp(GraphBuffer + idx, mask, sizeof(mask))==0) { + //frame marker found + if (GraphBuffer[idx+17]==1 && GraphBuffer[idx+26]==1 && GraphBuffer[idx+35]==1 && GraphBuffer[idx+44]==1 && GraphBuffer[idx+53]==1){ + //confirmed proper separator bits found + + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx], GraphBuffer[idx+1], GraphBuffer[idx+2], GraphBuffer[idx+3], GraphBuffer[idx+4], GraphBuffer[idx+5], GraphBuffer[idx+6], GraphBuffer[idx+7], GraphBuffer[idx+8]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+9], GraphBuffer[idx+10], GraphBuffer[idx+11],GraphBuffer[idx+12],GraphBuffer[idx+13],GraphBuffer[idx+14],GraphBuffer[idx+15],GraphBuffer[idx+16],GraphBuffer[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+18], GraphBuffer[idx+19], GraphBuffer[idx+20],GraphBuffer[idx+21],GraphBuffer[idx+22],GraphBuffer[idx+23],GraphBuffer[idx+24],GraphBuffer[idx+25],GraphBuffer[idx+26]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+27], GraphBuffer[idx+28], GraphBuffer[idx+29],GraphBuffer[idx+30],GraphBuffer[idx+31],GraphBuffer[idx+32],GraphBuffer[idx+33],GraphBuffer[idx+34],GraphBuffer[idx+35]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+36], GraphBuffer[idx+37], GraphBuffer[idx+38],GraphBuffer[idx+39],GraphBuffer[idx+40],GraphBuffer[idx+41],GraphBuffer[idx+42],GraphBuffer[idx+43],GraphBuffer[idx+44]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+45], GraphBuffer[idx+46], GraphBuffer[idx+47],GraphBuffer[idx+48],GraphBuffer[idx+49],GraphBuffer[idx+50],GraphBuffer[idx+51],GraphBuffer[idx+52],GraphBuffer[idx+53]); + PrintAndLog("%d%d%d%d%d%d%d%d %d%d",GraphBuffer[idx+54],GraphBuffer[idx+55],GraphBuffer[idx+56],GraphBuffer[idx+57],GraphBuffer[idx+58],GraphBuffer[idx+59],GraphBuffer[idx+60],GraphBuffer[idx+61],GraphBuffer[idx+62],GraphBuffer[idx+63]); + + uint32_t code = bytebits_to_byte(GraphBuffer+idx,32); + uint32_t code2 = bytebits_to_byte(GraphBuffer+idx+32,32); + short version = bytebits_to_byte(GraphBuffer+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(GraphBuffer+idx+19,8) ; + uint16_t number = (bytebits_to_byte(GraphBuffer+idx+36,8)<<8)|(bytebits_to_byte(GraphBuffer+idx+45,8)); //36,9 + + PrintAndLog("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); + ClearGraph(1); + return 0; + } else { + PrintAndLog("thought we had a valid tag but did not match format"); + } + } + } + if (idx >= (size-74)){ + PrintAndLog("start bits for io prox not found"); + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (7*32)+2) size = (7*32)+2; //only output a max of 7 blocks of 32 bits most tags will have full bit stream inside that sample size + + for (int i = 2; i < (size-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + GraphBuffer[i], + GraphBuffer[i+1], + GraphBuffer[i+2], + GraphBuffer[i+3], + GraphBuffer[i+4], + GraphBuffer[i+5], + GraphBuffer[i+6], + GraphBuffer[i+7], + GraphBuffer[i+8], + GraphBuffer[i+9], + GraphBuffer[i+10], + GraphBuffer[i+11], + GraphBuffer[i+12], + GraphBuffer[i+13], + GraphBuffer[i+14], + GraphBuffer[i+15]); + } + } + } + ClearGraph(1); + return 0; +} +/* +int CmdFSKdemodHIDold(const char *Cmd)//not put in commands yet //old CmdFSKdemod needs updating { static const int LowTone[] = { 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, @@ -284,12 +705,12 @@ int CmdFSKdemod(const char *Cmd) int lowLen = sizeof (LowTone) / sizeof (int); int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; + int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen uint32_t hi = 0, lo = 0; int i, j; int minMark = 0, maxMark = 0; - + for (i = 0; i < GraphTraceLen - convLen; ++i) { int lowSum = 0, highSum = 0; @@ -321,7 +742,7 @@ int CmdFSKdemod(const char *Cmd) GraphTraceLen -= (convLen + 16); RepaintGraphWindow(); - // Find bit-sync (3 lo followed by 3 high) + // Find bit-sync (3 lo followed by 3 high) (HID ONLY) int max = 0, maxPos = 0; for (i = 0; i < 6000; ++i) { int dec = 0; @@ -382,7 +803,7 @@ int CmdFSKdemod(const char *Cmd) PrintAndLog("hex: %08x %08x", hi, lo); return 0; } - +*/ int CmdGrid(const char *Cmd) { sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); @@ -463,7 +884,7 @@ int CmdSamples(const char *Cmd) uint8_t got[40000]; n = strtol(Cmd, NULL, 0); - if (n == 0) n = 512; + if (n == 0) n = 6000; if (n > sizeof(got)) n = sizeof(got); PrintAndLog("Reading %d samples\n", n); @@ -657,30 +1078,30 @@ int CmdManchesterDemod(const char *Cmd) { if (GraphBuffer[i-1] != GraphBuffer[i]) { - lc = i-lastval; - lastval = i; - - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { + lc = i-lastval; + lastval = i; + + // Error check: if bitidx becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really + // wrong! + if (bitidx > (GraphTraceLen*2/clock+8) ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" + BitStream[bitidx++]=GraphBuffer[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + BitStream[bitidx++]=GraphBuffer[i-1]; + BitStream[bitidx++]=GraphBuffer[i-1]; + } else { // Error warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); if (warnings > 10) { @@ -697,15 +1118,15 @@ int CmdManchesterDemod(const char *Cmd) for (i = 0; i < bitidx; i += 2) { if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; + } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { + BitStream[bit2idx++] = 0 ^ invert; + } else { + // We cannot end up in this state, this means we are unsynchronized, + // move up 1 bit: + i++; warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); if (warnings > 10) { @@ -914,7 +1335,9 @@ static command_t CommandTable[] = {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, {"detectclock", CmdDetectClockRate, 1, "Detect clock rate"}, - {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"fskdemod", CmdFSKdemod, 1, "[clock rate] [invert] Demodulate graph window from FSK to binary (clock = 64 or 50)(invert = 1 or 0)"}, + {"fskdemodhid", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK"}, + {"fskdemodio", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, diff --git a/client/cmddata.h b/client/cmddata.h index 8dcefc30..6a4e6ee6 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -24,6 +24,8 @@ int CmdBuffClear(const char *Cmd); int CmdDec(const char *Cmd); int CmdDetectClockRate(const char *Cmd); int CmdFSKdemod(const char *Cmd); +int CmdFSKdemodHID(const char *Cmd); +int CmdFSKdemodIO(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd);