]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - winsrc/command.cpp
fix windows compile error and remove linux compile warnings
[proxmark3-svn] / winsrc / command.cpp
index 1f77c4883306d26db5cdac4d52d3c0e4b437c1c1..b5d3e3d7d69f2abc0fd652d92c8610594ce6c07c 100644 (file)
@@ -9,7 +9,6 @@
 #include <stdio.h>\r
 #include <limits.h>\r
 #include <math.h>\r
 #include <stdio.h>\r
 #include <limits.h>\r
 #include <math.h>\r
-#include <unistd.h>\r
 \r
 #include "prox.h"\r
 #include "../common/iso14443_crc.c"\r
 \r
 #include "prox.h"\r
 #include "../common/iso14443_crc.c"\r
@@ -257,6 +256,148 @@ static void CmdEM410xwatch(char *str)
        } while (go);\r
 }\r
 \r
        } while (go);\r
 }\r
 \r
+/* Read the transmitted data of an EM4x50 tag\r
+ * Format:\r
+ *\r
+ *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity\r
+ *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity\r
+ *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity\r
+ *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity\r
+ *  CCCCCCCC                         <- column parity bits\r
+ *  0                                <- stop bit\r
+ *  LW                               <- Listen Window\r
+ *\r
+ * This pattern repeats for every block of data being transmitted.\r
+ * Transmission starts with two Listen Windows (LW - a modulated\r
+ * pattern of 320 cycles each (32/32/128/64/64)).\r
+ *\r
+ * Note that this data may or may not be the UID. It is whatever data\r
+ * is stored in the blocks defined in the control word First and Last \r
+ * Word Read values. UID is stored in block 32.\r
+ */ \r
+static void CmdEM4x50read(char *str)\r
+{\r
+       int i, j, startblock, clock, skip, block, start, end, low, high;\r
+       BOOL complete= FALSE;\r
+       int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];\r
+       char tmp[6];\r
+\r
+       high= low= 0;\r
+       clock= 64;\r
+\r
+       /* first get high and low values */\r
+       for (i = 0; i < GraphTraceLen; i++)\r
+       {\r
+               if (GraphBuffer[i] > high)      \r
+                       high = GraphBuffer[i];\r
+               else if (GraphBuffer[i] < low)\r
+                       low = GraphBuffer[i];\r
+       }\r
+\r
+       /* populate a buffer with pulse lengths */\r
+       i= 0;\r
+       j= 0;\r
+       while(i < GraphTraceLen)\r
+               {\r
+               // measure from low to low\r
+               while(GraphBuffer[i] > low)\r
+                       ++i;\r
+               start= i;\r
+               while(GraphBuffer[i] < high)\r
+                       ++i;\r
+               while(GraphBuffer[i] > low)\r
+                       ++i;\r
+               tmpbuff[j++]= i - start;\r
+               }\r
+\r
+       \r
+       /* look for data start - should be 2 pairs of LW (pulses of 192,128) */\r
+       start= -1;\r
+       skip= 0;\r
+       for (i= 0; i < j - 4 ; ++i)\r
+               {\r
+               skip += tmpbuff[i];\r
+               if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)\r
+                       if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)\r
+                               if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)\r
+                                       if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)\r
+                                               {\r
+                                               start= i + 3;\r
+                                               break;\r
+                                               }\r
+               }\r
+       startblock= i + 3;\r
+\r
+       /* skip over the remainder of the LW */\r
+       skip += tmpbuff[i+1]+tmpbuff[i+2];\r
+       while(GraphBuffer[skip] > low)\r
+               ++skip;\r
+       skip += 8;\r
+\r
+       /* now do it again to find the end */\r
+       end= start;\r
+       for (i += 3; i < j - 4 ; ++i)\r
+               {\r
+               end += tmpbuff[i];\r
+               if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)\r
+                       if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)\r
+                               if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)\r
+                                       if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)\r
+                                               {\r
+                                               complete= TRUE;\r
+                                               break;\r
+                                               }\r
+               }\r
+\r
+       if (start >= 0)\r
+               PrintToScrollback("Found data at sample: %i",skip);\r
+       else\r
+               {\r
+               PrintToScrollback("No data found!");\r
+               PrintToScrollback("Try again with more samples.");\r
+               return;\r
+               }\r
+\r
+       if (!complete)\r
+               {\r
+               PrintToScrollback("*** Warning!");\r
+               PrintToScrollback("Partial data - no end found!");\r
+               PrintToScrollback("Try again with more samples.");\r
+               }\r
+\r
+       /* get rid of leading crap */\r
+       sprintf(tmp,"%i",skip);\r
+       CmdLtrim(tmp);\r
+\r
+       /* now work through remaining buffer printing out data blocks */\r
+       block= 0;\r
+       i= startblock;\r
+       while(block < 6)\r
+               {\r
+               PrintToScrollback("Block %i:", block);\r
+               // mandemod routine needs to be split so we can call it for data\r
+               // just print for now for debugging\r
+               Cmdmanchesterdemod("i 64");\r
+               skip= 0;\r
+               /* look for LW before start of next block */\r
+               for ( ; i < j - 4 ; ++i)\r
+                       {\r
+                       skip += tmpbuff[i];\r
+                       if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)\r
+                               if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)\r
+                                       break;\r
+                       }\r
+               while(GraphBuffer[skip] > low)\r
+                       ++skip;\r
+               skip += 8;\r
+               sprintf(tmp,"%i",skip);\r
+               CmdLtrim(tmp);\r
+               start += skip;\r
+               block++;\r
+               }\r
+}\r
+\r
+\r
 /* Read the ID of an EM410x tag.\r
  * Format:\r
  *   1111 1111 1           <-- standard non-repeatable header\r
 /* Read the ID of an EM410x tag.\r
  * Format:\r
  *   1111 1111 1           <-- standard non-repeatable header\r
@@ -498,7 +639,6 @@ static void ChkBitstream(char *str)
 static void CmdLosim(char *str)\r
 {\r
        int i;\r
 static void CmdLosim(char *str)\r
 {\r
        int i;\r
-       char *zero = "0";\r
 \r
        /* convert to bitstream if necessary */\r
        ChkBitstream(str);\r
 \r
        /* convert to bitstream if necessary */\r
        ChkBitstream(str);\r
