X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/04d2721b3c7c4113e627d3f953835bde932065db..refs/heads/graphwork:/client/cmddata.c diff --git a/client/cmddata.c b/client/cmddata.c index 0c6cd72c..53a6584c 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" +#include "data_operations.h" uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t g_debugMode; int DemodBufferLen; @@ -56,6 +58,10 @@ void printDemodBuff() return; } if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty + + // 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", DemodBuffer[i], @@ -188,6 +194,11 @@ void printBitStream(uint8_t BitStream[], uint32_t 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], @@ -428,38 +439,16 @@ int Cmdaskrawdemod(const char *Cmd) return 1; } + int CmdAutoCorr(const char *Cmd) { - static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; - int window = atoi(Cmd); - - if (window == 0) { - PrintAndLog("needs a window"); - return 0; - } - if (window >= GraphTraceLen) { - PrintAndLog("window must be smaller than trace (%d samples)", - GraphTraceLen); - return 0; - } - - PrintAndLog("performing %d correlations", GraphTraceLen - window); - - for (int i = 0; i < GraphTraceLen - window; ++i) { - int sum = 0; - for (int j = 0; j < window; ++j) { - sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256; - } - CorrelBuffer[i] = sum; - } - GraphTraceLen = GraphTraceLen - window; - memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); - + autoCorr(GraphBuffer, GraphBuffer,GraphTraceLen,window); RepaintGraphWindow(); return 0; } + int CmdBitsamples(const char *Cmd) { int cnt = 0; @@ -560,6 +549,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 - @@ -659,9 +685,21 @@ int CmdFSKdemodHID(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); //get binary from fsk wave - size_t idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); + int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ - if (g_debugMode) PrintAndLog("DEBUG: Error demoding fsk"); + if (g_debugMode){ + if (idx==-1){ + PrintAndLog("DEBUG: Just Noise Detected"); + } else if (idx == -2) { + PrintAndLog("DEBUG: Error demoding fsk"); + } else if (idx == -3) { + PrintAndLog("DEBUG: Preamble not found"); + } else if (idx == -4) { + PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen); + } else { + PrintAndLog("DEBUG: Error demoding fsk %d", idx); + } + } return 0; } if (hi2==0 && hi==0 && lo==0) { @@ -732,9 +770,21 @@ int CmdFSKdemodParadox(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); //get binary from fsk wave - size_t idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); + int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ - if (g_debugMode) PrintAndLog("DEBUG: Error demoding fsk"); + if (g_debugMode){ + if (idx==-1){ + PrintAndLog("DEBUG: Just Noise Detected"); + } else if (idx == -2) { + PrintAndLog("DEBUG: Error demoding fsk"); + } else if (idx == -3) { + PrintAndLog("DEBUG: Preamble not found"); + } else if (idx == -4) { + PrintAndLog("DEBUG: Error in Manchester data"); + } else { + PrintAndLog("DEBUG: Error demoding fsk %d", idx); + } + } return 0; } if (hi2==0 && hi==0 && lo==0){ @@ -774,7 +824,21 @@ int CmdFSKdemodIO(const char *Cmd) //get binary from fsk wave idx = IOdemodFSK(BitStream,BitLen); if (idx<0){ - if (g_debugMode==1) PrintAndLog("DEBUG: demoding fsk error: %d", idx); + if (g_debugMode){ + if (idx==-1){ + PrintAndLog("DEBUG: Just Noise Detected"); + } else if (idx == -2) { + PrintAndLog("DEBUG: not enough samples"); + } else if (idx == -3) { + PrintAndLog("DEBUG: error during fskdemod"); + } else if (idx == -4) { + PrintAndLog("DEBUG: Preamble not found"); + } else if (idx == -5) { + PrintAndLog("DEBUG: Separator bits not found"); + } else { + PrintAndLog("DEBUG: Error demoding fsk %d", idx); + } + } return 0; } if (idx==0){ @@ -834,13 +898,13 @@ int CmdFSKdemodAWID(const char *Cmd) size_t size = getFromGraphBuf(BitStream); //get binary from fsk wave - int idx = AWIDdemodFSK(BitStream, size); + int idx = AWIDdemodFSK(BitStream, &size); if (idx<=0){ if (g_debugMode==1){ if (idx == -1) PrintAndLog("DEBUG: Error - not enough samples"); else if (idx == -2) - PrintAndLog("DEBUG: Error - only noise found - no waves"); + PrintAndLog("DEBUG: Error - only noise found"); else if (idx == -3) PrintAndLog("DEBUG: Error - problem during FSK demod"); // else if (idx == -3) @@ -848,7 +912,7 @@ int CmdFSKdemodAWID(const char *Cmd) else if (idx == -4) PrintAndLog("DEBUG: Error - AWID preamble not found"); else if (idx == -5) - PrintAndLog("DEBUG: Error - Second AWID preamble not found"); + PrintAndLog("DEBUG: Error - Size not correct: %d", size); else PrintAndLog("DEBUG: Error %d",idx); } @@ -933,17 +997,17 @@ int CmdFSKdemodPyramid(const char *Cmd) size_t size = getFromGraphBuf(BitStream); //get binary from fsk wave - int idx = PyramiddemodFSK(BitStream, size); + int idx = PyramiddemodFSK(BitStream, &size); if (idx < 0){ if (g_debugMode==1){ if (idx == -5) PrintAndLog("DEBUG: Error - not enough samples"); else if (idx == -1) - PrintAndLog("DEBUG: Error - only noise found - no waves"); + PrintAndLog("DEBUG: Error - only noise found"); else if (idx == -2) PrintAndLog("DEBUG: Error - problem during FSK demod"); else if (idx == -3) - PrintAndLog("DEBUG: Error - Second Pyramid preamble not found"); + PrintAndLog("DEBUG: Error - Size not correct: %d", size); else if (idx == -4) PrintAndLog("DEBUG: Error - Pyramid preamble not found"); else @@ -1039,7 +1103,6 @@ int CmdFSKdemodPyramid(const char *Cmd) PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); } } - //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands if (g_debugMode){ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); printDemodBuff(); @@ -1190,12 +1253,17 @@ int CmdFSKfcDetect(const char *Cmd) return 1; } +//by marshmellow +//attempt to detect the bit clock for PSK or NRZ modulations int CmdDetectNRZpskClockRate(const char *Cmd) { GetNRZpskClock("",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) { int invert=0; @@ -1243,7 +1311,7 @@ int CmdIndalaDecode(const char *Cmd) PrintAndLog("Error2: %d",ans); return -1; } - char showbits[251]; + char showbits[251]={0x00}; if (invert) if (g_debugMode==1) PrintAndLog("Had to invert bits"); @@ -1293,9 +1361,16 @@ 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(); + } 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}; @@ -1377,7 +1452,7 @@ int CmdHexsamples(const char *Cmd) int offset = 0; char string_buf[25]; char* string_ptr = string_buf; - uint8_t got[40000]; + uint8_t got[BIGBUF_SIZE]; sscanf(Cmd, "%i %i", &requested, &offset); @@ -1386,7 +1461,7 @@ int CmdHexsamples(const char *Cmd) requested = 8; } if (offset + requested > sizeof(got)) { - PrintAndLog("Tried to read past end of buffer, + > 40000"); + PrintAndLog("Tried to read past end of buffer, + > %d", BIGBUF_SIZE); return 0; } @@ -1433,27 +1508,81 @@ 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[40000] = {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); - GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[j] = ((int)got[j]) - 128; - } - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + PrintAndLog("Reading %d bytes from device memory\n", n); + GetFromBigBuf(got,n,0); + 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; + } + 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; } int CmdTuneSamples(const char *Cmd) @@ -1519,8 +1648,8 @@ int CmdLoad(const char *Cmd) FILE *f = fopen(filename, "r"); if (!f) { - PrintAndLog("couldn't open '%s'", filename); - return 0; + PrintAndLog("couldn't open '%s'", filename); + return 0; } GraphTraceLen = 0; @@ -1882,30 +2011,7 @@ int CmdDirectionalThreshold(const char *Cmd) printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); - int lastValue = GraphBuffer[0]; - GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. - - for (int i = 1; i < GraphTraceLen; ++i) { - // Apply first threshold to samples heading up - if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = 1; - } - // Apply second threshold to samples heading down - else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = -1; - } - else - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = GraphBuffer[i-1]; - - } - } - GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. + directionalThreshold(GraphBuffer, GraphBuffer,GraphTraceLen, upThres, downThres); RepaintGraphWindow(); return 0; } @@ -1986,7 +2092,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} };