]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmddata.c
Merged with master
[proxmark3-svn] / client / cmddata.c
index 998f5ebb175edaa23e8ceeb992edea6113860564..0ec73cbb79b542406bf1afd00df403ed12d9f349 100644 (file)
@@ -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;
@@ -537,10 +539,6 @@ int CmdBitstream(const char *Cmd)
       bit ^= 1;
 
     AppendGraph(0, clock, bit);
-       //    for (j = 0; j < (int)(clock/2); j++)
-       //      GraphBuffer[(i * clock) + j] = bit ^ 1;
-       //    for (j = (int)(clock/2); j < clock; j++)
-       //      GraphBuffer[(i * clock) + j] = bit;
   }
 
   RepaintGraphWindow();
@@ -564,6 +562,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 -
@@ -663,9 +698,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) {
@@ -725,8 +772,8 @@ int CmdFSKdemodHID(const char *Cmd)
   return 1;
 }
 
-//by marshmellow (based on existing demod + holiman's refactor)
-//Paradox Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
+//by marshmellow
+//Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded)
 //print full Paradox Prox ID and some bit format details if found
 int CmdFSKdemodParadox(const char *Cmd)
 {
@@ -736,9 +783,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){
@@ -778,7 +837,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){
@@ -838,13 +911,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)
@@ -852,7 +925,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);
     }
@@ -937,17 +1010,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
@@ -1043,7 +1116,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();
@@ -1137,8 +1209,7 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
   PrintAndLog("actual data bits start at sample %d", maxPos);
   PrintAndLog("length %d/%d", highLen, lowLen);
 
-       uint8_t bits[46];
-       bits[sizeof(bits)-1] = '\0';
+  uint8_t bits[46] = {0x00};
 
   // find bit pairs and manchester decode them
   for (i = 0; i < arraylen(bits) - 1; ++i) {
@@ -1195,13 +1266,18 @@ 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;
 }
 
-int PSKnrzDemod(const char *Cmd)
+//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;
        int clk=0;
@@ -1218,7 +1294,7 @@ int PSKnrzDemod(const char *Cmd)
                if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
                return -1;
        }
-       PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+  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);
@@ -1231,9 +1307,9 @@ int CmdIndalaDecode(const char *Cmd)
 {
   int ans;
   if (strlen(Cmd)>0){
-    ans = PSKnrzDemod(Cmd);
+    ans = PSKnrzDemod(Cmd, 0);
   } else{ //default to RF/32
-    ans = PSKnrzDemod("32");
+    ans = PSKnrzDemod("32", 0);
   }
 
        if (ans < 0){
@@ -1248,7 +1324,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");
@@ -1298,9 +1374,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};
@@ -1310,15 +1393,15 @@ int CmdPskClean(const char *Cmd)
        return 0;
 }
 
-//by marshmellow
-//takes 2 arguments - clock and invert both as integers
-//attempts to demodulate ask only
-//prints binary found and saves in graphbuffer for further commands
+// by marshmellow
+// takes 2 arguments - clock and invert both as integers
+// attempts to demodulate psk only
+// prints binary found and saves in demodbuffer for further commands
 int CmdpskNRZrawDemod(const char *Cmd)
 {
   int errCnt;
  
-  errCnt = PSKnrzDemod(Cmd);
+  errCnt = PSKnrzDemod(Cmd, 1);
        //output
        if (errCnt<0){
     if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);  
@@ -1340,6 +1423,32 @@ int CmdpskNRZrawDemod(const char *Cmd)
   return 0;
 }
 
+// by marshmellow
+// takes same args as cmdpsknrzrawdemod
+int CmdPSK2rawDemod(const char *Cmd)
+{
+  int errCnt=0;
+  errCnt=PSKnrzDemod(Cmd, 1);
+  if (errCnt<0){
+    if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);  
+    return 0;
+  } 
+  psk1TOpsk2(DemodBuffer, DemodBufferLen);
+  if (errCnt>0){
+    if (g_debugMode){
+      PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+      PrintAndLog("PSK2 demoded bitstream:");
+      // Now output the bitstream to the scrollback by line of 16 bits
+      printDemodBuff();
+    }
+  }else{
+    PrintAndLog("PSK2 demoded bitstream:");
+    // Now output the bitstream to the scrollback by line of 16 bits
+    printDemodBuff();  
+  }
+  return 1;
+}
+
 int CmdGrid(const char *Cmd)
 {
   sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
@@ -1356,7 +1465,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);
 
@@ -1365,7 +1474,7 @@ int CmdHexsamples(const char *Cmd)
     requested = 8;
   }
   if (offset + requested > sizeof(got)) {
-    PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
+    PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > %d", BIGBUF_SIZE);
     return 0;
        }
 
@@ -1412,27 +1521,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];
+       //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)
@@ -1954,8 +2117,9 @@ static command_t CommandTable[] =
   {"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"},
-       {"pskindalademod",CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional)"},
-       {"psknrzrawdemod",CmdpskNRZrawDemod,  1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional)"},
+       {"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)"},
   {"samples",       CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window"},
   {"save",          CmdSave,            1, "<filename> -- Save trace (from graph window)"},
   {"scale",         CmdScale,           1, "<int> -- Set cursor display scale"},
@@ -1964,7 +2128,8 @@ static command_t CommandTable[] =
   {"threshold",     CmdThreshold,       1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
        {"dirthreshold",  CmdDirectionalThreshold,   1, "<thres up> <thres down> -- 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}
 };
 
Impressum, Datenschutz