@@ -536,6 +676,22 @@ static void CmdLoread(char *str)
        SendCommand(&c, FALSE);\r
 }\r
 \r
        SendCommand(&c, FALSE);\r
 }\r
 \r
+static void CmdDetectReader(char *str)\r
+{\r
+       UsbCommand c;\r
+       // 'l' means LF - 125/134 kHz\r
+       if(*str == 'l') {\r
+               c.ext1 = 1;\r
+       } else if (*str == 'h') {\r
+               c.ext1 = 2;\r
+       } else if (*str != '\0') {\r
+               PrintToScrollback("use 'detectreader' or 'detectreader l' or 'detectreader h'");\r
+               return;\r
+       }\r
+       c.cmd = CMD_LISTEN_READER_FIELD;\r
+        SendCommand(&c, FALSE);\r
+}\r
+\r
 /* send a command before reading */\r
 static void CmdLoCommandRead(char *str)\r
 {\r
 /* send a command before reading */\r
 static void CmdLoCommandRead(char *str)\r
 {\r
@@ -547,7 +703,7 @@ static void CmdLoCommandRead(char *str)
        c.cmd = CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K;\r
        sscanf(str, "%i %i %i %s %s", &c.ext1, &c.ext2, &c.ext3, &c.d.asBytes,&dummy+1);\r
        // in case they specified 'h'\r
        c.cmd = CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K;\r
        sscanf(str, "%i %i %i %s %s", &c.ext1, &c.ext2, &c.ext3, &c.d.asBytes,&dummy+1);\r
        // in case they specified 'h'\r
-       strcpy(&c.d.asBytes + strlen(c.d.asBytes),dummy);\r
+       strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);\r
        SendCommand(&c, FALSE);\r
 }\r
 \r
        SendCommand(&c, FALSE);\r
 }\r
 \r
