From: marshmellow42 Date: Fri, 6 Feb 2015 19:45:46 +0000 (-0500) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Tag: v2.0.0-rc1~26^2~2 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/be2cf126bf74c3e0c60706dd2620c8a6d742e396?ds=sidebyside;hp=-c Merge remote-tracking branch 'upstream/master' --- be2cf126bf74c3e0c60706dd2620c8a6d742e396 diff --combined armsrc/lfops.c index 67652986,479da772..e34eab35 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@@ -15,130 -15,44 +15,44 @@@ #include "crc16.h" #include "string.h" #include "lfdemod.h" + #include "lfsampling.h" /** - * Does the sample acquisition. If threshold is specified, the actual sampling - * is not commenced until the threshold has been reached. - * @param trigger_threshold - the threshold - * @param silent - is true, now outputs are made. If false, dbprints the status - */ - void DoAcquisition125k_internal(int trigger_threshold,bool silent) - { - uint8_t *dest = BigBuf_get_addr(); - int n = BigBuf_max_traceLen(); - int i; - - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - - } - } - /** - * Perform sample aquisition. - */ - void DoAcquisition125k(int trigger_threshold) - { - DoAcquisition125k_internal(trigger_threshold, false); - } - - /** - * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream - * if not already loaded, sets divisor and starts up the antenna. - * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz - * 0 or 95 ==> 125 KHz - * - **/ - void LFSetupFPGAForADC(int divisor, bool lf_field) - { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - } - /** - * Initializes the FPGA, and acquires the samples. - **/ - void AcquireRawAdcSamples125k(int divisor) - { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); - } - /** - * Initializes the FPGA for snoop-mode, and acquires the samples. - **/ - - void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) - { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); - } - + * Function to do a modulation and then get samples. + * @param delay_off + * @param period_0 + * @param period_1 + * @param command + */ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); - - int divisor_used = 95; // 125 KHz // see if 'h' was specified if (command[strlen((char *) command) - 1] == 'h') divisor_used = 88; // 134.8 KHz + sample_config sc = { 0,0,1, divisor_used, 0}; + setSamplingConfig(&sc); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - // And a little more time for the tag to fully power up - SpinDelay(2000); + LFSetupFPGAForADC(sc.divisor, 1); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // And a little more time for the tag to fully power up + SpinDelay(2000); // now modulate the reader field while(*command != '\0' && *command != ' ') { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); @@@ -150,14 -64,16 +64,16 @@@ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition125k(-1); + DoAcquisition_config(false); } + + /* blank r/w tag data stream ...0000000000000000 01111111 1010101010101010101010101010101010101010101010101010101010101010 @@@ -645,8 -561,8 +561,8 @@@ void CmdHIDdemodFSK(int findone, int *h WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - // FSK demodulator + DoAcquisition_default(-1,true); + // FSK demodulator size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); @@@ -724,7 -640,7 +640,7 @@@ void CmdEM410xdemod(int findone, int *h 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); @@@ -734,11 -650,11 +650,11 @@@ WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = BigBuf_max_traceLen(); + DoAcquisition_default(-1,true); + 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(); @@@ -787,8 -703,8 +703,8 @@@ void CmdIOdemodFSK(int findone, int *hi while(!BUTTON_PRESS()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - //fskdemod and get start index + DoAcquisition_default(-1,true); + //fskdemod and get start index WDT_HIT(); idx = IOdemodFSK(dest, BigBuf_max_traceLen()); if (idx>0){ @@@ -1394,7 -1310,9 +1310,9 @@@ int DemodPCF7931(uint8_t **outBlocks) int lmin=128, lmax=128; uint8_t dir; - AcquireRawAdcSamples125k(0); + LFSetupFPGAForADC(95, true); + DoAcquisition_default(0, 0); + lmin = 64; lmax = 192; diff --combined client/cmddata.c index 66ba7455,430afb17..a1159ec8 --- a/client/cmddata.c +++ b/client/cmddata.c @@@ -21,6 -21,8 +21,8 @@@ #include "cmdmain.h" #include "cmddata.h" #include "lfdemod.h" + #include "usb_cmd.h" + uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t g_debugMode; int DemodBufferLen; @@@ -247,113 -249,44 +249,113 @@@ void printEM410x(uint64_t id } //by marshmellow -//take binary from demod buffer and see if we can find an EM410x ID -int CmdEm410xDecode(const char *Cmd) +//takes 3 arguments - clock, invert and maxErr as integers +//attempts to demodulate ask while decoding manchester +//prints binary found and saves in graphbuffer for further commands +int CmdAskEM410xDemod(const char *Cmd) { - uint64_t id=0; - size_t size = DemodBufferLen, idx=0; - id = Em410xDecode(DemodBuffer, &size, &idx); - if (id>0){ - setDemodBuf(DemodBuffer, size, idx); + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer"); + PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data"); + PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); + + return 0; + } + + + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + size_t BitLen = getFromGraphBuf(BitStream); + + if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt<0||BitLen<16){ //if fatal error (or -1) + if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + return 0; + } + PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); + + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + //PrintAndLog("ASK/Manchester decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + setDemodBuf(BitStream,BitLen,0); + //printDemodBuff(); + uint64_t lo =0; + size_t idx=0; + lo = Em410xDecode(BitStream, &BitLen, &idx); + if (lo>0){ + //set GraphBuffer for clone or sim command + setDemodBuf(BitStream, BitLen, idx); if (g_debugMode){ - PrintAndLog("DEBUG: Printing demod buffer:"); + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); printDemodBuff(); } - printEM410x(id); - return 1; + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; } return 0; } - //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 3 arguments - clock, invert, maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { int invert=0; int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askmandemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askmandemod = demod an ask/manchester tag from GraphBuffer"); + PrintAndLog(" : data askmandemod 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askmandemod 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askmandemod 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askmandemod 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } - + if (clk==1){ + invert=1; + clk=0; + } size_t BitLen = getFromGraphBuf(BitStream); if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); if (errCnt<0||BitLen<16){ //if fatal error (or -1) if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; @@@ -382,7 -315,7 +384,7 @@@ printEM410x(lo); return 1; } - return 0; + return 1; } //by marshmellow @@@ -393,17 -326,6 +395,17 @@@ int Cmdmandecoderaw(const char *Cmd int i =0; int errCnt=0; size_t size=0; + size_t maxErr = 20; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data manrawdecode"); + PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); + return 0; + } + if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; for (;i=20){ + if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; } @@@ -455,21 -377,7 +457,21 @@@ int CmdBiphaseDecodeRaw(const char *Cmd int offset=0; int invert=0; int high=0, low=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data biphaserawdecode [offset] "); + PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position"); + PrintAndLog(" [invert <0|1>], set to 1 to invert output"); + PrintAndLog(""); + PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer"); + PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output"); + return 0; + } sscanf(Cmd, "%i %i", &offset, &invert); + if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; //get graphbuffer & high and low for (;i 12 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askrawdemod [clock] [maxError] [amplify]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); + PrintAndLog(""); + PrintAndLog(" sample: data askrawdemod = demod an ask tag from GraphBuffer"); + PrintAndLog(" : data askrawdemod a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLog(" : data askrawdemod 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askrawdemod 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askrawdemod 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askrawdemod 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data askrawdemod 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } + if (clk==1){ + invert=1; + clk=0; + } + if (amp == 'a' || amp == 'A') askAmp=1; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); + errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) PrintAndLog("no data found"); if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); return 0; } - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //move BitStream back to DemodBuffer setDemodBuf(BitStream,BitLen,0); //output if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); } PrintAndLog("ASK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@@ -689,6 -571,43 +691,43 @@@ int CmdDec(const char *Cmd RepaintGraphWindow(); return 0; } + /** + * Undecimate - I'd call it 'interpolate', but we'll save that + * name until someone does an actual interpolation command, not just + * blindly repeating samples + * @param Cmd + * @return + */ + int CmdUndec(const char *Cmd) + { + if(param_getchar(Cmd, 0) == 'h') + { + PrintAndLog("Usage: data undec [factor]"); + PrintAndLog("This function performs un-decimation, by repeating each sample N times"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" factor The number of times to repeat each sample.[default:2]"); + PrintAndLog("Example: 'data undec 3'"); + return 0; + } + + uint8_t factor = param_get8ex(Cmd, 0,2, 10); + //We have memory, don't we? + int swap[MAX_GRAPH_TRACE_LEN] = { 0 }; + uint32_t g_index = 0 ,s_index = 0; + while(g_index < GraphTraceLen && s_index < MAX_GRAPH_TRACE_LEN) + { + int count = 0; + for(count = 0; count < factor && s_index+count < MAX_GRAPH_TRACE_LEN; count ++) + swap[s_index+count] = GraphBuffer[g_index]; + s_index+=count; + } + + memcpy(GraphBuffer,swap, s_index * sizeof(int)); + GraphTraceLen = s_index; + RepaintGraphWindow(); + return 0; + } //by marshmellow //shift graph zero up or down based on input + or - @@@ -711,47 -630,20 +750,47 @@@ int CmdGraphShiftZero(const char *Cmd return 0; } +//by marshmellow +//use large jumps in read samples to identify edges of waves and then amplify that wave to max +//similar to dirtheshold, threshold, and askdemod commands +//takes a threshold length which is the measured length between two samples then determines an edge +int CmdAskEdgeDetect(const char *Cmd) +{ + int thresLen = 25; + sscanf(Cmd, "%i", &thresLen); + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=thresLen) //large jump up + shift=127; + else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down + shift=-127; + + shiftedVal=GraphBuffer[i]+shift; + + if (shiftedVal>127) + shiftedVal=127; + else if (shiftedVal<-127) + shiftedVal=-127; + GraphBuffer[i-1] = shiftedVal; + } + RepaintGraphWindow(); + //CmdNorm(""); + return 0; +} + /* Print our clock rate */ // uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) { - GetClock("",0,0); - //int clock = DetectASKClock(0); - //PrintAndLog("Auto-detected clock rate: %d", clock); - return 0; + int ans = GetClock("",0,0); + return ans; } //by marshmellow //fsk raw demod and print binary -//takes 4 arguments - Clock, invert, rchigh, rclow -//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) +//takes 4 arguments - Clock, invert, fchigh, fclow +//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave @@@ -760,23 -652,6 +799,23 @@@ int invert=0; int fchigh=0; int fclow=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data fskrawdemod [clock] [fchigh] [fclow]"); + PrintAndLog(" [set clock as integer] optional, omit for autodetect."); + PrintAndLog(" , 1 for invert output, can be used even if the clock is omitted"); + PrintAndLog(" [fchigh], larger field clock length, omit for autodetect"); + PrintAndLog(" [fclow], small field clock length, omit for autodetect"); + PrintAndLog(""); + PrintAndLog(" sample: data fskrawdemod = demod an fsk tag from GraphBuffer using autodetect"); + PrintAndLog(" : data fskrawdemod 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); + PrintAndLog(" : data fskrawdemod 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); + PrintAndLog(" : data fskrawdemod 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); + PrintAndLog(" : data fskrawdemod 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); + return 0; + } //set options from parameters entered with the command sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); @@@ -789,12 -664,10 +828,12 @@@ 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; @@@ -817,7 -690,6 +856,7 @@@ // 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"); } @@@ -834,9 -706,8 +873,9 @@@ int CmdFSKdemodHID(const char *Cmd uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave - int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); + int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ if (g_debugMode){ if (idx==-1){ @@@ -920,7 -791,6 +959,7 @@@ int CmdFSKdemodParadox(const char *Cmd uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ @@@ -972,7 -842,6 +1011,7 @@@ int CmdFSKdemodIO(const char *Cmd } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave idx = IOdemodFSK(BitStream,BitLen); @@@ -1049,7 -918,6 +1088,7 @@@ int CmdFSKdemodAWID(const char *Cmd //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = AWIDdemodFSK(BitStream, &size); @@@ -1149,7 -1017,6 +1188,7 @@@ int CmdFSKdemodPyramid(const char *Cmd //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = PyramiddemodFSK(BitStream, &size); @@@ -1389,9 -1256,8 +1428,9 @@@ int CmdFSKfcDetect(const char *Cmd { uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); - - uint16_t ans = countFC(BitStream, size); + if (size==0) return 0; + uint8_t dummy = 0; + uint16_t ans = countFC(BitStream, size, &dummy); if (ans==0) { if (g_debugMode) PrintAndLog("DEBUG: No data found"); return 0; @@@ -1405,69 -1271,44 +1444,69 @@@ if (g_debugMode) PrintAndLog("DEBUG: Clock detect error"); return 0; } - PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); - return 1; + if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + return 1; + } + if (g_debugMode){ + PrintAndLog("DEBUG: unknown fsk field clock detected"); + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + } + return 0; } //by marshmellow -//attempt to detect the bit clock for PSK or NRZ modulations -int CmdDetectNRZpskClockRate(const char *Cmd) +//attempt to detect the bit clock for PSK modulations +int CmdDetectPSKClockRate(const char *Cmd) { - GetNRZpskClock("",0,0); + GetPskClock("",0,0); return 0; } //by marshmellow -//attempt to psk1 or nrz demod graph buffer -//NOTE CURRENTLY RELIES ON PEAKS :( -int PSKnrzDemod(const char *Cmd, uint8_t verbose) +//attempt to detect the bit clock for NRZ modulations +int CmdDetectNRZClockRate(const char *Cmd) { - int invert=0; - int clk=0; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); - return -1; - } - if (verbose) PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + GetNrzClock("",0,0); + return 0; +} - //prime demod buffer for output - setDemodBuf(BitStream,BitLen,0); - return errCnt; +//by marshmellow +//attempt to psk1 demod graph buffer +int PSKDemod(const char *Cmd, uint8_t verbose) +{ + int invert=0; + int clk=0; + int maxErr=100; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; + } + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = pskRawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + return errCnt; } + + // Indala 26 bit decode // by marshmellow // optional arguments - same as CmdpskNRZrawDemod (clock & invert) @@@ -1475,9 -1316,9 +1514,9 @@@ int CmdIndalaDecode(const char *Cmd { int ans; if (strlen(Cmd)>0){ - ans = PSKnrzDemod(Cmd, 0); + ans = PSKDemod(Cmd, 0); } else{ //default to RF/32 - ans = PSKnrzDemod("32", 0); + ans = PSKDemod("32", 0); } if (ans < 0){ @@@ -1549,7 -1390,6 +1588,7 @@@ return 1; } +/* //by marshmellow //attempt to clean psk wave noise after a peak //NOTE RELIES ON PEAKS :( @@@ -1561,104 -1401,35 +1600,104 @@@ int CmdPskClean(const char *Cmd setGraphBuf(bitStream, bitLen); return 0; } +*/ // by marshmellow -// takes 2 arguments - clock and invert both as integers +// takes 3 arguments - clock, invert, maxErr as integers +// attempts to demodulate nrz only +// prints binary found and saves in demodbuffer for further commands +int CmdNRZrawDemod(const char *Cmd) +{ + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data nrzrawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer"); + PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); + PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } + + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; + } + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + }else{ + } + PrintAndLog("NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; +} + +// by marshmellow +// takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate psk only // prints binary found and saves in demodbuffer for further commands -int CmdpskNRZrawDemod(const char *Cmd) +int CmdPSK1rawDemod(const char *Cmd) { int errCnt; - - errCnt = PSKnrzDemod(Cmd, 1); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk1rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk1rawdemod = demod a psk1 tag from GraphBuffer"); + PrintAndLog(" : data psk1rawdemod 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk1rawdemod 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data psk1rawdemod 1 = demod a psk1 tag from GraphBuffer while inverting data"); + PrintAndLog(" : data psk1rawdemod 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + return 0; + } + errCnt = PSKDemod(Cmd, 1); //output if (errCnt<0){ - if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); + if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; - } + } if (errCnt>0){ - if (g_debugMode){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - } + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); }else{ - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - return 1; } - return 0; + PrintAndLog("PSK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; } // by marshmellow @@@ -1666,21 -1437,7 +1705,21 @@@ int CmdPSK2rawDemod(const char *Cmd) { int errCnt=0; - errCnt=PSKnrzDemod(Cmd, 1); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk2rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk2rawdemod = demod a psk2 tag from GraphBuffer, autodetect clock"); + PrintAndLog(" : data psk2rawdemod 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk2rawdemod 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); + PrintAndLog(" : data psk2rawdemod 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); + PrintAndLog(" : data psk2rawdemod 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); + return 0; + } + errCnt=PSKDemod(Cmd, 1); if (errCnt<0){ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; @@@ -1773,25 -1530,79 +1812,79 @@@ int CmdHpf(const char *Cmd RepaintGraphWindow(); return 0; } + typedef struct { + uint8_t * buffer; + uint32_t numbits; + uint32_t position; + }BitstreamOut; + + bool _headBit( BitstreamOut *stream) + { + int bytepos = stream->position >> 3; // divide by 8 + int bitpos = (stream->position++) & 7; // mask out 00000111 + return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1; + } + + uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) + { + int i; + uint8_t val = 0; + for(i =0 ; i < bits_per_sample; i++) + { + val |= (_headBit(b) << (7-i)); + } + return val; + } int CmdSamples(const char *Cmd) { - uint8_t got[BIGBUF_SIZE] = {0x00}; + //If we get all but the last byte in bigbuf, + // we don't have to worry about remaining trash + // in the last byte in case the bits-per-sample + // does not line up on byte boundaries + uint8_t got[BIGBUF_SIZE-1] = { 0 }; int n = strtol(Cmd, NULL, 0); if (n == 0) - n = 20000; + n = sizeof(got); if (n > sizeof(got)) n = sizeof(got); - PrintAndLog("Reading %d samples from device memory\n", n); + PrintAndLog("Reading %d bytes from device memory\n", n); GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[j] = ((int)got[j]) - 128; + PrintAndLog("Data fetched"); + UsbCommand response; + WaitForResponse(CMD_ACK, &response); + uint8_t bits_per_sample = 8; + + //Old devices without this feature would send 0 at arg[0] + if(response.arg[0] > 0) + { + sample_config *sc = (sample_config *) response.d.asBytes; + PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample + , sc->decimation); + bits_per_sample = sc->bits_per_sample; } - GraphTraceLen = n; + if(bits_per_sample < 8) + { + PrintAndLog("Unpacking..."); + BitstreamOut bout = { got, bits_per_sample * n, 0}; + int j =0; + for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) { + uint8_t sample = getByte(bits_per_sample, &bout); + GraphBuffer[j] = ((int) sample )- 128; + } + GraphTraceLen = j; + PrintAndLog("Unpacked %d samples" , j ); + }else + { + for (int j = 0; j < n; j++) { + GraphBuffer[j] = ((int)got[j]) - 128; + } + GraphTraceLen = n; + } + RepaintGraphWindow(); return 0; } @@@ -2284,9 -2095,7 +2377,9 @@@ static command_t CommandTable[] {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave - default = 25"}, + {"askem410xdemod",CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in demod buffer (offset = 0|1 bits to shift the decode start)"}, @@@ -2314,13 -2123,12 +2407,13 @@@ {"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"}, @@@ -2329,7 -2137,8 +2422,8 @@@ {"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"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {NULL, NULL, 0, NULL} }; diff --combined client/cmdlf.c index a34275f3,f56aa1b7..ea1ff131 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@@ -356,24 -356,155 +356,155 @@@ int CmdIndalaClone(const char *Cmd return 0; } + int usage_lf_read() + { + PrintAndLog("Usage: lf read"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog("This function takes no arguments. "); + PrintAndLog("Use 'lf config' to set parameters."); + return 0; + } + int usage_lf_snoop() + { + PrintAndLog("Usage: lf snoop"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog("This function takes no arguments. "); + PrintAndLog("Use 'lf config' to set parameters."); + return 0; + } + + int usage_lf_config() + { + PrintAndLog("Usage: lf config [H|] [b ] [d ] [a 0|1]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" L Low frequency (125 KHz)"); + PrintAndLog(" H High frequency (134 KHz)"); + PrintAndLog(" q Manually set divisor. 88-> 134KHz, 95-> 125 Hz"); + PrintAndLog(" b Sets resolution of bits per sample. Default (max): 8"); + PrintAndLog(" d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); + PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); + PrintAndLog(" t Sets trigger threshold. 0 means no threshold"); + PrintAndLog("Examples:"); + PrintAndLog(" lf config b 8 L"); + PrintAndLog(" Samples at 125KHz, 8bps."); + PrintAndLog(" lf config H b 4 d 3"); + PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with "); + PrintAndLog(" a resolution of 4 bits per sample."); + PrintAndLog(" lf read"); + PrintAndLog(" Performs a read (active field)"); + PrintAndLog(" lf snoop"); + PrintAndLog(" Performs a snoop (no active field)"); + return 0; + } + + int CmdLFSetConfig(const char *Cmd) + { + + uint8_t divisor = 0;//Frequency divisor + uint8_t bps = 0; // Bits per sample + uint8_t decimation = 0; //How many to keep + bool averaging = 1; // Defaults to true + bool errors = FALSE; + int trigger_threshold =-1;//Means no change + uint8_t unsigned_trigg = 0; + + uint8_t cmdp =0; + while(param_getchar(Cmd, cmdp) != 0x00) + { + PrintAndLog("working %c", param_getchar(Cmd, cmdp)); + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + return usage_lf_config(); + case 'H': + divisor = 88; + cmdp++; + break; + case 'L': + divisor = 95; + cmdp++; + break; + case 'q': + errors |= param_getdec(Cmd,cmdp+1,&divisor); + cmdp+=2; + break; + case 't': + errors |= param_getdec(Cmd,cmdp+1,&unsigned_trigg); + cmdp+=2; + if(!errors) trigger_threshold = unsigned_trigg; + break; + case 'b': + errors |= param_getdec(Cmd,cmdp+1,&bps); + cmdp+=2; + break; + case 'd': + errors |= param_getdec(Cmd,cmdp+1,&decimation); + cmdp+=2; + break; + case 'a': + averaging = param_getchar(Cmd,cmdp+1) == '1'; + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = 1; + break; + } + if(errors) break; + } + if(cmdp == 0) + { + errors = 1;// No args + } + + //Validations + if(errors) + { + return usage_lf_config(); + } + //Bps is limited to 8, so fits in lower half of arg1 + if(bps >> 8) bps = 8; + + sample_config config = { + decimation,bps,averaging,divisor,trigger_threshold + }; + //Averaging is a flag on high-bit of arg[1] + UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG}; + memcpy(c.d.asBytes,&config,sizeof(sample_config)); + SendCommand(&c); + return 0; + } + int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { - PrintAndLog("Samples 1: 'lf read'"); - PrintAndLog(" 2: 'lf read h'"); - PrintAndLog(" 3: 'lf read '"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + + uint8_t cmdp =0; + if(param_getchar(Cmd, cmdp) == 'h') + { + return usage_lf_read(); + } + //And ship it to device + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; + } + + int CmdLFSnoop(const char *Cmd) + { + uint8_t cmdp =0; + if(param_getchar(Cmd, cmdp) == 'h') + { + return usage_lf_snoop(); + } + + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) @@@ -450,33 -581,6 +581,6 @@@ int CmdLFSimManchester(const char *Cmd return 0; } - int CmdLFSnoop(const char *Cmd) - { - UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; - - // 'h' means higher-low-frequency, 134 kHz - c.arg[0] = 0; - c.arg[1] = -1; - - if (*Cmd == 'l') { - sscanf(Cmd, "l %"lli, &c.arg[1]); - } else if(*Cmd == 'h') { - c.arg[0] = 1; - sscanf(Cmd, "h %"lli, &c.arg[1]); - } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { - PrintAndLog("usage 1: snoop"); - PrintAndLog(" 2: snoop [trigger threshold]"); - PrintAndLog(" 3: snoop [trigger threshold]"); - PrintAndLog(""); - PrintAndLog("Sample: lf snoop l 200"); - PrintAndLog(" : lf snoop 95 200"); - return 0; - } - - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; - } int CmdVchDemod(const char *Cmd) { @@@ -559,17 -663,13 +663,17 @@@ int CmdLFfind(const char *Cmd { int ans=0; char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1>"); - PrintAndLog(" , if not set, try reading data from tag."); + char testRaw = param_getchar(Cmd, 1); + if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: lf search <0|1> [u]"); + PrintAndLog(" , if not set, try reading data from tag."); + PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); PrintAndLog(""); - PrintAndLog(" sample: lf search"); - PrintAndLog(" : lf search 1"); + PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); + PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); + PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); + return 0; } @@@ -580,9 -680,8 +684,9 @@@ 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) { @@@ -615,37 -714,12 +719,37 @@@ 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; } @@@ -654,12 -728,13 +758,13 @@@ static command_t CommandTable[] {"help", CmdHelp, 1, "This help"}, {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"}, {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, {"io", CmdLFIO, 1, "{ ioProx tags... }"}, {"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, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"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)"}, {"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)"}, diff --combined client/graph.h index 56d6178c,9817d776..279b5f7b --- a/client/graph.h +++ b/client/graph.h @@@ -17,14 -17,15 +17,16 @@@ 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(); void DetectHighLowInGraph(int *high, int *low, bool addFuzz); - #define MAX_GRAPH_TRACE_LEN (1024*128) + // Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample) + #define MAX_GRAPH_TRACE_LEN (40000 * 8 ) + extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern int GraphTraceLen; #endif