]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
em4x50read (work in progress)
authoradam@algroup.co.uk <adam@algroup.co.uk@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Mon, 6 Jul 2009 23:02:12 +0000 (23:02 +0000)
committeradam@algroup.co.uk <adam@algroup.co.uk@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Mon, 6 Jul 2009 23:02:12 +0000 (23:02 +0000)
winsrc/command.cpp

index f8a9d569d7cdb84c6091e6108d4987cb68fa0268..913631efa8b88d1ac29ff07a0195aa00d42c5b81 100644 (file)
@@ -256,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
@@ -2434,6 +2576,7 @@ static struct {
        "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
Impressum, Datenschutz