@@ -1870,8 +2026,7 @@ static void CmdFlexdemod(char *str)
 \r
 static void Cmdaskdemod(char *str) {\r
        int i;\r
 \r
 static void Cmdaskdemod(char *str) {\r
        int i;\r
-       int n = 0;\r
-       int c,high,low = 0;\r
+       int c, high = 0, low = 0;\r
 \r
        // TODO: complain if we do not give 2 arguments here !\r
        sscanf(str, "%i", &c);\r
 \r
        // TODO: complain if we do not give 2 arguments here !\r
        sscanf(str, "%i", &c);\r
@@ -2081,7 +2236,7 @@ static void Cmdmanchestermod(char *str)
  *               Typical values can be 64, 32, 128...\r
  */\r
 static void Cmdmanchesterdemod(char *str) {\r
  *               Typical values can be 64, 32, 128...\r
  */\r
 static void Cmdmanchesterdemod(char *str) {\r
-       int i, j;\r
+       int i, j, invert= 0;\r
        int bit;\r
        int clock;\r
        int lastval;\r
        int bit;\r
        int clock;\r
        int lastval;\r
@@ -2093,6 +2248,16 @@ static void Cmdmanchesterdemod(char *str) {
        int bit2idx = 0;\r
        int warnings = 0;\r
 \r
        int bit2idx = 0;\r
        int warnings = 0;\r
 \r
+       /* check if we're inverting output */\r
+       if(*str == 'i')\r
+       {\r
+               PrintToScrollback("Inverting output");\r
+               invert= 1;\r
+               do\r
+                       ++str;\r
+               while(*str == ' '); // in case a 2nd argument was given\r
+       }\r
+\r
        /* Holds the decoded bitstream: each clock period contains 2 bits       */\r
        /* later simplified to 1 bit after manchester decoding.                 */\r
        /* Add 10 bits to allow for noisy / uncertain traces without aborting   */\r
        /* Holds the decoded bitstream: each clock period contains 2 bits       */\r
        /* later simplified to 1 bit after manchester decoding.                 */\r
        /* Add 10 bits to allow for noisy / uncertain traces without aborting   */\r
@@ -2163,7 +2328,7 @@ static void Cmdmanchesterdemod(char *str) {
                        if (!hithigh || !hitlow)\r
                                bit ^= 1;\r
 \r
                        if (!hithigh || !hitlow)\r
                                bit ^= 1;\r
 \r
-                       BitStream[bit2idx++] = bit;\r
+                       BitStream[bit2idx++] = bit ^ invert;\r
                }\r
        }\r
 \r
                }\r
        }\r
 \r
@@ -2171,7 +2336,7 @@ static void Cmdmanchesterdemod(char *str) {
        else\r
        {\r
 \r
        else\r
        {\r
 \r
-       /* Then detect duration between 2 successive transitions */\r
+               /* Then detect duration between 2 successive transitions */\r
                for (bitidx = 1; i < GraphTraceLen; i++)\r
                {\r
                        if (GraphBuffer[i-1] != GraphBuffer[i])\r
                for (bitidx = 1; i < GraphTraceLen; i++)\r
                {\r
                        if (GraphBuffer[i-1] != GraphBuffer[i])\r
@@ -2206,18 +2371,18 @@ static void Cmdmanchesterdemod(char *str) {
                                                PrintToScrollback("Error: too many detection errors, aborting.");\r
                                                return;\r
                                        }\r
                                                PrintToScrollback("Error: too many detection errors, aborting.");\r
                                                return;\r
                                        }\r
+                               }\r
                        }\r
                }\r
                        }\r
                }\r
-       }\r
 \r
 \r
-       // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream\r
-       // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful\r
-       // to stop output at the final bitidx2 value, not bitidx\r
-       for (i = 0; i < bitidx; i += 2) {\r
-               if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {\r
-                       BitStream[bit2idx++] = 1;\r
+               // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream\r
+               // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful\r
+               // to stop output at the final bitidx2 value, not bitidx\r
+               for (i = 0; i < bitidx; i += 2) {\r
+                       if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {\r
+                               BitStream[bit2idx++] = 1 ^ invert;\r
                } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {\r
                } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {\r
-                       BitStream[bit2idx++] = 0;\r
+                       BitStream[bit2idx++] = 0 ^ invert;\r
                } else {\r
                        // We cannot end up in this state, this means we are unsynchronized,\r
                        // move up 1 bit:\r
                } else {\r
                        // We cannot end up in this state, this means we are unsynchronized,\r
                        // move up 1 bit:\r
@@ -2231,8 +2396,8 @@ static void Cmdmanchesterdemod(char *str) {
                                        PrintToScrollback("Error: too many decode errors, aborting.");\r
                                        return;\r
                                }\r
                                        PrintToScrollback("Error: too many decode errors, aborting.");\r
                                        return;\r
                                }\r
-               }\r
-       }\r
+                       }\r
+               }       \r
        }\r
 \r
        PrintToScrollback("Manchester decoded bitstream");\r
        }\r
 \r
        PrintToScrollback("Manchester decoded bitstream");\r
