X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e770c6482407fb67c37973cc3e95409cd5c6d952..be2cf126bf74c3e0c60706dd2620c8a6d742e396:/client/cmddata.c diff --git a/client/cmddata.c b/client/cmddata.c index b03a3ebc..a1159ec8 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -21,6 +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; @@ -246,26 +248,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 +258,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 +327,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 +346,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 +395,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 +419,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 +458,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 +496,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 +504,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); @@ -694,6 +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 - @@ -716,6 +750,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 +789,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 +800,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 +1445,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 +1612,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 +1671,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 +1706,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"); @@ -1750,25 +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; } @@ -2261,6 +2377,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)"}, @@ -2305,7 +2422,8 @@ static command_t CommandTable[] = {"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} };