From e770c6482407fb67c37973cc3e95409cd5c6d952 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 5 Feb 2015 17:01:18 -0500 Subject: [PATCH 1/8] lf psk/nrz split, add maxErr argument changed psk to use wave lengths instead of peaks split out NRZ from psk demod added maxErr argument to raw demods (except fsk) --- armsrc/lfops.c | 4 +- client/cmddata.c | 411 ++++++++++++++++++++++++++++++++++++++--------- client/cmddata.h | 10 +- client/cmdlf.c | 48 ++++-- client/graph.c | 34 +++- client/graph.h | 3 +- 6 files changed, 416 insertions(+), 94 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 7b6fa97a7..67652986a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -724,7 +724,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); @@ -738,7 +738,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 25d752f6a..b03a3ebcd 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -267,24 +267,109 @@ int CmdEm410xDecode(const char *Cmd) //by marshmellow -//takes 2 arguments - clock and invert both as integers +//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) +{ + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || 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: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); + printDemodBuff(); + } + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; + } + return 0; +} + +//by marshmellow +//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) > 3 || 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; } - 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; @@ -313,7 +398,7 @@ int Cmdaskmandemod(const char *Cmd) printEM410x(lo); return 1; } - return 0; + return 1; } //by marshmellow @@ -324,6 +409,16 @@ int Cmdmandecoderaw(const char *Cmd) int i =0; int errCnt=0; size_t size=0; + 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 2 || 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 3 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askrawdemod [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 askrawdemod = demod an ask tag from GraphBuffer"); + 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"); + 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; } 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); 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 @@ -595,10 +720,8 @@ int CmdGraphShiftZero(const char *Cmd) // 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 @@ -613,6 +736,22 @@ int CmdFSKrawdemod(const char *Cmd) int invert=0; int fchigh=0; int fclow=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 4 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data fskrawdemod [clock] <0|1> [rchigh] [rclow]"); + 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 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 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); @@ -625,10 +764,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; @@ -651,6 +792,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"); } @@ -667,8 +809,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){ @@ -752,6 +895,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){ @@ -803,6 +947,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); @@ -879,6 +1024,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); @@ -978,6 +1124,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); @@ -1217,8 +1364,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; @@ -1232,44 +1380,71 @@ 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)){ + if (g_debugMode){ + 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); - - //prime demod buffer for output - setDemodBuf(BitStream,BitLen,0); - return errCnt; + GetNrzClock("",0,0); + return 0; } + +//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) @@ -1277,9 +1452,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){ @@ -1351,6 +1526,7 @@ int CmdIndalaDecode(const char *Cmd) return 1; } +/* //by marshmellow //attempt to clean psk wave noise after a peak //NOTE RELIES ON PEAKS :( @@ -1362,35 +1538,104 @@ int CmdPskClean(const char *Cmd) setGraphBuf(bitStream, bitLen); return 0; } +*/ // by marshmellow -// takes 2 arguments - clock and invert both as integers -// attempts to demodulate psk only +// takes 3 arguments - clock, invert, maxErr as integers +// attempts to demodulate nrz only // prints binary found and saves in demodbuffer for further commands -int CmdpskNRZrawDemod(const char *Cmd) +int CmdNRZrawDemod(const char *Cmd) { - int errCnt; + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || 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; + } - errCnt = PSKnrzDemod(Cmd, 1); - //output - if (errCnt<0){ - if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); + 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){ - 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(); - } - }else{ - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - 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 0; } - 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 CmdPSK1rawDemod(const char *Cmd) +{ + int errCnt; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || 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); + return 0; + } + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + }else{ + } + PrintAndLog("PSK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; } // by marshmellow @@ -1398,7 +1643,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) > 3 || 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; @@ -2002,7 +2261,8 @@ 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)"}, + {"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)"}, @@ -2030,12 +2290,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 514be3a2b..42954cbee 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 07a8750f7..a34275f36 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -559,13 +559,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; } @@ -576,8 +580,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) { @@ -610,12 +615,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 95050f558..009974371 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); + clock = DetectASKClock(grph,size,0,20); // Only print this message if we're not looping something if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); @@ -136,7 +135,7 @@ 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); @@ -152,7 +151,32 @@ int GetNRZpskClock(const char *str, int peak, int verbose) PrintAndLog("Failed to copy from graphbuffer"); return -1; } - clock = DetectpskNRZClock(grph,size,0); + 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); + 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 = 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 fe35d4f1c..56d6178c4 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(); From 6de4350803266394eba84947faa7447ec168c550 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 6 Feb 2015 14:36:25 -0500 Subject: [PATCH 2/8] data askraw patches, data askedgedetect demod, data askraw patches - added amp option (for stubborn waves) NEW data askedgedetect demod for manual demod, adjusted detectclock (ask clock) in case of cleaned (edgedetect) waves finish maxErr args finish psk detect --- client/cmddata.c | 128 ++++--- client/graph.c | 2 +- common/lfdemod.c | 890 +++++++++++++++++++++++++++++++---------------- common/lfdemod.h | 15 +- 4 files changed, 684 insertions(+), 351 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index b03a3ebcd..66ba74555 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -246,26 +246,6 @@ void printEM410x(uint64_t id) return; } -//by marshmellow -//take binary from demod buffer and see if we can find an EM410x ID -int CmdEm410xDecode(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); - if (g_debugMode){ - PrintAndLog("DEBUG: Printing demod buffer:"); - printDemodBuff(); - } - printEM410x(id); - return 1; - } - return 0; -} - - //by marshmellow //takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask while decoding manchester @@ -276,7 +256,7 @@ int CmdAskEM410xDemod(const char *Cmd) int clk=0; int maxErr=100; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + 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"); @@ -345,7 +325,7 @@ int Cmdaskmandemod(const char *Cmd) int clk=0; int maxErr=100; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + 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"); @@ -364,6 +344,10 @@ int Cmdaskmandemod(const char *Cmd) 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); @@ -409,6 +393,7 @@ 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"); @@ -432,7 +417,7 @@ int Cmdmandecoderaw(const char *Cmd) } size=i; errCnt=manrawdecode(BitStream, &size); - if (errCnt>=20){ + if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; } @@ -471,7 +456,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd) int invert=0; int high=0, low=0; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') { + 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)"); @@ -509,7 +494,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd) } //by marshmellow -//takes 3 arguments - clock, invert, maxErr as integers +//takes 4 arguments - clock, invert, maxErr as integers and amplify as char //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) @@ -517,30 +502,40 @@ int Cmdaskrawdemod(const char *Cmd) int invert=0; int clk=0; int maxErr=100; + uint8_t askAmp = 0; + char amp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data askrawdemod [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."); + if (strlen(Cmd) > 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 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(" 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 %i", &clk, &invert, &maxErr); + 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, maxErr); + 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); @@ -716,6 +711,35 @@ 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) @@ -726,8 +750,8 @@ int CmdDetectClockRate(const char *Cmd) //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 @@ -737,15 +761,16 @@ int CmdFSKrawdemod(const char *Cmd) int fchigh=0; int fclow=0; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 4 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data fskrawdemod [clock] <0|1> [rchigh] [rclow]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - - PrintAndLog(" [set maximum allowed errors], default = 100."); + 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"); @@ -1381,10 +1406,8 @@ int CmdFSKfcDetect(const char *Cmd) return 0; } if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ - if (g_debugMode){ - PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); - return 1; - } + 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"); @@ -1550,7 +1573,7 @@ int CmdNRZrawDemod(const char *Cmd) int clk=0; int maxErr=100; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + 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"); @@ -1609,7 +1632,7 @@ int CmdPSK1rawDemod(const char *Cmd) { int errCnt; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + 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"); @@ -1644,7 +1667,7 @@ int CmdPSK2rawDemod(const char *Cmd) { int errCnt=0; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + 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"); @@ -2261,6 +2284,7 @@ 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"}, + {"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)"}, diff --git a/client/graph.c b/client/graph.c index 009974371..1bf730b75 100644 --- a/client/graph.c +++ b/client/graph.c @@ -94,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,20); + DetectASKClock(grph,size,&clock,20); // Only print this message if we're not looping something if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); diff --git a/common/lfdemod.c b/common/lfdemod.c index 88a250d87..448195f2a 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 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) +{ + uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock + uint16_t loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return 0; + if (size= 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 -//detect psk clock by reading #peaks vs no peaks(or errors) -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock) +//detect nrz clock by reading #peaks vs no peaks(or errors) +int DetectNRZClock(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]; -} + //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low); + int ii; + uint8_t clkCnt; + uint8_t tol = 0; + int peakcnt=0; + int peaksdet[]={0,0,0,0,0,0,0,0}; + int maxPeak=0; + //test for large clipped waves + for (i=0; i= 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]low){ - BitStream[i]=low+8; - gap--; - } - if (gap == 0){ - newLow=0; - gap=4; - } - }else if (newHigh == 1){ - if (BitStream[i]= high) newHigh=1; - } - return; + //try lining up the peaks by moving starting point (try first 256) + for (ii=0; ii< loopCnt; ++ii){ + if ((dest[ii] >= 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 dbeab0f7b..2880ff82f 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 From 3b692427ac2585148be70b2dd3363a8ad1a95fe0 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Tue, 3 Feb 2015 07:21:57 +0100 Subject: [PATCH 3/8] Bugfix hw tune, hf tune: voltage measures were VERY wrong Modified hw detectreader: display reader field strength in mV units and to be less phony --- armsrc/appmain.c | 95 ++++++++++++++++++++++++++++-------------------- armsrc/apps.h | 4 ++ 2 files changed, 60 insertions(+), 39 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index cb1b9f73f..189f9d7a3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -135,12 +135,25 @@ static int ReadAdc(int ch) AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(32) | - ADC_MODE_STARTUP_TIME(16) | - ADC_MODE_SAMPLE_HOLD_TIME(8); + ADC_MODE_PRESCALE(63 /* was 32 */) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz + ADC_MODE_STARTUP_TIME(1 /* was 16 */) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us + ADC_MODE_SAMPLE_HOLD_TIME(15 /* was 8 */); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us + + // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. + // Both AMPL_LO and AMPL_HI are very high impedance (10MOhm) outputs, the input capacitance of the ADC is 12pF (typical). This results in a time constant + // of RC = 10MOhm * 12pF = 120us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. + // + // The maths are: + // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be + // + // v_cap = v_in * (1 - exp(-RC/SHTIM)) = v_in * (1 - exp(-3)) = v_in * 0,95 (i.e. an error of 5%) + // + // Note: with the "historic" values in the comments above, the error was 34% !!! + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch); AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) ; d = AT91C_BASE_ADC->ADC_CDR[ch]; @@ -183,9 +196,7 @@ void MeasureAntennaTuning(void) WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); - // Vref = 3.3V, and a 10000:240 voltage divider on the input - // can measure voltages up to 137500 mV - adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10); + adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); if (i==95) vLf125 = adcval; // voltage at 125Khz if (i==89) vLf134 = adcval; // voltage at 134Khz @@ -205,11 +216,9 @@ void MeasureAntennaTuning(void) FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); - // Vref = 3300mV, and an 10:1 voltage divider on the input - // can measure voltages up to 33000 mV - vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),LF_Results,256); + cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_A_OFF(); LED_B_OFF(); @@ -222,19 +231,21 @@ void MeasureAntennaTuningHf(void) DbpString("Measuring HF antenna, press button to exit"); + // Let the FPGA drive the high-frequency antenna around 13.56 MHz. + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + for (;;) { - // Let the FPGA drive the high-frequency antenna around 13.56 MHz. - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); - // Vref = 3300mV, and an 10:1 voltage divider on the input - // can measure voltages up to 33000 mV - vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; Dbprintf("%d mV",vHf); if (BUTTON_PRESS()) break; } DbpString("cancelled"); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + } @@ -512,26 +523,32 @@ static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]); void ListenReaderField(int limit) { - int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max; - int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max; + int lf_av, lf_av_new, lf_baseline= 0, lf_max; + int hf_av, hf_av_new, hf_baseline= 0, hf_max; int mode=1, display_val, display_max, i; -#define LF_ONLY 1 -#define HF_ONLY 2 +#define LF_ONLY 1 +#define HF_ONLY 2 +#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE + + + // switch off FPGA - we don't want to measure our own signal + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - lf_av=lf_max=ReadAdc(ADC_CHAN_LF); + lf_av = lf_max = AvgAdc(ADC_CHAN_LF); if(limit != HF_ONLY) { - Dbprintf("LF 125/134 Baseline: %d", lf_av); + Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); lf_baseline = lf_av; } - hf_av=hf_max=ReadAdc(ADC_CHAN_HF); + hf_av = hf_max = AvgAdc(ADC_CHAN_HF); if (limit != LF_ONLY) { - Dbprintf("HF 13.56 Baseline: %d", hf_av); + Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); hf_baseline = hf_av; } @@ -554,38 +571,38 @@ void ListenReaderField(int limit) WDT_HIT(); if (limit != HF_ONLY) { - if(mode==1) { - if (abs(lf_av - lf_baseline) > 10) LED_D_ON(); - else LED_D_OFF(); + if(mode == 1) { + if (abs(lf_av - lf_baseline) > REPORT_CHANGE) + LED_D_ON(); + else + LED_D_OFF(); } - ++lf_count; - lf_av_new= ReadAdc(ADC_CHAN_LF); + lf_av_new = AvgAdc(ADC_CHAN_LF); // see if there's a significant change - if(abs(lf_av - lf_av_new) > 10) { - Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av, lf_av_new, lf_count); + if(abs(lf_av - lf_av_new) > REPORT_CHANGE) { + Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); lf_av = lf_av_new; if (lf_av > lf_max) lf_max = lf_av; - lf_count= 0; } } if (limit != LF_ONLY) { if (mode == 1){ - if (abs(hf_av - hf_baseline) > 10) LED_B_ON(); - else LED_B_OFF(); + if (abs(hf_av - hf_baseline) > REPORT_CHANGE) + LED_B_ON(); + else + LED_B_OFF(); } - ++hf_count; - hf_av_new= ReadAdc(ADC_CHAN_HF); + hf_av_new = AvgAdc(ADC_CHAN_HF); // see if there's a significant change - if(abs(hf_av - hf_av_new) > 10) { - Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av, hf_av_new, hf_count); + if(abs(hf_av - hf_av_new) > REPORT_CHANGE) { + Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); hf_av = hf_av_new; if (hf_av > hf_max) hf_max = hf_av; - hf_count= 0; } } diff --git a/armsrc/apps.h b/armsrc/apps.h index 58a2a6219..a15d8b817 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -38,6 +38,10 @@ void DbpString(char *str); void Dbprintf(const char *fmt, ...); void Dbhexdump(int len, uint8_t *d, bool bAsci); +// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV +#define MAX_ADC_HF_VOLTAGE 36300 +// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV +#define MAX_ADC_LF_VOLTAGE 140800 int AvgAdc(int ch); void ToSendStuffBit(int b); From b4fb11ba92dd67c249e1f99f4470a10c6db5e00b Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 8 Feb 2015 00:48:00 -0500 Subject: [PATCH 4/8] fix inconsistent spacing within functions did not convert spaces to tabs but made the functions consistent with what it used so it can be auto converted. (sorry for the annoying space/tab usage in the past.) we can convert all to tabs later. --- client/cmddata.c | 338 +++++++++++++++++++++++------------------------ client/cmdlf.c | 36 ++--- client/graph.c | 26 ++-- 3 files changed, 199 insertions(+), 201 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index a1159ec80..e54631751 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -60,7 +60,7 @@ void printDemodBuff() if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty // ensure equally divided by 16 - bitLen &= 0xfff0; + bitLen &= 0xfff0; for (i = 0; i <= (bitLen-16); i+=16) { PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", @@ -188,36 +188,36 @@ int Cmdaskdemod(const char *Cmd) //by marshmellow void printBitStream(uint8_t BitStream[], uint32_t bitLen) { - uint32_t i = 0; - if (bitLen<16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen>512) bitLen=512; - - // ensure equally divided by 16 - bitLen &= 0xfff0; + uint32_t i = 0; + if (bitLen<16) { + PrintAndLog("Too few bits found: %d",bitLen); + return; + } + if (bitLen>512) bitLen=512; + + // ensure equally divided by 16 + bitLen &= 0xfff0; - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } return; } //by marshmellow @@ -225,27 +225,27 @@ void printBitStream(uint8_t BitStream[], uint32_t bitLen) void printEM410x(uint64_t id) { if (id !=0){ - uint64_t iii=1; - uint64_t id2lo=0; - uint32_t ii=0; - uint32_t i=0; - for (ii=5; ii>0;ii--){ - for (i=0;i<8;i++){ - id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); - } + uint64_t iii=1; + uint64_t id2lo=0; + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); - PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); - PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); - PrintAndLog("DEZ 14/IK2 : %014lld",id); - PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); - PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); - } - return; + } + //output em id + PrintAndLog("EM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID: %010llx", id2lo); + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); + PrintAndLog("DEZ 14/IK2 : %014lld",id); + PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); + PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); + } + return; } //by marshmellow @@ -324,7 +324,7 @@ int CmdAskEM410xDemod(const char *Cmd) int Cmdaskmandemod(const char *Cmd) { int invert=0; - int clk=0; + int clk=0; int maxErr=100; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { @@ -342,7 +342,7 @@ int Cmdaskmandemod(const char *Cmd) return 0; } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; @@ -351,15 +351,15 @@ int Cmdaskmandemod(const char *Cmd) invert=1; clk=0; } - size_t BitLen = getFromGraphBuf(BitStream); + 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); + 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 @@ -368,8 +368,8 @@ int Cmdaskmandemod(const char *Cmd) } PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits - setDemodBuf(BitStream,BitLen,0); - printDemodBuff(); + setDemodBuf(BitStream,BitLen,0); + printDemodBuff(); uint64_t lo =0; size_t idx=0; lo = Em410xDecode(BitStream, &BitLen, &idx); @@ -394,7 +394,7 @@ int Cmdmandecoderaw(const char *Cmd) { int i =0; int errCnt=0; - size_t size=0; + size_t size=0; size_t maxErr = 20; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { @@ -408,28 +408,28 @@ int Cmdmandecoderaw(const char *Cmd) if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; - for (;ihigh) high=DemodBuffer[i]; - else if(DemodBuffer[i]high) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); return 0; } - size=i; - errCnt=manrawdecode(BitStream, &size); + size=i; + errCnt=manrawdecode(BitStream, &size); if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; } PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream, size); + printBitStream(BitStream, size); if (errCnt==0){ - uint64_t id = 0; + uint64_t id = 0; size_t idx=0; - id = Em410xDecode(BitStream, &size, &idx); - if (id>0){ + id = Em410xDecode(BitStream, &size, &idx); + if (id>0){ //need to adjust to set bitstream back to manchester encoded data //setDemodBuf(BitStream, size, idx); @@ -451,48 +451,48 @@ int Cmdmandecoderaw(const char *Cmd) // width waves vs small width waves to help the decode positioning) or askbiphdemod int CmdBiphaseDecodeRaw(const char *Cmd) { - int i = 0; - int errCnt=0; + int i = 0; + int errCnt=0; size_t size=0; - 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; - } + 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 + if (DemodBufferLen==0) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + //get graphbuffer & high and low for (;ihigh)high=DemodBuffer[i]; else if(DemodBuffer[i]1 || low <0){ - PrintAndLog("Error: please raw demod the wave first then decode"); - return 0; - } + } + if (high>1 || low <0){ + PrintAndLog("Error: please raw demod the wave first then decode"); + return 0; + } size=i; errCnt=BiphaseRawDecode(BitStream, &size, offset, invert); - if (errCnt>=20){ - PrintAndLog("Too many errors attempting to decode: %d",errCnt); - return 0; - } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + if (errCnt>=20){ + PrintAndLog("Too many errors attempting to decode: %d",errCnt); + return 0; + } + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); printBitStream(BitStream, size); - PrintAndLog("\nif bitstream does not look right try offset=1"); - return 1; + PrintAndLog("\nif bitstream does not look right try offset=1"); + return 1; } //by marshmellow @@ -501,8 +501,8 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert=0; - int clk=0; + int invert=0; + int clk=0; int maxErr=100; uint8_t askAmp = 0; char amp = param_getchar(Cmd, 0); @@ -524,7 +524,7 @@ int Cmdaskrawdemod(const char *Cmd) return 0; } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); + sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; @@ -534,21 +534,21 @@ int Cmdaskrawdemod(const char *Cmd) clk=0; } if (amp == 'a' || amp == 'A') askAmp=1; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; int errCnt=0; - 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"); + 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); //move BitStream back to DemodBuffer - setDemodBuf(BitStream,BitLen,0); + setDemodBuf(BitStream,BitLen,0); - //output + //output if (errCnt>0){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); } @@ -817,17 +817,17 @@ int CmdFSKrawdemod(const char *Cmd) return 0; } //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); + sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (rfLen==1){ invert=1; //if invert option only is used rfLen = 0; } - } + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; //get field clock lengths uint16_t fcs=0; @@ -848,10 +848,10 @@ int CmdFSKrawdemod(const char *Cmd) if (rfLen == 0) rfLen = 50; } PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); + int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ PrintAndLog("FSK decoded bitstream:"); - setDemodBuf(BitStream,size,0); + setDemodBuf(BitStream,size,0); // 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 @@ -872,14 +872,14 @@ int CmdFSKdemodHID(const char *Cmd) uint32_t hi2=0, hi=0, lo=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); - if (BitLen==0) return 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){ - PrintAndLog("DEBUG: Just Noise Detected"); + PrintAndLog("DEBUG: Just Noise Detected"); } else if (idx == -2) { PrintAndLog("DEBUG: Error demoding fsk"); } else if (idx == -3) { @@ -897,7 +897,7 @@ int CmdFSKdemodHID(const char *Cmd) return 0; } if (hi2 != 0){ //extra large HID tags - PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", + PrintAndLog("HID Prox 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 @@ -912,7 +912,7 @@ int CmdFSKdemodHID(const char *Cmd) lo2=lo2>>1; idx3++; } - fmtLen =idx3+19; + fmtLen =idx3+19; fc =0; cardnum=0; if(fmtLen==26){ @@ -936,8 +936,8 @@ int CmdFSKdemodHID(const char *Cmd) cardnum = (lo>>1)&0x7FFFF; fc = ((hi&0xF)<<12)|(lo>>20); } - } - PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + } + PrintAndLog("HID Prox 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) fmtLen, (unsigned int) fc, (unsigned int) cardnum); } @@ -1003,18 +1003,18 @@ int CmdFSKdemodIO(const char *Cmd) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave //set defaults - int idx=0; + int idx=0; //something in graphbuffer? if (GraphTraceLen < 65) { if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer"); return 0; } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; //get binary from fsk wave - idx = IOdemodFSK(BitStream,BitLen); + idx = IOdemodFSK(BitStream,BitLen); if (idx<0){ if (g_debugMode){ if (idx==-1){ @@ -1054,7 +1054,7 @@ int CmdFSKdemodIO(const char *Cmd) return 0; } PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); - PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); @@ -1062,17 +1062,17 @@ int CmdFSKdemodIO(const char *Cmd) PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); uint32_t code = bytebits_to_byte(BitStream+idx,32); - uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); + uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); setDemodBuf(BitStream,64,idx); - if (g_debugMode){ + if (g_debugMode){ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64); printDemodBuff(); } - return 1; + return 1; } @@ -1100,8 +1100,6 @@ int CmdFSKdemodAWID(const char *Cmd) PrintAndLog("DEBUG: Error - only noise found"); else if (idx == -3) PrintAndLog("DEBUG: Error - problem during FSK demod"); - // else if (idx == -3) - // PrintAndLog("Error: thought we had a tag but the parity failed"); else if (idx == -4) PrintAndLog("DEBUG: Error - AWID preamble not found"); else if (idx == -5) @@ -1512,29 +1510,29 @@ int PSKDemod(const char *Cmd, uint8_t verbose) // optional arguments - same as CmdpskNRZrawDemod (clock & invert) int CmdIndalaDecode(const char *Cmd) { - int ans; - if (strlen(Cmd)>0){ - ans = PSKDemod(Cmd, 0); - } else{ //default to RF/32 - ans = PSKDemod("32", 0); - } + int ans; + if (strlen(Cmd)>0){ + ans = PSKDemod(Cmd, 0); + } else{ //default to RF/32 + ans = PSKDemod("32", 0); + } if (ans < 0){ if (g_debugMode==1) - PrintAndLog("Error1: %d",ans); + PrintAndLog("Error1: %d",ans); return 0; } uint8_t invert=0; ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert); if (ans < 1) { if (g_debugMode==1) - PrintAndLog("Error2: %d",ans); + PrintAndLog("Error2: %d",ans); return -1; } char showbits[251]={0x00}; if (invert) - if (g_debugMode==1) - PrintAndLog("Had to invert bits"); + if (g_debugMode==1) + PrintAndLog("Had to invert bits"); //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; @@ -1581,10 +1579,10 @@ int CmdIndalaDecode(const char *Cmd) showbits[idx]='\0'; PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); } - if (g_debugMode){ - PrintAndLog("DEBUG: printing demodbuffer:"); - printDemodBuff(); - } + if (g_debugMode){ + PrintAndLog("DEBUG: printing demodbuffer:"); + printDemodBuff(); + } return 1; } @@ -1685,14 +1683,14 @@ int CmdPSK1rawDemod(const char *Cmd) return 0; } errCnt = PSKDemod(Cmd, 1); - //output - if (errCnt<0){ + //output + if (errCnt<0){ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; } - if (errCnt>0){ + if (errCnt>0){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - }else{ + }else{ } PrintAndLog("PSK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@ -1787,8 +1785,8 @@ int CmdHexsamples(const char *Cmd) *(string_ptr - 1) = '\0'; PrintAndLog("%s", string_buf); string_buf[0] = '\0'; + } } - } return 0; } @@ -1932,12 +1930,12 @@ int CmdTuneSamples(const char *Cmd) GraphBuffer[i] = resp.d.asBytes[i] - 128; } - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); + PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); GraphTraceLen = 256; ShowGraphWindow(); - return 0; + return 0; } @@ -2310,8 +2308,8 @@ int CmdThreshold(const char *Cmd) int CmdDirectionalThreshold(const char *Cmd) { - int8_t upThres = param_get8(Cmd, 0); - int8_t downThres = param_get8(Cmd, 1); + int8_t upThres = param_get8(Cmd, 0); + int8_t downThres = param_get8(Cmd, 1); printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); @@ -2379,15 +2377,15 @@ static command_t CommandTable[] = {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, {"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)"}, + {"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)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate graph window as an AWID FSK tag using raw"}, {"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, @@ -2397,7 +2395,7 @@ static command_t CommandTable[] = {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate graph window as a Paradox FSK tag using raw"}, {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"}, @@ -2406,13 +2404,13 @@ static command_t CommandTable[] = {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, {"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"}, + {"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)"}, - {"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)"}, - {"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"}, + {"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)"}, + {"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)"}, @@ -2420,10 +2418,10 @@ static command_t CommandTable[] = {"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"}, {"shiftgraphzero",CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, - {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlf.c b/client/cmdlf.c index ea1ff1314..27e764a2a 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -662,27 +662,27 @@ int CmdVchDemod(const char *Cmd) int CmdLFfind(const char *Cmd) { int ans=0; - char cmdp = param_getchar(Cmd, 0); - 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."); + char cmdp = param_getchar(Cmd, 0); + 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 = try reading data from tag & search for known tags"); - PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(""); + 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; - } + return 0; + } - if (!offline && (cmdp != '1')){ + if (!offline && (cmdp != '1')){ ans=CmdLFRead(""); ans=CmdSamples("20000"); - } else if (GraphTraceLen < 1000) { - PrintAndLog("Data in Graphbuffer was too small."); - return 0; + } else if (GraphTraceLen < 1000) { + 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"); @@ -734,20 +734,20 @@ int CmdLFfind(const char *Cmd) 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; @@ -765,7 +765,7 @@ static command_t CommandTable[] = {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, {"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, - {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, diff --git a/client/graph.c b/client/graph.c index 1bf730b75..f508fe883 100644 --- a/client/graph.c +++ b/client/graph.c @@ -56,24 +56,24 @@ void setGraphBuf(uint8_t *buff, size_t size) uint16_t i = 0; if ( size > MAX_GRAPH_TRACE_LEN ) size = MAX_GRAPH_TRACE_LEN; - ClearGraph(0); - for (; i < size; ++i){ + ClearGraph(0); + for (; i < size; ++i){ GraphBuffer[i]=buff[i]-128; - } - GraphTraceLen=size; - RepaintGraphWindow(); - return; + } + GraphTraceLen=size; + RepaintGraphWindow(); + return; } size_t getFromGraphBuf(uint8_t *buff) { if (buff == NULL ) return 0; - uint32_t i; - for (i=0;i127) GraphBuffer[i]=127; //trim - if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim - buff[i]=(uint8_t)(GraphBuffer[i]+128); - } - return i; + uint32_t i; + for (i=0;i127) GraphBuffer[i]=127; //trim + if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim + buff[i]=(uint8_t)(GraphBuffer[i]+128); + } + return i; } From 0c8d25ebd826f709b8e6cc2c8c1f185c633e326c Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Sun, 8 Feb 2015 22:14:20 +0100 Subject: [PATCH 5/8] Fixed: hf mf sim failed on fast reader responses In Miller Decoder: don't wait too long for a stable signal In Miller Decoder: Don't accept sequences of four or more zeroes as start bit In EmSendCmd14443aRaw: don't wait for emptying the FPGA delay queue if it isn't filled --- armsrc/iso14443a.c | 62 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b73495a3c..103f25e69 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -310,26 +310,27 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.twoBits = (Uart.twoBits << 8) | bit; - if (Uart.state == STATE_UNSYNCD) { // not yet synced + if (Uart.state == STATE_UNSYNCD) { // not yet synced - if (Uart.highCnt < 7) { // wait for a stable unmodulated signal + if (Uart.highCnt < 2) { // wait for a stable unmodulated signal if (Uart.twoBits == 0xffff) { Uart.highCnt++; } else { Uart.highCnt = 0; } } else { - Uart.syncBit = 0xFFFF; // not set - // look for 00xx1111 (the start bit) - if ((Uart.twoBits & 0x6780) == 0x0780) Uart.syncBit = 7; - else if ((Uart.twoBits & 0x33C0) == 0x03C0) Uart.syncBit = 6; - else if ((Uart.twoBits & 0x19E0) == 0x01E0) Uart.syncBit = 5; - else if ((Uart.twoBits & 0x0CF0) == 0x00F0) Uart.syncBit = 4; - else if ((Uart.twoBits & 0x0678) == 0x0078) Uart.syncBit = 3; - else if ((Uart.twoBits & 0x033C) == 0x003C) Uart.syncBit = 2; - else if ((Uart.twoBits & 0x019E) == 0x001E) Uart.syncBit = 1; - else if ((Uart.twoBits & 0x00CF) == 0x000F) Uart.syncBit = 0; - if (Uart.syncBit != 0xFFFF) { + Uart.syncBit = 0xFFFF; // not set + // we look for a ...1111111100x11111xxxxxx pattern (the start bit) + if ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8; // mask is 11x11111 xxxxxxxx, + // check for 00x11111 xxxxxxxx + else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7; // both masks shifted right one bit, left padded with '1' + else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6; // ... + else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5; + else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4; + else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3; + else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2; + else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1; + if (Uart.syncBit != 0xFFFF) { // found a sync bit Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8); Uart.startTime -= Uart.syncBit; Uart.endTime = Uart.startTime; @@ -342,11 +343,9 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) { if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation in both halves - error UartReset(); - Uart.highCnt = 6; } else { // Modulation in first half = Sequence Z = logic "0" if (Uart.state == STATE_MILLER_X) { // error - must not follow after X UartReset(); - Uart.highCnt = 6; } else { Uart.bitCount++; Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg @@ -401,12 +400,13 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) if (Uart.len) { return TRUE; // we are finished with decoding the raw data sequence } else { - UartReset(); // Nothing receiver - start over + UartReset(); // Nothing received - start over + Uart.highCnt = 1; } } if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC UartReset(); - Uart.highCnt = 6; + Uart.highCnt = 1; } else { // a logic "0" Uart.bitCount++; Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg @@ -1425,6 +1425,7 @@ void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *p CodeIso14443aBitsAsReaderPar(cmd, len*8, parity); } + //----------------------------------------------------------------------------- // Wait for commands from reader // Stop when button is pressed (return 1) or field was gone (return 2) @@ -1447,9 +1448,9 @@ static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) // Set ADC to read field strength AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(32) | - ADC_MODE_STARTUP_TIME(16) | - ADC_MODE_SAMPLE_HOLD_TIME(8); + ADC_MODE_PRESCALE(63) | + ADC_MODE_STARTUP_TIME(1) | + ADC_MODE_SAMPLE_HOLD_TIME(15); AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); // start ADC AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; @@ -1459,7 +1460,7 @@ static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) // Clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - + for(;;) { WDT_HIT(); @@ -1471,7 +1472,7 @@ static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; if (analogCnt >= 32) { - if ((33000 * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { vtime = GetTickCount(); if (!timer) timer = vtime; // 50ms no field --> card to idle state @@ -1546,14 +1547,15 @@ static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNe } // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: - for (i = 0; i < 2 ; ) { + uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; + for (i = 0; i <= fpga_queued_bits/8 + 1; ) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = SEC_F; FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; i++; } } - + LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded?8:0); return 0; @@ -1655,7 +1657,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - + c = 0; for(;;) { WDT_HIT(); @@ -2264,6 +2266,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // free eventually allocated BigBuf memory but keep Emulator Memory BigBuf_free_keep_EM(); + // clear trace iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@ -2328,10 +2331,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * WDT_HIT(); // find reader field - // Vref = 3300mV, and an 10:1 voltage divider on the input - // can measure voltages up to 33000 mV if (cardSTATE == MFEMUL_NOFIELD) { - vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; if (vHf > MF_MINFIELDV) { cardSTATE_TO_IDLE(); LED_A_ON(); @@ -2406,6 +2407,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE); break; } + uint32_t ar = bytes_to_num(receivedCmd, 4); uint32_t nr = bytes_to_num(&receivedCmd[4], 4); @@ -2512,6 +2514,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); num_to_bytes(ans, 4, rAUTH_AT); } + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); //Dbprintf("Sending rAUTH %02x%02x%02x%02x", rAUTH_AT[0],rAUTH_AT[1],rAUTH_AT[2],rAUTH_AT[3]); cardSTATE = MFEMUL_AUTH1; @@ -2692,7 +2695,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * if(ar_nr_collected > 1) { Dbprintf("Collected two pairs of AR/NR which can be used to extract keys from reader:"); Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x", - ar_nr_responses[0], // UID + ar_nr_responses[0], // UID ar_nr_responses[1], //NT ar_nr_responses[2], //AR1 ar_nr_responses[3], //NR1 @@ -2712,6 +2715,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } } if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen); + } From f3bf15e4844454338fe42d5e93b897c7a61824a6 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 9 Feb 2015 11:11:04 -0500 Subject: [PATCH 6/8] lf/data combined detectclock functions to one cleaned up detect clock functions - now uses one main function that takes a char argument to select which modulation to detect the clock for REMOVED commands: pskdetectclock, nrzdetectclock, fskfcdetect. renamed DetectClock function to DetectAskClock to be more descriptive. --- client/cmddata.c | 107 ++++++++++----------------------- client/cmddata.h | 4 -- client/cmdlf.c | 4 +- client/cmdlfem4x.c | 2 +- client/graph.c | 143 ++++++++++++++++++++++++++++----------------- client/graph.h | 7 ++- common/lfdemod.c | 92 ++++++++++++++--------------- 7 files changed, 175 insertions(+), 184 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e54631751..1bd3f6de6 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -636,7 +636,7 @@ int CmdBitstream(const char *Cmd) } /* Get our clock */ - clock = GetClock(Cmd, high, 1); + clock = GetAskClock(Cmd, high, 1); gtl = ClearGraph(0); bit = 0; @@ -781,10 +781,33 @@ int CmdAskEdgeDetect(const char *Cmd) /* Print our clock rate */ // uses data from graphbuffer +// adjusted to take char parameter for type of modulation to find the clock - by marshmellow. int CmdDetectClockRate(const char *Cmd) { - int ans = GetClock("",0,0); - return ans; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data detectclock [modulation]"); + PrintAndLog(" [modulation as char], specify the modulation type you want to detect the clock of"); + PrintAndLog(" 'a' = ask, 'f' = fsk, 'n' = nrz/direct, 'p' = psk"); + PrintAndLog(""); + PrintAndLog(" sample: data detectclock a = detect the clock of an ask modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock f = detect the clock of an fsk modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock p = detect the clock of an psk modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock n = detect the clock of an nrz/direct modulated wave in the GraphBuffer"); + } + int ans=0; + if (cmdp == 'a'){ + ans = GetAskClock("", true, false); + } else if (cmdp == 'f'){ + ans = GetFskClock("", true, false); + } else if (cmdp == 'n'){ + ans = GetNrzClock("", true, false); + } else if (cmdp == 'p'){ + ans = GetPskClock("", true, false); + } else { + PrintAndLog ("Please specify a valid modulation to detect the clock of - see option h for help"); + } + return ans; } //by marshmellow @@ -995,7 +1018,6 @@ int CmdFSKdemodParadox(const char *Cmd) return 1; } - //by marshmellow //IO-Prox demod - FSK RF/64 with preamble of 000000001 //print ioprox ID and some format details @@ -1075,7 +1097,6 @@ int CmdFSKdemodIO(const char *Cmd) return 1; } - //by marshmellow //AWID Prox demod - FSK RF/50 with preamble of 00000001 (always a 96 bit data stream) //print full AWID Prox ID and some bit format details if found @@ -1420,55 +1441,6 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating return 0; } -//by marshmellow -//attempt to detect the field clock and bit clock for FSK -int CmdFSKfcDetect(const char *Cmd) -{ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(BitStream); - 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; - } - uint8_t fc1, fc2; - fc1 = (ans >> 8) & 0xFF; - fc2 = ans & 0xFF; - - uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2); - if (rf1==0) { - if (g_debugMode) PrintAndLog("DEBUG: Clock detect error"); - return 0; - } - 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 modulations -int CmdDetectPSKClockRate(const char *Cmd) -{ - GetPskClock("",0,0); - return 0; -} - -//by marshmellow -//attempt to detect the bit clock for NRZ modulations -int CmdDetectNRZClockRate(const char *Cmd) -{ - GetNrzClock("",0,0); - return 0; -} - //by marshmellow //attempt to psk1 demod graph buffer int PSKDemod(const char *Cmd, uint8_t verbose) @@ -1504,7 +1476,6 @@ int PSKDemod(const char *Cmd, uint8_t verbose) return errCnt; } - // Indala 26 bit decode // by marshmellow // optional arguments - same as CmdpskNRZrawDemod (clock & invert) @@ -1586,20 +1557,6 @@ int CmdIndalaDecode(const char *Cmd) return 1; } -/* -//by marshmellow -//attempt to clean psk wave noise after a peak -//NOTE RELIES ON PEAKS :( -int CmdPskClean(const char *Cmd) -{ - uint8_t bitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t bitLen = getFromGraphBuf(bitStream); - pskCleanWave(bitStream, bitLen); - setGraphBuf(bitStream, bitLen); - return 0; -} -*/ - // by marshmellow // takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate nrz only @@ -2046,7 +2003,7 @@ int CmdManchesterDemod(const char *Cmd) } /* Get our clock */ - clock = GetClock(Cmd, high, 1); + clock = GetAskClock(Cmd, high, 1); int tolerance = clock/4; @@ -2206,7 +2163,7 @@ int CmdManchesterMod(const char *Cmd) int bit, lastbit, wave; /* Get our clock */ - clock = GetClock(Cmd, 0, 1); + clock = GetAskClock(Cmd, 0, 1); wave = 0; lastbit = 1; @@ -2385,10 +2342,10 @@ static command_t CommandTable[] = {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate graph window as an AWID FSK tag using raw"}, - {"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, + //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK tag using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox tag FSK using raw"}, {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate graph window as a Pyramid FSK tag using raw"}, @@ -2405,10 +2362,10 @@ 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"}, + //{"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)"}, - {"pskdetectclock",CmdDetectPSKClockRate, 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)"}, {"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)"}, diff --git a/client/cmddata.h b/client/cmddata.h index 42954cbee..29b3bbc99 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -27,17 +27,13 @@ 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 CmdDetectPskClockRate(const char *Cmd); int CmdPSK1rawDemod(const char *Cmd); int CmdPSK2rawDemod(const char *Cmd); int CmdGrid(const char *Cmd); diff --git a/client/cmdlf.c b/client/cmdlf.c index 27e764a2a..b7c1b13f7 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -728,8 +728,8 @@ int CmdLFfind(const char *Cmd) if (testRaw=='u' || testRaw=='U'){ //test unknown tag formats (raw mode) PrintAndLog("\nChecking for Unknown tags:\n"); - ans=CmdFSKfcDetect(""); - if (ans == 1){ //fsk + ans=CmdDetectClockRate("f"); + if (ans != 0){ //fsk ans=CmdFSKrawdemod(""); if (ans>0) { PrintAndLog("\nUnknown FSK Modulated Tag Found!"); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 95b0342d4..232d56357 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -61,7 +61,7 @@ int CmdEM410xRead(const char *Cmd) } /* get clock */ - clock = GetClock(Cmd, high, 0); + clock = GetAskClock(Cmd, false, false); /* parity for our 4 columns */ parity[0] = parity[1] = parity[2] = parity[3] = 0; diff --git a/client/graph.c b/client/graph.c index f508fe883..11dbc4d59 100644 --- a/client/graph.c +++ b/client/graph.c @@ -76,33 +76,6 @@ size_t getFromGraphBuf(uint8_t *buff) return i; } - -// Get or auto-detect clock rate -int GetClock(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; - } - DetectASKClock(grph,size,&clock,20); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - } - } - return clock; -} - // A simple test to see if there is any data inside Graphbuffer. bool HasGraphData(){ @@ -135,52 +108,116 @@ void DetectHighLowInGraph(int *high, int *low, bool addFuzz) { } } -int GetPskClock(const char *str, int peak, int verbose) +// Get or auto-detect ask clock rate +int GetAskClock(const char str[], bool printAns, bool verbose) { int clock; sscanf(str, "%i", &clock); if (!strcmp(str, "")) clock = 0; + if (clock != 0) + return clock; // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(grph); - if ( size == 0 ) { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if (size == 0) { + if (verbose) 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 -1; + } + DetectASKClock(grph, size, &clock, 20); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); } return clock; } -int GetNrzClock(const char *str, int peak, int verbose) +int GetPskClock(const char str[], bool printAns, bool verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + if (clock!=0) + return clock; + // Auto-detect clock + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if ( size == 0 ) { + if (verbose) + PrintAndLog("Failed to copy from graphbuffer"); + return -1; + } + clock = DetectPSKClock(grph,size,0); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); + } + return clock; +} + +uint8_t GetNrzClock(const char str[], bool printAns, bool verbose) { int clock; sscanf(str, "%i", &clock); if (!strcmp(str, "")) clock = 0; + if (clock!=0) + return clock; // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(grph); - if ( size == 0 ) { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if ( size == 0 ) { + if (verbose) PrintAndLog("Failed to copy from graphbuffer"); - return -1; - } - clock = DetectNRZClock(grph,size,0); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - } + return -1; + } + clock = DetectNRZClock(grph, size, 0); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); } return clock; } +//by marshmellow +//attempt to detect the field clock and bit clock for FSK +uint8_t GetFskClock(const char str[], bool printAns, bool verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + if (clock != 0) return (uint8_t)clock; + + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; + uint8_t dummy = 0; + uint16_t ans = countFC(BitStream, size, &dummy); + if (ans==0) { + if (verbose) PrintAndLog("DEBUG: No data found"); + return 0; + } + uint8_t fc1, fc2; + fc1 = (ans >> 8) & 0xFF; + fc2 = ans & 0xFF; + + uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2); + if (rf1==0) { + if (verbose) PrintAndLog("DEBUG: Clock detect error"); + return 0; + } + if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ + if (printAns) PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + return rf1; + } + if (verbose){ + PrintAndLog("DEBUG: unknown fsk field clock detected"); + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + } + return 0; +} diff --git a/client/graph.h b/client/graph.h index 279b5f7b0..e4872afc4 100644 --- a/client/graph.h +++ b/client/graph.h @@ -16,9 +16,10 @@ void AppendGraph(int redraw, int clock, int bit); int ClearGraph(int redraw); //int DetectClock(int peak); size_t getFromGraphBuf(uint8_t *buff); -int GetClock(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); +int GetAskClock(const char str[], bool printAns, bool verbose); +int GetPskClock(const char str[], bool printAns, bool verbose); +uint8_t GetNrzClock(const char str[], bool printAns, bool verbose); +uint8_t GetFskClock(const char str[], bool printAns, bool verbose); void setGraphBuf(uint8_t *buff, size_t size); bool HasGraphData(); diff --git a/common/lfdemod.c b/common/lfdemod.c index 448195f2a..47e63ef6e 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -50,7 +50,7 @@ uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) for (uint8_t i = 0; i < bitLen; i++){ ans ^= ((bits >> i) & 1); } - //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType); + //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType); return (ans == pType); } @@ -244,14 +244,14 @@ int ManchesterEncode(uint8_t *BitStream, size_t size) { size_t modIdx=20000, i=0; if (size>modIdx) return -1; - for (size_t idx=0; idx < size; idx++){ - BitStream[idx+modIdx++] = BitStream[idx]; - BitStream[idx+modIdx++] = BitStream[idx]^1; - } - for (; i<(size*2); i++){ - BitStream[i] = BitStream[i+20000]; - } - return i; + for (size_t idx=0; idx < size; idx++){ + BitStream[idx+modIdx++] = BitStream[idx]; + BitStream[idx+modIdx++] = BitStream[idx]^1; + } + for (; i<(size*2); i++){ + BitStream[i] = BitStream[i+20000]; + } + return i; } //by marshmellow @@ -331,23 +331,23 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) //by marshmellow 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; + 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; + shiftedVal=BitStream[i]+shift; - if (shiftedVal>255) - shiftedVal=255; - else if (shiftedVal<0) - shiftedVal=0; - BitStream[i-1] = shiftedVal; - } - return; + if (shiftedVal>255) + shiftedVal=255; + else if (shiftedVal<0) + shiftedVal=0; + BitStream[i-1] = shiftedVal; + } + return; } //by marshmellow @@ -712,7 +712,7 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p for (int word = 0; word < (bLen); word+=pLen){ for (int bit=0; bit < pLen; bit++){ parityWd = (parityWd << 1) | BitStream[startIdx+word+bit]; - BitStream[j++] = (BitStream[startIdx+word+bit]); + BitStream[j++] = (BitStream[startIdx+word+bit]); } j--; // if parity fails then return 0 @@ -750,17 +750,17 @@ int AWIDdemodFSK(uint8_t *dest, size_t *size) // FSK Demod then try to locate an Farpointe Data (pyramid) ID int PyramiddemodFSK(uint8_t *dest, size_t *size) { - //make sure buffer has data - if (*size < 128*50) return -5; + //make sure buffer has data + if (*size < 128*50) return -5; - //test samples are not just noise - if (justNoise(dest, *size)) return -1; + //test samples are not just noise + if (justNoise(dest, *size)) return -1; - // FSK demodulator - *size = fskdemod(dest, *size, 50, 1, 10, 8); // fsk2a RF/50 - if (*size < 128) return -2; //did we get a good demod? + // FSK demodulator + *size = fskdemod(dest, *size, 50, 1, 10, 8); // fsk2a RF/50 + if (*size < 128) return -2; //did we get a good demod? - uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; size_t startIdx = 0; uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); if (errChk == 0) return -4; //preamble not found @@ -794,7 +794,7 @@ 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 == 0) return -1; if (size0 && maxPeak < peakcnt){ - maxPeak = peakcnt; + maxPeak = peakcnt; } peakcnt=0; } @@ -1041,7 +1041,7 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock) int iii=7; int best=0; for (iii=7; iii > 0; iii--){ - if (peaksdet[iii] > peaksdet[best]){ + 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]); @@ -1306,7 +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; + if (size == 0) return 0; uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); rfLensFnd=0; @@ -1329,7 +1329,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc fcCounter = fcLow; else //set it to the large fc fcCounter = fcHigh; - + //look for bit clock (rf/xx) if ((fcCounterlastFCcnt)){ //not the same size as the last wave - start of new bit sequence @@ -1496,7 +1496,7 @@ uint8_t countPSK_FC(uint8_t *BitStream, size_t size) uint8_t fcLensFnd = 0; uint32_t fcCounter = 0; size_t i; - if (size == 0) return 0; + if (size == 0) return 0; // prime i to first up transition for (i = 1; i < size-1; i++) @@ -1548,7 +1548,7 @@ uint8_t countPSK_FC(uint8_t *BitStream, size_t size) 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 == 0) return -1; if (*size Date: Mon, 9 Feb 2015 08:53:39 +0100 Subject: [PATCH 7/8] hw tune, data tune: adjusted "unusable" and "marginal" voltages. Display LF tuning graph only when LF antenna is connected. --- client/cmddata.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 1bd3f6de6..c6cb7d3f5 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1874,24 +1874,31 @@ int CmdTuneSamples(const char *Cmd) PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); - if (peakv<2000) + +#define LF_UNUSABLE_V 2948 // was 2000. Changed due to bugfix in voltage measurements. LF results are now 47% higher. +#define LF_MARGINAL_V 14739 // was 10000. Changed due to bugfix bug in voltage measurements. LF results are now 47% higher. +#define HF_UNUSABLE_V 3167 // was 2000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. +#define HF_MARGINAL_V 7917 // was 5000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. + + if (peakv < LF_UNUSABLE_V) PrintAndLog("# Your LF antenna is unusable."); - else if (peakv<10000) + else if (peakv < LF_MARGINAL_V) PrintAndLog("# Your LF antenna is marginal."); - if (vHf<2000) + if (vHf < HF_UNUSABLE_V) PrintAndLog("# Your HF antenna is unusable."); - else if (vHf<5000) + else if (vHf < HF_MARGINAL_V) PrintAndLog("# Your HF antenna is marginal."); - for (int i = 0; i < 256; i++) { - GraphBuffer[i] = resp.d.asBytes[i] - 128; + if (peakv >= LF_UNUSABLE_V) { + for (int i = 0; i < 256; i++) { + GraphBuffer[i] = resp.d.asBytes[i] - 128; + } + PrintAndLog("Displaying LF tuning graph. Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); + GraphTraceLen = 256; + ShowGraphWindow(); } - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); - GraphTraceLen = 256; - ShowGraphWindow(); - return 0; } From 3bba7deac0b4e1908db70e6a005d275859458c15 Mon Sep 17 00:00:00 2001 From: Jesse Hallio Date: Tue, 10 Feb 2015 04:31:53 +0200 Subject: [PATCH 8/8] Add settable ATQA and SAK to hf mf csetuid command. --- client/cmdhfmf.c | 55 ++++++++++++++++++++++++++++++++++++--------- client/mifarehost.c | 37 ++++++++++++++++-------------- client/mifarehost.h | 2 +- 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index f225359d7..d0852ea5b 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1433,27 +1433,60 @@ int CmdHF14AMfCSetUID(const char *Cmd) uint8_t wipeCard = 0; uint8_t uid[8] = {0x00}; uint8_t oldUid[8] = {0x00}; + uint8_t atqa[2] = {0x00}; + uint8_t sak[1] = {0x00}; + uint8_t atqaPresent = 1; int res; + char ctmp; + int argi=0; - if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { - PrintAndLog("Usage: hf mf csetuid "); - PrintAndLog("sample: hf mf csetuid 01020304 w"); - PrintAndLog("Set UID for magic Chinese card (only works with!!!)"); - PrintAndLog("If you want wipe card then add 'w' into command line. \n"); + if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') { + PrintAndLog("Usage: hf mf csetuid [ATQA 4 hex symbols SAK 2 hex symbols] [w]"); + PrintAndLog("sample: hf mf csetuid 01020304"); + PrintAndLog("sample: hf mf csetuid 01020304 0004 08 w"); + PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)"); + PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line."); return 0; - } + } - if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) { + if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) { PrintAndLog("UID must include 8 HEX symbols"); return 1; } + argi++; + + ctmp = param_getchar(Cmd, argi); + if (ctmp == 'w' || ctmp == 'W') { + wipeCard = 1; + atqaPresent = 0; + } + + if (atqaPresent) { + if (param_getchar(Cmd, argi)) { + if (param_gethex(Cmd, argi, atqa, 4)) { + PrintAndLog("ATQA must include 4 HEX symbols"); + return 1; + } + argi++; + if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) { + PrintAndLog("SAK must include 2 HEX symbols"); + return 1; + } + argi++; + } else + atqaPresent = 0; + } + + if(!wipeCard) { + ctmp = param_getchar(Cmd, argi); + if (ctmp == 'w' || ctmp == 'W') { + wipeCard = 1; + } + } - char ctmp = param_getchar(Cmd, 1); - if (ctmp == 'w' || ctmp == 'W') wipeCard = 1; - PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4)); - res = mfCSetUID(uid, oldUid, wipeCard); + res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid, wipeCard); if (res) { PrintAndLog("Can't set UID. error=%d", res); return 1; diff --git a/client/mifarehost.c b/client/mifarehost.c index 7f7848508..35499b836 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -231,28 +231,31 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { // "MAGIC" CARD -int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) { - +int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) { uint8_t oldblock0[16] = {0x00}; uint8_t block0[16] = {0x00}; - memcpy(block0, uid, 4); - block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC - // mifare classic SAK(byte 5) and ATQA(byte 6 and 7) - //block0[5] = 0x08; - //block0[6] = 0x04; - //block0[7] = 0x00; - - block0[5] = 0x01; //sak - block0[6] = 0x01; - block0[7] = 0x0f; - + int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER); - if ( old == 0) { - memcpy(block0+8, oldblock0+8, 8); - PrintAndLog("block 0: %s", sprint_hex(block0,16)); + if (old == 0) { + memcpy(block0, oldblock0, 16); + PrintAndLog("old block 0: %s", sprint_hex(block0,16)); } else { - PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0."); + PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0."); } + + // fill in the new values + // UID + memcpy(block0, uid, 4); + // Mifare UID BCC + block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; + // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed) + if (sak!=NULL) + block0[5]=sak[0]; + if (atqa!=NULL) { + block0[6]=atqa[1]; + block0[7]=atqa[0]; + } + PrintAndLog("new block 0: %s", sprint_hex(block0,16)); return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER); } diff --git a/client/mifarehost.h b/client/mifarehost.h index 96eb75f70..a11f11d50 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -55,7 +55,7 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); -int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe); +int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe); int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params); int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);