From: marshmellow42 Date: Fri, 6 Feb 2015 19:45:46 +0000 (-0500) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Tag: v2.0.0-rc1~26^2~2 X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/be2cf126bf74c3e0c60706dd2620c8a6d742e396?hp=146c201cbe67cf3967cb497b3d67fb579c3ccb0e Merge remote-tracking branch 'upstream/master' --- diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 479da772..e34eab35 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -640,7 +640,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) uint8_t *dest = BigBuf_get_addr(); size_t size=0, idx=0; - int clk=0, invert=0, errCnt=0; + int clk=0, invert=0, errCnt=0, maxErr=20; uint64_t lo=0; // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); @@ -654,7 +654,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) size = BigBuf_max_traceLen(); //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode - errCnt = askmandemod(dest, &size, &clk, &invert); + errCnt = askmandemod(dest, &size, &clk, &invert, maxErr); //Dbprintf("DEBUG: ASK Got"); WDT_HIT(); diff --git a/client/cmddata.c b/client/cmddata.c index 430afb17..a1159ec8 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -249,44 +249,113 @@ void printEM410x(uint64_t id) } //by marshmellow -//take binary from demod buffer and see if we can find an EM410x ID -int CmdEm410xDecode(const char *Cmd) +//takes 3 arguments - clock, invert and maxErr as integers +//attempts to demodulate ask while decoding manchester +//prints binary found and saves in graphbuffer for further commands +int CmdAskEM410xDemod(const char *Cmd) { - uint64_t id=0; - size_t size = DemodBufferLen, idx=0; - id = Em410xDecode(DemodBuffer, &size, &idx); - if (id>0){ - setDemodBuf(DemodBuffer, size, idx); + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer"); + PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data"); + PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); + + return 0; + } + + + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + size_t BitLen = getFromGraphBuf(BitStream); + + if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt<0||BitLen<16){ //if fatal error (or -1) + if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + return 0; + } + PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); + + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + //PrintAndLog("ASK/Manchester decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + setDemodBuf(BitStream,BitLen,0); + //printDemodBuff(); + uint64_t lo =0; + size_t idx=0; + lo = Em410xDecode(BitStream, &BitLen, &idx); + if (lo>0){ + //set GraphBuffer for clone or sim command + setDemodBuf(BitStream, BitLen, idx); if (g_debugMode){ - PrintAndLog("DEBUG: Printing demod buffer:"); + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); printDemodBuff(); } - printEM410x(id); - return 1; + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; } return 0; } - //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 3 arguments - clock, invert, maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { int invert=0; int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askmandemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askmandemod = demod an ask/manchester tag from GraphBuffer"); + PrintAndLog(" : data askmandemod 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askmandemod 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askmandemod 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askmandemod 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } - + if (clk==1){ + invert=1; + clk=0; + } size_t BitLen = getFromGraphBuf(BitStream); if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); if (errCnt<0||BitLen<16){ //if fatal error (or -1) if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; @@ -315,7 +384,7 @@ int Cmdaskmandemod(const char *Cmd) printEM410x(lo); return 1; } - return 0; + return 1; } //by marshmellow @@ -326,6 +395,17 @@ int Cmdmandecoderaw(const char *Cmd) int i =0; int errCnt=0; size_t size=0; + size_t maxErr = 20; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data manrawdecode"); + PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); + return 0; + } + if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; for (;i=20){ + if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; } @@ -377,7 +457,21 @@ int CmdBiphaseDecodeRaw(const char *Cmd) int offset=0; int invert=0; int high=0, low=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data biphaserawdecode [offset] "); + PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position"); + PrintAndLog(" [invert <0|1>], set to 1 to invert output"); + PrintAndLog(""); + PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer"); + PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output"); + return 0; + } sscanf(Cmd, "%i %i", &offset, &invert); + if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; //get graphbuffer & high and low for (;i 12 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askrawdemod [clock] [maxError] [amplify]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); + PrintAndLog(""); + PrintAndLog(" sample: data askrawdemod = demod an ask tag from GraphBuffer"); + PrintAndLog(" : data askrawdemod a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLog(" : data askrawdemod 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askrawdemod 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askrawdemod 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askrawdemod 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data askrawdemod 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } + if (clk==1){ + invert=1; + clk=0; + } + if (amp == 'a' || amp == 'A') askAmp=1; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); + errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) PrintAndLog("no data found"); if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); return 0; } - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //move BitStream back to DemodBuffer setDemodBuf(BitStream,BitLen,0); //output if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); } PrintAndLog("ASK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@ -630,20 +750,47 @@ int CmdGraphShiftZero(const char *Cmd) return 0; } +//by marshmellow +//use large jumps in read samples to identify edges of waves and then amplify that wave to max +//similar to dirtheshold, threshold, and askdemod commands +//takes a threshold length which is the measured length between two samples then determines an edge +int CmdAskEdgeDetect(const char *Cmd) +{ + int thresLen = 25; + sscanf(Cmd, "%i", &thresLen); + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=thresLen) //large jump up + shift=127; + else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down + shift=-127; + + shiftedVal=GraphBuffer[i]+shift; + + if (shiftedVal>127) + shiftedVal=127; + else if (shiftedVal<-127) + shiftedVal=-127; + GraphBuffer[i-1] = shiftedVal; + } + RepaintGraphWindow(); + //CmdNorm(""); + return 0; +} + /* Print our clock rate */ // uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) { - GetClock("",0,0); - //int clock = DetectASKClock(0); - //PrintAndLog("Auto-detected clock rate: %d", clock); - return 0; + int ans = GetClock("",0,0); + return ans; } //by marshmellow //fsk raw demod and print binary -//takes 4 arguments - Clock, invert, rchigh, rclow -//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) +//takes 4 arguments - Clock, invert, fchigh, fclow +//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave @@ -652,6 +799,23 @@ int CmdFSKrawdemod(const char *Cmd) int invert=0; int fchigh=0; int fclow=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data fskrawdemod [clock] [fchigh] [fclow]"); + PrintAndLog(" [set clock as integer] optional, omit for autodetect."); + PrintAndLog(" , 1 for invert output, can be used even if the clock is omitted"); + PrintAndLog(" [fchigh], larger field clock length, omit for autodetect"); + PrintAndLog(" [fclow], small field clock length, omit for autodetect"); + PrintAndLog(""); + PrintAndLog(" sample: data fskrawdemod = demod an fsk tag from GraphBuffer using autodetect"); + PrintAndLog(" : data fskrawdemod 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); + PrintAndLog(" : data fskrawdemod 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); + PrintAndLog(" : data fskrawdemod 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); + PrintAndLog(" : data fskrawdemod 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); + return 0; + } //set options from parameters entered with the command sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); @@ -664,10 +828,12 @@ int CmdFSKrawdemod(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get field clock lengths uint16_t fcs=0; + uint8_t dummy=0; if (fchigh==0 || fclow == 0){ - fcs=countFC(BitStream, BitLen); + fcs=countFC(BitStream, BitLen, &dummy); if (fcs==0){ fchigh=10; fclow=8; @@ -690,6 +856,7 @@ int CmdFSKrawdemod(const char *Cmd) // Now output the bitstream to the scrollback by line of 16 bits if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size printBitStream(BitStream,size); + return 1; } else{ PrintAndLog("no FSK data found"); } @@ -706,8 +873,9 @@ int CmdFSKdemodHID(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave - int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); + int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ if (g_debugMode){ if (idx==-1){ @@ -791,6 +959,7 @@ int CmdFSKdemodParadox(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ @@ -842,6 +1011,7 @@ int CmdFSKdemodIO(const char *Cmd) } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave idx = IOdemodFSK(BitStream,BitLen); @@ -918,6 +1088,7 @@ int CmdFSKdemodAWID(const char *Cmd) //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = AWIDdemodFSK(BitStream, &size); @@ -1017,6 +1188,7 @@ int CmdFSKdemodPyramid(const char *Cmd) //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = PyramiddemodFSK(BitStream, &size); @@ -1256,8 +1428,9 @@ int CmdFSKfcDetect(const char *Cmd) { uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); - - uint16_t ans = countFC(BitStream, size); + if (size==0) return 0; + uint8_t dummy = 0; + uint16_t ans = countFC(BitStream, size, &dummy); if (ans==0) { if (g_debugMode) PrintAndLog("DEBUG: No data found"); return 0; @@ -1271,44 +1444,69 @@ int CmdFSKfcDetect(const char *Cmd) if (g_debugMode) PrintAndLog("DEBUG: Clock detect error"); return 0; } - PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); - return 1; + if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + return 1; + } + if (g_debugMode){ + PrintAndLog("DEBUG: unknown fsk field clock detected"); + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + } + return 0; } //by marshmellow -//attempt to detect the bit clock for PSK or NRZ modulations -int CmdDetectNRZpskClockRate(const char *Cmd) +//attempt to detect the bit clock for PSK modulations +int CmdDetectPSKClockRate(const char *Cmd) { - GetNRZpskClock("",0,0); + GetPskClock("",0,0); return 0; } //by marshmellow -//attempt to psk1 or nrz demod graph buffer -//NOTE CURRENTLY RELIES ON PEAKS :( -int PSKnrzDemod(const char *Cmd, uint8_t verbose) +//attempt to detect the bit clock for NRZ modulations +int CmdDetectNRZClockRate(const char *Cmd) { - int invert=0; - int clk=0; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); - return -1; - } - if (verbose) PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + GetNrzClock("",0,0); + return 0; +} - //prime demod buffer for output - setDemodBuf(BitStream,BitLen,0); - return errCnt; +//by marshmellow +//attempt to psk1 demod graph buffer +int PSKDemod(const char *Cmd, uint8_t verbose) +{ + int invert=0; + int clk=0; + int maxErr=100; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; + } + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = pskRawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + return errCnt; } + + // Indala 26 bit decode // by marshmellow // optional arguments - same as CmdpskNRZrawDemod (clock & invert) @@ -1316,9 +1514,9 @@ int CmdIndalaDecode(const char *Cmd) { int ans; if (strlen(Cmd)>0){ - ans = PSKnrzDemod(Cmd, 0); + ans = PSKDemod(Cmd, 0); } else{ //default to RF/32 - ans = PSKnrzDemod("32", 0); + ans = PSKDemod("32", 0); } if (ans < 0){ @@ -1390,6 +1588,7 @@ int CmdIndalaDecode(const char *Cmd) return 1; } +/* //by marshmellow //attempt to clean psk wave noise after a peak //NOTE RELIES ON PEAKS :( @@ -1401,35 +1600,104 @@ int CmdPskClean(const char *Cmd) setGraphBuf(bitStream, bitLen); return 0; } +*/ // by marshmellow -// takes 2 arguments - clock and invert both as integers +// takes 3 arguments - clock, invert, maxErr as integers +// attempts to demodulate nrz only +// prints binary found and saves in demodbuffer for further commands +int CmdNRZrawDemod(const char *Cmd) +{ + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data nrzrawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer"); + PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); + PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } + + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; + } + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + }else{ + } + PrintAndLog("NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; +} + +// by marshmellow +// takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate psk only // prints binary found and saves in demodbuffer for further commands -int CmdpskNRZrawDemod(const char *Cmd) +int CmdPSK1rawDemod(const char *Cmd) { int errCnt; - - errCnt = PSKnrzDemod(Cmd, 1); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk1rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk1rawdemod = demod a psk1 tag from GraphBuffer"); + PrintAndLog(" : data psk1rawdemod 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk1rawdemod 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data psk1rawdemod 1 = demod a psk1 tag from GraphBuffer while inverting data"); + PrintAndLog(" : data psk1rawdemod 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + return 0; + } + errCnt = PSKDemod(Cmd, 1); //output if (errCnt<0){ - if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); + if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; - } + } if (errCnt>0){ - if (g_debugMode){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - } + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); }else{ - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - return 1; } - return 0; + PrintAndLog("PSK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; } // by marshmellow @@ -1437,7 +1705,21 @@ int CmdpskNRZrawDemod(const char *Cmd) int CmdPSK2rawDemod(const char *Cmd) { int errCnt=0; - errCnt=PSKnrzDemod(Cmd, 1); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk2rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk2rawdemod = demod a psk2 tag from GraphBuffer, autodetect clock"); + PrintAndLog(" : data psk2rawdemod 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk2rawdemod 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); + PrintAndLog(" : data psk2rawdemod 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); + PrintAndLog(" : data psk2rawdemod 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); + return 0; + } + errCnt=PSKDemod(Cmd, 1); if (errCnt<0){ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; @@ -2095,7 +2377,9 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave - default = 25"}, + {"askem410xdemod",CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in demod buffer (offset = 0|1 bits to shift the decode start)"}, @@ -2123,12 +2407,13 @@ static command_t CommandTable[] = {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, + {"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"nrzrawdemod", CmdNRZrawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, - {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 indala tags and output ID binary & hex (args optional)"}, - {"psk1nrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 or nrz tags and output binary (args optional)"}, - {"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk2 tags and output binary (args optional)"}, + {"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"}, + {"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, diff --git a/client/cmddata.h b/client/cmddata.h index 514be3a2..42954cbe 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -17,6 +17,7 @@ int CmdData(const char *Cmd); void printDemodBuff(); int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); +int CmdAskEM410xDemod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); int Cmdaskmandemod(const char *Cmd); int CmdAutoCorr(const char *Cmd); @@ -26,15 +27,19 @@ int CmdBitstream(const char *Cmd); int CmdBuffClear(const char *Cmd); int CmdDec(const char *Cmd); int CmdDetectClockRate(const char *Cmd); +int CmdDetectNRZClockRate(const char *Cmd); +int CmdDetectPSKClockRate(const char *Cmd); int CmdFSKdemodAWID(const char *Cmd); int CmdFSKdemod(const char *Cmd); int CmdFSKdemodHID(const char *Cmd); int CmdFSKdemodIO(const char *Cmd); int CmdFSKdemodParadox(const char *Cmd); int CmdFSKdemodPyramid(const char *Cmd); +int CmdFSKfcDetect(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); -int CmdDetectNRZpskClockRate(const char *Cmd); -int CmdpskNRZrawDemod(const char *Cmd); +int CmdDetectPskClockRate(const char *Cmd); +int CmdPSK1rawDemod(const char *Cmd); +int CmdPSK2rawDemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd); @@ -46,6 +51,7 @@ int Cmdmandecoderaw(const char *Cmd); int CmdManchesterDemod(const char *Cmd); int CmdManchesterMod(const char *Cmd); int CmdNorm(const char *Cmd); +int CmdNRZrawDemod(const char *Cmd); int CmdPlot(const char *Cmd); int CmdSamples(const char *Cmd); int CmdTuneSamples(const char *Cmd); diff --git a/client/cmdlf.c b/client/cmdlf.c index f56aa1b7..ea1ff131 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -663,13 +663,17 @@ int CmdLFfind(const char *Cmd) { int ans=0; char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1>"); - PrintAndLog(" , if not set, try reading data from tag."); + char testRaw = param_getchar(Cmd, 1); + if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: lf search <0|1> [u]"); + PrintAndLog(" , if not set, try reading data from tag."); + PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); PrintAndLog(""); - PrintAndLog(" sample: lf search"); - PrintAndLog(" : lf search 1"); + PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); + PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); + PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); + return 0; } @@ -680,8 +684,9 @@ int CmdLFfind(const char *Cmd) PrintAndLog("Data in Graphbuffer was too small."); return 0; } - + if (cmdp == 'u' || cmdp == 'U') testRaw = 'u'; PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("False Positives ARE possible\n"); PrintAndLog("\nChecking for known tags:\n"); ans=CmdFSKdemodIO(""); if (ans>0) { @@ -714,12 +719,37 @@ int CmdLFfind(const char *Cmd) PrintAndLog("\nValid Indala ID Found!"); return 1; } - ans=Cmdaskmandemod(""); + ans=CmdAskEM410xDemod(""); if (ans>0) { PrintAndLog("\nValid EM410x ID Found!"); return 1; } - PrintAndLog("No Known Tags Found!\n"); + PrintAndLog("\nNo Known Tags Found!\n"); + if (testRaw=='u' || testRaw=='U'){ + //test unknown tag formats (raw mode) + PrintAndLog("\nChecking for Unknown tags:\n"); + ans=CmdFSKfcDetect(""); + if (ans == 1){ //fsk + ans=CmdFSKrawdemod(""); + if (ans>0) { + PrintAndLog("\nUnknown FSK Modulated Tag Found!"); + return 1; + } + } + ans=Cmdaskmandemod(""); + if (ans>0) { + PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); + return 1; + } + ans=CmdPSK1rawDemod(""); + if (ans>0) { + PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'"); + PrintAndLog("\nCould also be PSK3 - [currently not supported]"); + PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); + return 1; + } + PrintAndLog("\nNo Data Found!\n"); + } return 0; } diff --git a/client/graph.c b/client/graph.c index 95050f55..1bf730b7 100644 --- a/client/graph.c +++ b/client/graph.c @@ -66,8 +66,7 @@ void setGraphBuf(uint8_t *buff, size_t size) } size_t getFromGraphBuf(uint8_t *buff) { - if ( buff == NULL ) return 0; - + if (buff == NULL ) return 0; uint32_t i; for (i=0;i127) GraphBuffer[i]=127; //trim @@ -95,7 +94,7 @@ int GetClock(const char *str, int peak, int verbose) PrintAndLog("Failed to copy from graphbuffer"); return -1; } - clock = DetectASKClock(grph,size,0); + DetectASKClock(grph,size,&clock,20); // Only print this message if we're not looping something if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); @@ -136,7 +135,32 @@ void DetectHighLowInGraph(int *high, int *low, bool addFuzz) { } } -int GetNRZpskClock(const char *str, int peak, int verbose) +int GetPskClock(const char *str, int peak, int verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + // Auto-detect clock + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if ( size == 0 ) { + PrintAndLog("Failed to copy from graphbuffer"); + return -1; + } + clock = DetectPSKClock(grph,size,0); + // Only print this message if we're not looping something + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + } + } + return clock; +} + +int GetNrzClock(const char *str, int peak, int verbose) { int clock; sscanf(str, "%i", &clock); @@ -152,7 +176,7 @@ int GetNRZpskClock(const char *str, int peak, int verbose) PrintAndLog("Failed to copy from graphbuffer"); return -1; } - clock = DetectpskNRZClock(grph,size,0); + clock = DetectNRZClock(grph,size,0); // Only print this message if we're not looping something if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); diff --git a/client/graph.h b/client/graph.h index 9817d776..279b5f7b 100644 --- a/client/graph.h +++ b/client/graph.h @@ -17,7 +17,8 @@ int ClearGraph(int redraw); //int DetectClock(int peak); size_t getFromGraphBuf(uint8_t *buff); int GetClock(const char *str, int peak, int verbose); -int GetNRZpskClock(const char *str, int peak, int verbose); +int GetPskClock(const char *str, int peak, int verbose); +int GetNrzClock(const char *str, int peak, int verbose); void setGraphBuf(uint8_t *buff, size_t size); bool HasGraphData(); diff --git a/common/lfdemod.c b/common/lfdemod.c index 88a250d8..448195f2 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -120,18 +120,19 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx) } //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 3 arguments - clock, invert, maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr) { int i; - int clk2=*clk; - *clk=DetectASKClock(BinStream, *size, *clk); //clock default - + //int clk2=*clk; + int start = DetectASKClock(BinStream, *size, clk, 20); //clock default + if (*clk==0) return -3; + if (start < 0) return -3; // if autodetected too low then adjust //MAY NEED ADJUSTMENT - if (clk2==0 && *clk<8) *clk =64; - if (clk2==0 && *clk<32) *clk=32; + //if (clk2==0 && *clk<8) *clk =64; + //if (clk2==0 && *clk<32) *clk=32; if (*invert != 0 && *invert != 1) *invert=0; uint32_t initLoopMax = 200; if (initLoopMax > *size) initLoopMax=*size; @@ -145,14 +146,14 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) 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 + 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 = *size; if (gLen > 3000) gLen=3000; uint8_t errCnt =0; + uint16_t MaxBits = 500; uint32_t bestStart = *size; - uint32_t bestErrCnt = (*size/1000); - uint32_t maxErr = (*size/1000); + int bestErrCnt = maxErr+1; // PrintAndLog("DEBUG - lastbit - %d",lastBit); // loop to find first wave that works for (iii=0; iii < gLen; ++iii){ @@ -179,10 +180,10 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) 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-iii) >(MaxBits * *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<=maxErr)) { //possible good read if (errCnt==0){ bestStart=iii; @@ -196,7 +197,7 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) } } } - if (bestErrCnt=400) break; + if (bitnum >=MaxBits) break; } *size=bitnum; } else{ @@ -258,12 +259,14 @@ int ManchesterEncode(uint8_t *BitStream, size_t size) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, size_t *size) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; + uint16_t bitnum=0; + uint16_t MaxBits = 500; + uint16_t errCnt = 0; + size_t i=1; + uint16_t bestErr = 1000; + uint16_t bestRun = 0; + size_t ii=1; + if (size == 0) return -1; for (ii=1;ii<3;++ii){ i=1; for (i=i+ii;i<*size-2;i+=2){ @@ -272,7 +275,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) } else { errCnt++; } - if(bitnum>300) break; + if(bitnum>MaxBits) break; } if (bestErr>errCnt){ bestErr=errCnt; @@ -284,7 +287,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) if (errCnt<20){ ii=bestRun; i=1; - for (i=i+ii;i < *size-2;i+=2){ + for (i=i+ii; i < *size-2; i+=2){ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){ BitStream[bitnum++]=0; } else if((BitStream[i] == 0) && BitStream[i+1] == 1){ @@ -293,7 +296,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) BitStream[bitnum++]=77; //errCnt++; } - if(bitnum>300) break; + if(bitnum>MaxBits) break; } *size=bitnum; } @@ -304,10 +307,12 @@ int manrawdecode(uint8_t * BitStream, size_t *size) //take 01 or 10 = 0 and 11 or 00 = 1 int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) { - uint8_t bitnum=0; + uint16_t bitnum=0; uint32_t errCnt =0; uint32_t i; + uint16_t MaxBits=500; i=offset; + if (size == 0) return -1; for (;i<*size-2; i+=2){ if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ BitStream[bitnum++]=1^invert; @@ -317,56 +322,76 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) BitStream[bitnum++]=77; errCnt++; } - if(bitnum>250) break; + if(bitnum>MaxBits) break; } *size=bitnum; return errCnt; } //by marshmellow -//takes 2 arguments - clock and invert both as integers +void askAmp(uint8_t *BitStream, size_t size) +{ + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=30) //large jump up + shift=127; + else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down + shift=-127; + + shiftedVal=BitStream[i]+shift; + + if (shiftedVal>255) + shiftedVal=255; + else if (shiftedVal<0) + shiftedVal=0; + BitStream[i-1] = shiftedVal; + } + return; +} + +//by marshmellow +//takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp) { uint32_t i; - // int invert=0; //invert default - int clk2 = *clk; - *clk=DetectASKClock(BinStream, *size, *clk); //clock default - //uint8_t BitStream[502] = {0}; - - //HACK: if clock not detected correctly - default - if (clk2==0 && *clk<8) *clk =64; - if (clk2==0 && *clk<32 && clk2==0) *clk=32; + if (*size==0) return -1; + int start = DetectASKClock(BinStream, *size, clk, 20); //clock default + if (*clk==0) return -1; + if (start<0) return -1; if (*invert != 0 && *invert != 1) *invert =0; uint32_t initLoopMax = 200; if (initLoopMax > *size) initLoopMax=*size; // Detect high and lows //25% fuzz in case highs and lows aren't clipped [marshmellow] int high, low, ans; + if (amp==1) askAmp(BinStream, *size); ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75); - if (ans<1) return -2; //just noise + if (ans<1) return -1; //just noise //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); 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 + if (*clk == 32) tol=0; //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; uint32_t gLen = *size; if (gLen > 500) gLen=500; uint8_t errCnt =0; uint32_t bestStart = *size; - uint32_t bestErrCnt = (*size/1000); - uint32_t maxErr = bestErrCnt; + uint32_t bestErrCnt = maxErr; //(*size/1000); uint8_t midBit=0; + uint16_t MaxBits=1000; //PrintAndLog("DEBUG - lastbit - %d",lastBit); //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ + for (iii=start; iii < gLen; ++iii){ if ((BinStream[iii]>=high) || (BinStream[iii]<=low)){ lastBit=iii-*clk; + errCnt=0; //loop through to see if this start location works for (i = iii; i < *size; ++i) { if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ @@ -395,16 +420,16 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) errCnt++; lastBit+=*clk;//skip over until hit too many errors - if (errCnt > ((*size/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; + if (errCnt > maxErr){ + //errCnt=0; break; } } } - if ((i-iii)>(500 * *clk)) break; //got enough bits + if ((i-iii)>(MaxBits * *clk)) break; //got enough bits } //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<(*size/1000))) { + if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) { //possible good read if (errCnt==0){ bestStart=iii; @@ -418,9 +443,9 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) } } } - if (bestErrCnt (*clk-tol))){ //low found and we are expecting a bar lastBit+=*clk; - BinStream[bitnum] = 1-*invert; + BinStream[bitnum] = 1 - *invert; bitnum++; midBit=0; } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ @@ -462,11 +487,10 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) BinStream[bitnum]=77; bitnum++; } - lastBit+=*clk;//skip over error } } - if (bitnum >=400) break; + if (bitnum >= MaxBits) break; } *size=bitnum; } else{ @@ -744,32 +768,71 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) return (int)startIdx; } + +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) +{ + uint8_t allPeaks=1; + uint16_t cntPeaks=0; + for (size_t i=20; i<255; i++){ + if (dest[i]>low && dest[i]190) return 1; + } + return allPeaks; +} + // by marshmellow // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) // maybe somehow adjust peak trimming value based on samples to fix? -int DetectASKClock(uint8_t dest[], size_t size, int clock) +// return start index of best starting position for that clock and return clock (by reference) +int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) { int i=0; int clk[]={8,16,32,40,50,64,100,128,256}; int loopCnt = 256; //don't need to loop through entire array... + if (size == 0) return -1; if (size> 8; + uint8_t fc2 = fcTest & 0xFF; + + for (i=0; i<8; i++){ + if (clk[i] == fc1) { + *clock=fc1; + return 0; + } + if (clk[i] == fc2) { + *clock=fc2; + return 0; + } + } + } + int ii; int clkCnt; int tol = 0; int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; + int bestStart[]={0,0,0,0,0,0,0,0,0}; int errCnt=0; //test each valid clock from smallest to greatest to see which lines up - for(clkCnt=0; clkCnt < 8; ++clkCnt){ + for(clkCnt=0; clkCnt < 8; clkCnt++){ if (clk[clkCnt] == 32){ tol=1; }else{ @@ -777,7 +840,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) } bestErr[clkCnt]=1000; //try lining up the peaks by moving starting point (try first 256) - for (ii=0; ii < loopCnt; ++ii){ + for (ii=0; ii < loopCnt; ii++){ if ((dest[ii] >= peak) || (dest[ii] <= low)){ errCnt=0; // now that we have the first one lined up test rest of wave array @@ -792,9 +855,15 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) //if we found no errors then we can stop here // this is correct one - return this clock //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); - if(errCnt==0 && clkCnt<6) return clk[clkCnt]; + if(errCnt==0 && clkCnt<6) { + *clock = clk[clkCnt]; + return ii; + } //if we found errors see if it is lowest so far and save it as best run - if(errCntmaxErr) return -1; + *clock=clk[best]; + return bestStart[best]; } //by marshmellow -//detect psk clock by reading #peaks vs no peaks(or errors) -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock) +//detect psk clock by reading each phase shift +// a phase shift is determined by measuring the sample length of each wave +int DetectPSKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 2048; //don't need to loop through entire array... - if (size= peak) || (dest[ii] <= low)){ - errCnt=0; - peakcnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - peakcnt++; - }else{ //error no peak detected - errCnt++; - } - } - if(peakcnt>peaksdet[clkCnt]) { - peaksdet[clkCnt]=peakcnt; - bestErr[clkCnt]=errCnt; - } - } - } - } - int iii=0; - int best=0; - //int ratio2; //debug - int ratio; - //int bits; - for (iii=0; iii < 7; ++iii){ - ratio=1000; - //ratio2=1000; //debug - //bits=size/clk[iii]; //debug - if (peaksdet[iii] > 0){ - ratio=bestErr[iii]/peaksdet[iii]; - if (((bestErr[best]/peaksdet[best]) > (ratio)+1)){ - best = iii; - } - //ratio2=bits/peaksdet[iii]; //debug - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); - } - return clk[best]; + size_t waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0; + uint8_t clkCnt, fc=0, fullWaveLen=0, tol=1; + uint16_t peakcnt=0, errCnt=0, waveLenCnt=0; + uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; + uint16_t peaksdet[]={0,0,0,0,0,0,0,0,0}; + countFC(dest, size, &fc); + //PrintAndLog("DEBUG: FC: %d",fc); + + //find first full wave + for (i=0; i= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + //PrintAndLog("DEBUG: waveStart: %d",waveStart); + } else { + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + break; + } + waveStart=0; + } + } + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + + //test each valid clock from greatest to smallest to see which lines up + for(clkCnt=7; clkCnt >= 1 ; clkCnt--){ + lastClkBit = firstFullWave; //set end of wave as clock align + waveStart = 0; + errCnt=0; + peakcnt=0; + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d",clk[clkCnt],lastClkBit); + + for (i = firstFullWave+fullWaveLen-1; i < loopCnt-2; i++){ + //top edge of wave = start of new wave + if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt=0; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + //if this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, ii: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,ii+1,fc); + if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit + peakcnt++; + lastClkBit+=clk[clkCnt]; + } else if (i lastClkBit + clk[clkCnt] + tol + fc){ + lastClkBit+=clk[clkCnt]; //no phase shift but clock bit + } + waveStart=i+1; + } + } + } + if (errCnt == 0){ + return clk[clkCnt]; + } + if (errCnt <= bestErr[clkCnt]) bestErr[clkCnt]=errCnt; + if (peakcnt > peaksdet[clkCnt]) peaksdet[clkCnt]=peakcnt; + } + //all tested with errors + //return the highest clk with the most peaks found + uint8_t best=7; + for (i=7; i>=1; i--){ + if (peaksdet[i] > peaksdet[best]) { + best = i; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } -// by marshmellow (attempt to get rid of high immediately after a low) -void pskCleanWave(uint8_t *BitStream, size_t size) +//by marshmellow +//detect nrz clock by reading #peaks vs no peaks(or errors) +int DetectNRZClock(uint8_t dest[], size_t size, int clock) { - int i; - int gap = 4; - int newLow=0; - int newHigh=0; - int high, low; - getHiLo(BitStream, size, &high, &low, 80, 90); - - for (i=0; i < size; ++i){ - if (newLow == 1){ - if (BitStream[i]>low){ - BitStream[i]=low+8; - gap--; - } - if (gap == 0){ - newLow=0; - gap=4; - } - }else if (newHigh == 1){ - if (BitStream[i]= high) newHigh=1; - } - return; + int i=0; + int clk[]={8,16,32,40,50,64,100,128,256}; + int loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return 0; + if (size= peak || dest[i] <= low){ + peakcnt++; + } else { + if (peakcnt>0 && maxPeak < peakcnt){ + maxPeak = peakcnt; + } + peakcnt=0; + } + } + peakcnt=0; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt < 8; ++clkCnt){ + //ignore clocks smaller than largest peak + if (clk[clkCnt]= peak) || (dest[ii] <= low)){ + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + } + } + } + } + int iii=7; + int best=0; + for (iii=7; iii > 0; iii--){ + if (peaksdet[iii] > peaksdet[best]){ + best = iii; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } // by marshmellow @@ -1007,137 +1131,166 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) return 1; } -// by marshmellow - demodulate PSK1 wave or NRZ wave (both similar enough) +// by marshmellow - demodulate NRZ wave (both similar enough) // peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak -int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) +// there probably is a much simpler way to do this.... +int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr) { - if (justNoise(dest, *size)) return -1; - pskCleanWave(dest,*size); - int clk2 = DetectpskNRZClock(dest, *size, *clk); - *clk=clk2; - uint32_t i; - int high, low, ans; - ans = getHiLo(dest, 1260, &high, &low, 75, 80); //25% fuzz on high 20% fuzz on low - if (ans<1) return -2; //just noise - uint32_t gLen = *size; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - uint8_t tol = 1; //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 = 2; //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; - uint8_t errCnt =0; - uint32_t bestStart = *size; - uint32_t maxErr = (*size/1000); - uint32_t bestErrCnt = maxErr; - uint8_t curBit=0; - uint8_t bitHigh=0; - uint8_t ignorewin=*clk/8; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - align to clock - for (iii=0; iii < gLen; ++iii){ - if ((dest[iii]>=high) || (dest[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i] < high && dest[i] > low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i >= lastBit+*clk+tol){ //clock val - lastBit+=*clk; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt++; - } - if (bitnum>=1000) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt < (maxErr))) { - //possible good read - if (errCnt == 0){ - bestStart = iii; - bestErrCnt = errCnt; - break; //great read - finish - } - if (errCnt < bestErrCnt){ //set this as new best run - bestErrCnt = errCnt; - bestStart = iii; - } - } - } - } - if (bestErrCnt < maxErr){ - //best run is good enough set to best run and set overwrite BinStream - iii=bestStart; - lastBit=bestStart-*clk; - bitnum=0; - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=1-*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - lastBit+=*clk; - dest[bitnum]=curBit; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ - //error bar found no clock... - bitHigh=1; - dest[bitnum]=77; - bitnum++; - errCnt++; - } - if (bitnum >=1000) break; - } - *size=bitnum; - } else{ - *size=bitnum; - *clk=bestStart; - return -1; - } + if (justNoise(dest, *size)) return -1; + *clk = DetectNRZClock(dest, *size, *clk); + if (*clk==0) return -2; + uint32_t i; + int high, low, ans; + ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low + if (ans<1) return -2; //just noise + uint32_t gLen = 256; + if (gLen>*size) gLen = *size; + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + uint8_t tol = 1; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + uint32_t iii = 0; + uint16_t errCnt =0; + uint16_t MaxBits = 1000; + uint32_t bestErrCnt = maxErr+1; + uint32_t bestPeakCnt = 0; + uint32_t bestPeakStart=0; + uint8_t curBit=0; + uint8_t bitHigh=0; + uint8_t errBitHigh=0; + uint16_t peakCnt=0; + uint8_t ignoreWindow=4; + uint8_t ignoreCnt=ignoreWindow; //in case of noice near peak + //loop to find first wave that works - align to clock + for (iii=0; iii < gLen; ++iii){ + if ((dest[iii]>=high) || (dest[iii]<=low)){ + lastBit=iii-*clk; + peakCnt=0; + errCnt=0; + bitnum=0; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + bitnum++; + peakCnt++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + bitnum++; + peakCnt++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if no bars found + }else if(dest[i] < high && dest[i] > low) { + if (ignoreCnt==0){ + bitHigh=0; + if (errBitHigh==1){ + errCnt++; + } + errBitHigh=0; + } else { + ignoreCnt--; + } + //if we are past a clock point + if (i >= lastBit+*clk+tol){ //clock val + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errBitHigh=1; + } + if (bitnum>=MaxBits) break; + } + //we got more than 64 good bits and not all errors + if (bitnum > (64) && (errCnt <= (maxErr))) { + //possible good read + if (errCnt == 0){ + //bestStart = iii; + bestErrCnt = errCnt; + bestPeakCnt = peakCnt; + bestPeakStart = iii; + break; //great read - finish + } + if (errCnt < bestErrCnt){ //set this as new best run + bestErrCnt = errCnt; + //bestStart = iii; + } + if (peakCnt > bestPeakCnt){ + bestPeakCnt=peakCnt; + bestPeakStart=iii; + } + } + } + } + //PrintAndLog("DEBUG: bestErrCnt: %d, maxErr: %d, bestStart: %d, bestPeakCnt: %d, bestPeakStart: %d",bestErrCnt,maxErr,bestStart,bestPeakCnt,bestPeakStart); + if (bestErrCnt <= maxErr){ + //best run is good enough set to best run and set overwrite BinStream + iii=bestPeakStart; + lastBit=bestPeakStart-*clk; + bitnum=0; + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + bitnum++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + bitnum++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if no bars found + }else if(dest[i]low) { + if (ignoreCnt==0){ + bitHigh=0; + //if peak is done was it an error peak? + if (errBitHigh==1){ + dest[bitnum]=77; + bitnum++; + errCnt++; + } + errBitHigh=0; + } else { + ignoreCnt--; + } + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + errBitHigh=1; + } + if (bitnum >= MaxBits) break; + } + *size=bitnum; + } else{ + *size=bitnum; + return -1; + } - if (bitnum>16){ - *size=bitnum; - } else return -1; - return errCnt; + if (bitnum>16){ + *size=bitnum; + } else return -1; + return errCnt; } //by marshmellow @@ -1153,6 +1306,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc uint16_t rfCounter = 0; uint8_t firstBitFnd = 0; size_t i; + if (size == 0) return 0; uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); rfLensFnd=0; @@ -1249,7 +1403,8 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc //by marshmellow //countFC is to detect the field clock lengths. //counts and returns the 2 most common wave lengths -uint16_t countFC(uint8_t *BitStream, size_t size) +//mainly used for FSK field clock detection +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC) { 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}; @@ -1257,7 +1412,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size) uint8_t lastFCcnt=0; uint32_t fcCounter = 0; size_t i; - + if (size == 0) return 0; + // prime i to first up transition for (i = 1; i < size-1; i++) if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) @@ -1320,7 +1476,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size) fcH=fcLens[best2]; fcL=fcLens[best1]; } - + + *mostFC=fcLens[best1]; // TODO: take top 3 answers and compare to known Field clocks to get top 2 uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; @@ -1328,3 +1485,152 @@ uint16_t countFC(uint8_t *BitStream, size_t size) return fcs; } + +//by marshmellow +//countPSK_FC is to detect the psk carrier clock length. +//counts and returns the 1 most common wave length +uint8_t countPSK_FC(uint8_t *BitStream, size_t size) +{ + 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 fcLensFnd = 0; + uint32_t fcCounter = 0; + size_t i; + if (size == 0) return 0; + + // prime i to first up transition + for (i = 1; i < size-1; i++) + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) + break; + + for (; i < size-1; i++){ + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ + // new up transition + fcCounter++; + + // save last field clock count (fc/xx) + // find which fcLens to save it to: + for (int ii=0; ii<10; ii++){ + if (fcLens[ii]==fcCounter){ + fcCnts[ii]++; + fcCounter=0; + break; + } + } + if (fcCounter>0 && fcLensFnd<10){ + //add new fc length + fcCnts[fcLensFnd]++; + fcLens[fcLensFnd++]=fcCounter; + } + fcCounter=0; + } else { + // count sample + fcCounter++; + } + } + + uint8_t best1=9; + uint16_t maxCnt1=0; + // go through fclens and find which ones are bigest + for (i=0; i<10; i++){ + //PrintAndLog("DEBUG: FC %d, Cnt %d",fcLens[i],fcCnts[i]); + // get the best FC value + if (fcCnts[i]>maxCnt1) { + maxCnt1=fcCnts[i]; + best1=i; + } + } + return fcLens[best1]; +} + +//by marshmellow - demodulate PSK1 wave +//uses wave lengths (# Samples) +int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) +{ + uint16_t loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return -1; + if (*size= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + avgWaveVal=dest[i+1]; + //PrintAndLog("DEBUG: waveStart: %d",waveStart); + } else { + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + lastAvgWaveVal = avgWaveVal/waveLenCnt; + if (waveLenCnt > fc){ + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + //if average wave value is > graph 0 then it is an up wave or a 1 + if (lastAvgWaveVal > 128) curPhase^=1; + break; + } + waveStart=0; + avgWaveVal=0; + } + } + avgWaveVal+=dest[i+1]; + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + lastClkBit = firstFullWave; //set start of wave as clock align + waveStart = 0; + errCnt=0; + size_t numBits=0; + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit); + + for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){ + //top edge of wave = start of new wave + if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt=0; + avgWaveVal = dest[i+1]; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + lastAvgWaveVal = avgWaveVal/waveLenCnt; + if (waveLenCnt > fc){ + //PrintAndLog("DEBUG: avgWaveVal: %d, waveSum: %d",lastAvgWaveVal,avgWaveVal); + //if this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc); + if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit + curPhase^=1; + dest[numBits] = curPhase; + numBits++; + lastClkBit += *clock; + } else if (i lastClkBit + *clock + tol + fc){ + lastClkBit += *clock; //no phase shift but clock bit + dest[numBits] = curPhase; + numBits++; + } + avgWaveVal=0; + waveStart=i+1; + } + } + avgWaveVal+=dest[i+1]; + } + *size = numBits; + return errCnt; +} diff --git a/common/lfdemod.h b/common/lfdemod.h index dbeab0f7..2880ff82 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -15,31 +15,34 @@ #define LFDEMOD_H__ #include -int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr); uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx); int ManchesterEncode(uint8_t *BitStream, size_t size); int manrawdecode(uint8_t *BitStream, size_t *size); int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp); int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); int IOdemodFSK(uint8_t *dest, size_t size); int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow); uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); -int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert); +int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr); void psk1TOpsk2(uint8_t *BitStream, size_t size); -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int DetectNRZClock(uint8_t dest[], size_t size, int clock); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); void pskCleanWave(uint8_t *bitStream, size_t size); int PyramiddemodFSK(uint8_t *dest, size_t *size); int AWIDdemodFSK(uint8_t *dest, size_t *size); size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); -uint16_t countFC(uint8_t *BitStream, size_t size); +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC); uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow); int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); uint8_t justNoise(uint8_t *BitStream, size_t size); +uint8_t countPSK_FC(uint8_t *BitStream, size_t size); +int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert); +int DetectPSKClock(uint8_t dest[], size_t size, int clock); #endif