@@ -2422,9 +2587,11 @@ static struct {
        "buffclear",            CmdBuffClear,0,         "    Clear sample buffer and graph window",\r
        "dec",                          CmdDec,1,               "    Decimate samples",\r
        "detectclock",          Cmddetectclockrate,1, "    Detect clock rate",\r
        "buffclear",            CmdBuffClear,0,         "    Clear sample buffer and graph window",\r
        "dec",                          CmdDec,1,               "    Decimate samples",\r
        "detectclock",          Cmddetectclockrate,1, "    Detect clock rate",\r
+       "detectreader",         CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)",\r
        "em410xsim",            CmdEM410xsim,1,         "<UID> -- Simulate EM410x tag",\r
        "em410xread",           CmdEM410xread,1,        "[clock rate] -- Extract ID from EM410x tag",\r
        "em410xwatch",          CmdEM410xwatch,0,       "    Watches for EM410x tags",\r
        "em410xsim",            CmdEM410xsim,1,         "<UID> -- Simulate EM410x tag",\r
        "em410xread",           CmdEM410xread,1,        "[clock rate] -- Extract ID from EM410x tag",\r
        "em410xwatch",          CmdEM410xwatch,0,       "    Watches for EM410x tags",\r
+       "em4x50read",           CmdEM4x50read,1,        "    Extract data from EM4x50 tag",\r
        "exit",                         CmdQuit,1,                      "    Exit program",\r
        "flexdemod",            CmdFlexdemod,1,         "    Demodulate samples for FlexPass",\r
        "fpgaoff",                      CmdFPGAOff,0,           "    Set FPGA off",                                                     // ## FPGA Control\r
        "exit",                         CmdQuit,1,                      "    Exit program",\r
        "flexdemod",            CmdFlexdemod,1,         "    Demodulate samples for FlexPass",\r
        "fpgaoff",                      CmdFPGAOff,0,           "    Set FPGA off",                                                     // ## FPGA Control\r
@@ -2452,7 +2619,7 @@ static struct {
        "hisamplest",           CmdHi14readt,0,         "    Get samples HF, for testing",\r
        "hisimlisten",          CmdHisimlisten,0,       "    Get HF samples as fake tag",\r
        "hpf",                          CmdHpf,1,               "    Remove DC offset from trace",\r
        "hisamplest",           CmdHi14readt,0,         "    Get samples HF, for testing",\r
        "hisimlisten",          CmdHisimlisten,0,       "    Get HF samples as fake tag",\r
        "hpf",                          CmdHpf,1,               "    Remove DC offset from trace",\r
-       "indalademod",          CmdIndalademod,0,         "['224'] -- Demodulate samples for Indala",\r
+       "indalademod",          CmdIndalademod,0,         "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)",\r
        "lcd",                          CmdLcd,0,                       "<HEX command> <count> -- Send command/data to LCD",\r
        "lcdreset",                     CmdLcdReset,0,          "    Hardware reset LCD",\r
        "load",                         CmdLoad,1,              "<filename> -- Load trace (to graph window",\r
        "lcd",                          CmdLcd,0,                       "<HEX command> <count> -- Send command/data to LCD",\r
        "lcdreset",                     CmdLcdReset,0,          "    Hardware reset LCD",\r
        "load",                         CmdLoad,1,              "<filename> -- Load trace (to graph window",\r
@@ -2461,7 +2628,7 @@ static struct {
        "losamples",            CmdLosamples,0,         "[128 - 16000] -- Get raw samples for LF tag",\r
        "losim",                        CmdLosim,0,             "    Simulate LF tag",\r
        "ltrim",                        CmdLtrim,1,             "<samples> -- Trim samples from left of trace",\r
        "losamples",            CmdLosamples,0,         "[128 - 16000] -- Get raw samples for LF tag",\r
        "losim",                        CmdLosim,0,             "    Simulate LF tag",\r
        "ltrim",                        CmdLtrim,1,             "<samples> -- Trim samples from left of trace",\r
-       "mandemod",                     Cmdmanchesterdemod,1,   "[clock rate] -- Try a Manchester demodulation on a binary stream",\r
+       "mandemod",                     Cmdmanchesterdemod,1,   "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)",\r
        "manmod",                       Cmdmanchestermod,1,     "[clock rate] -- Manchester modulate a binary stream",\r
        "norm",                         CmdNorm,1,              "    Normalize max/min to +/-500",\r
        "plot",                         CmdPlot,1,              "    Show graph window",\r
        "manmod",                       Cmdmanchestermod,1,     "[clock rate] -- Manchester modulate a binary stream",\r
        "norm",                         CmdNorm,1,              "    Normalize max/min to +/-500",\r
        "plot",                         CmdPlot,1,              "    Show graph window",\r
Impressum, Datenschutz