]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmddata.c
Merge remote-tracking branch 'upstream/master'
[proxmark3-svn] / client / cmddata.c
index b03a3ebcd51dff16521be259c2e8724f0871552d..a1159ec80675c6742942a4896f0c9783bed7f30e 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;
@@ -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("     <invert>, 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("     <invert>, 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] <invert>");
     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("     <invert>, 1 for invert output");
-    PrintAndLog("     [set maximum allowed errors], default = 100.");
+  if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
+    PrintAndLog("Usage:  data askrawdemod [clock] <invert> [maxError] [amplify]");
+    PrintAndLog("     [set clock as integer] optional, if not set, autodetect");
+    PrintAndLog("     <invert>, 1 to invert output");
+    PrintAndLog("     [set maximum allowed errors], default = 100");
+    PrintAndLog("     <amplify>, '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, &amp);
   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<GraphTraceLen; i++){
+    if (GraphBuffer[i]-GraphBuffer[i-1]>=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("     <invert>, 1 for invert output");
-
-    PrintAndLog("     [set maximum allowed errors], default = 100.");
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+    PrintAndLog("Usage:  data fskrawdemod [clock] <invert> [fchigh] [fclow]");
+    PrintAndLog("     [set clock as integer] optional, omit for autodetect.");
+    PrintAndLog("     <invert>, 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("     <invert>, 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("     <invert>, 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("     <invert>, 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, "<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