]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - winsrc/command.cpp
added 'buffclear' - when you absolutely positivley must clear every bit in the room
[proxmark3-svn] / winsrc / command.cpp
index 02abdd4f690ac2990b72f7d26114d3c7f2cd21c4..8a7fd6fbb9a28fef4feef68a90103ecc72e78d4a 100644 (file)
@@ -52,6 +52,13 @@ static void CmdReset(char *str)
        SendCommand(&c, FALSE);\r
 }\r
 \r
+static void CmdBuffClear(char *str)\r
+{\r
+       UsbCommand c;\r
+       c.cmd = CMD_BUFF_CLEAR;\r
+       SendCommand(&c, FALSE);\r
+       CmdClearGraph(TRUE);\r
+}\r
 \r
 static void CmdQuit(char *str)\r
 {\r
@@ -211,10 +218,10 @@ int CmdClearGraph(int redraw)
 {\r
        int gtl = GraphTraceLen;\r
        GraphTraceLen = 0;\r
-       \r
+\r
        if (redraw)\r
                RepaintGraphWindow();\r
-       \r
+\r
        return gtl;\r
 }\r
 \r
@@ -225,8 +232,8 @@ static void CmdAppendGraph(int redraw, int clock, int bit)
 \r
        for (i = 0; i < (int)(clock/2); i++)\r
                GraphBuffer[GraphTraceLen++] = bit ^ 1;\r
-       \r
-       for (i = (int)(clock/2); i < clock; i++)        \r
+\r
+       for (i = (int)(clock/2); i < clock; i++)\r
                GraphBuffer[GraphTraceLen++] = bit;\r
 \r
        if (redraw)\r
@@ -240,7 +247,7 @@ static void CmdEM410xwatch(char *str)
        char *zero = "";\r
        char *twok = "2000";\r
        go = 1;\r
-       \r
+\r
        do\r
        {\r
                CmdLoread(zero);\r
@@ -262,9 +269,10 @@ static void CmdEM410xread(char *str)
        int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;\r
        int parity[4];\r
        char id[11];\r
+       int retested = 0;\r
        int BitStream[MAX_GRAPH_TRACE_LEN];\r
        high = low = 0;\r
-       \r
+\r
        /* Detect high and lows and clock */\r
        for (i = 0; i < GraphTraceLen; i++)\r
        {\r
@@ -272,15 +280,15 @@ static void CmdEM410xread(char *str)
                        high = GraphBuffer[i];\r
                else if (GraphBuffer[i] < low)\r
                        low = GraphBuffer[i];\r
-       }       \r
-       \r
+       }\r
+\r
        /* get clock */\r
        clock = GetClock(str, high);\r
-       \r
+\r
        /* parity for our 4 columns */\r
        parity[0] = parity[1] = parity[2] = parity[3] = 0;\r
        header = rows = 0;\r
-       \r
+\r
        /* manchester demodulate */\r
        bit = bit2idx = 0;\r
        for (i = 0; i < (int)(GraphTraceLen / clock); i++)\r
@@ -288,7 +296,7 @@ static void CmdEM410xread(char *str)
                hithigh = 0;\r
                hitlow = 0;\r
                first = 1;\r
-               \r
+\r
                /* Find out if we hit both high and low peaks */\r
                for (j = 0; j < clock; j++)\r
                {\r
@@ -296,14 +304,14 @@ static void CmdEM410xread(char *str)
                                hithigh = 1;\r
                        else if (GraphBuffer[(i * clock) + j] == low)\r
                                hitlow = 1;\r
-                       \r
+\r
                        /* it doesn't count if it's the first part of our read\r
                         because it's really just trailing from the last sequence */\r
                        if (first && (hithigh || hitlow))\r
                                hithigh = hitlow = 0;\r
                        else\r
                                first = 0;\r
-                       \r
+\r
                        if (hithigh && hitlow)\r
                                break;\r
                }\r
@@ -315,6 +323,7 @@ static void CmdEM410xread(char *str)
                BitStream[bit2idx++] = bit;\r
        }\r
        \r
+retest:\r
        /* We go till 5 before the graph ends because we'll get that far below */\r
        for (i = 1; i < bit2idx - 5; i++)\r
        {\r
@@ -327,29 +336,29 @@ static void CmdEM410xread(char *str)
                                /* Read another byte! */\r
                                sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));\r
                                rows++;\r
-                               \r
+\r
                                /* Keep parity info */\r
                                parity[0] ^= BitStream[i];\r
                                parity[1] ^= BitStream[i+1];\r
                                parity[2] ^= BitStream[i+2];\r
                                parity[3] ^= BitStream[i+3];\r
-                               \r
+\r
                                /* Move 4 bits ahead */\r
                                i += 4;\r
                        }\r
-                       \r
+\r
                        /* Damn, something wrong! reset */\r
                        else\r
                        {\r
                                PrintToScrollback("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);\r
-                               \r
+\r
                                /* Start back rows * 5 + 9 header bits, -1 to not start at same place */\r
                                i -= 9 + (5 * rows) - 5;\r
 \r
                                rows = header = 0;\r
                        }\r
                }\r
-               \r
+\r
                /* Step 3: Got our 40 bits! confirm column parity */\r
                else if (rows == 10)\r
                {\r
@@ -360,34 +369,44 @@ static void CmdEM410xread(char *str)
                        {\r
                                /* Sweet! */\r
                                PrintToScrollback("EM410x Tag ID: %s", id);\r
-                               \r
+\r
                                /* Stop any loops */\r
                                go = 0;\r
-                               break;\r
+                               return;\r
                        }\r
-                       \r
+\r
                        /* Crap! Incorrect parity or no stop bit, start all over */\r
                        else\r
                        {\r
                                rows = header = 0;\r
-                               \r
+\r
                                /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */\r
                                i -= 59;\r
                        }\r
                }\r
-                               \r
+\r
                /* Step 1: get our header */\r
                else if (header < 9)\r
                {\r
                        /* Need 9 consecutive 1's */\r
                        if (BitStream[i] == 1)\r
                                header++;\r
-                       \r
+\r
                        /* We don't have a header, not enough consecutive 1 bits */\r
                        else\r
                                header = 0;\r
                }\r
        }\r
+       \r
+       /* if we've already retested after flipping bits, return */\r
+       if (retested++)\r
+               return;\r
+\r
+       /* if this didn't work, try flipping bits */\r
+       for (i = 0; i < bit2idx; i++)\r
+               BitStream[i] ^= 1;\r
+\r
+       goto retest;\r
 }\r
 \r
 /* emulate an EM410X tag\r
@@ -402,20 +421,20 @@ static void CmdEM410xsim(char *str)
 {\r
        int i, n, j, h, binary[4], parity[4];\r
        char *s = "0";\r
-       \r
+\r
        /* clock is 64 in EM410x tags */\r
        int clock = 64;\r
-       \r
+\r
        /* clear our graph */\r
        CmdClearGraph(0);\r
-       \r
+\r
        /* write it out a few times */\r
        for (h = 0; h < 4; h++)\r
        {\r
                /* write 9 start bits */\r
                for (i = 0; i < 9; i++)\r
                        CmdAppendGraph(0, clock, 1);\r
-               \r
+\r
                /* for each hex char */\r
                parity[0] = parity[1] = parity[2] = parity[3] = 0;\r
                for (i = 0; i < 10; i++)\r
@@ -424,36 +443,36 @@ static void CmdEM410xsim(char *str)
                        sscanf(&str[i], "%1x", &n);\r
                        for (j = 3; j >= 0; j--, n/= 2)\r
                                binary[j] = n % 2;\r
-                       \r
+\r
                        /* append each bit */\r
                        CmdAppendGraph(0, clock, binary[0]);\r
                        CmdAppendGraph(0, clock, binary[1]);\r
                        CmdAppendGraph(0, clock, binary[2]);\r
                        CmdAppendGraph(0, clock, binary[3]);\r
-                       \r
+\r
                        /* append parity bit */\r
                        CmdAppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);\r
-                       \r
+\r
                        /* keep track of column parity */\r
                        parity[0] ^= binary[0];\r
                        parity[1] ^= binary[1];\r
                        parity[2] ^= binary[2];\r
                        parity[3] ^= binary[3];\r
                }\r
-               \r
+\r
                /* parity columns */\r
                CmdAppendGraph(0, clock, parity[0]);\r
                CmdAppendGraph(0, clock, parity[1]);\r
                CmdAppendGraph(0, clock, parity[2]);\r
                CmdAppendGraph(0, clock, parity[3]);\r
-               \r
+\r
                /* stop bit */\r
                CmdAppendGraph(0, clock, 0);\r
        }\r
-       \r
+\r
        /* modulate that biatch */\r
        Cmdmanchestermod(s);\r
-       \r
+\r
        /* booyah! */\r
        RepaintGraphWindow();\r
 \r
@@ -463,7 +482,7 @@ static void CmdEM410xsim(char *str)
 static void ChkBitstream(char *str)\r
 {\r
        int i;\r
-       \r
+\r
        /* convert to bitstream if necessary */\r
        for (i = 0; i < (int)(GraphTraceLen / 2); i++)\r
        {\r
@@ -479,10 +498,10 @@ static void CmdLosim(char *str)
 {\r
        int i;\r
        char *zero = "0";\r
-       \r
+\r
        /* convert to bitstream if necessary */\r
        ChkBitstream(str);\r
-       \r
+\r
        for (i = 0; i < GraphTraceLen; i += 48) {\r
                UsbCommand c;\r
                int j;\r
@@ -1822,60 +1841,54 @@ static void CmdFlexdemod(char *str)
 }\r
 \r
 /*\r
- * Generic command to demodulate ASK. bit length in argument.\r
- * Giving the bit length helps discriminate ripple effects\r
- * upon zero crossing for noisy traces.\r
+ * Generic command to demodulate ASK.\r
  *\r
- * Second is convention: positive or negative (High mod means zero\r
+ * Argument is convention: positive or negative (High mod means zero\r
  * or high mod means one)\r
  *\r
  * Updates the Graph trace with 0/1 values\r
  *\r
  * Arguments:\r
- * sl : bit length in terms of number of samples per bit\r
- *      (use yellow/purple markers to compute).\r
  * c : 0 or 1\r
  */\r
 \r
 static void Cmdaskdemod(char *str) {\r
        int i;\r
-       int sign = 1;\r
        int n = 0;\r
-       int c = 0;\r
-       int t1 = 0;\r
+       int c,high,low = 0;\r
 \r
        // TODO: complain if we do not give 2 arguments here !\r
-       sscanf(str, "%i %i", &n, &c);\r
-       if (c == 0) {\r
-               c = 1 ;\r
-       } else {\r
-               c = -1;\r
+       sscanf(str, "%i", &c);\r
+\r
+       /* Detect high and lows and clock */\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
-       if (GraphBuffer[0]*c > 0) {\r
-               GraphBuffer[0] = 1;\r
+       if (GraphBuffer[0] > 0) {\r
+               GraphBuffer[0] = 1-c;\r
        } else {\r
-               GraphBuffer[0] = 0;\r
+               GraphBuffer[0] = c;\r
        }\r
        for(i=1;i<GraphTraceLen;i++) {\r
-               /* Analyse signal within the symbol length */\r
-               /* Decide if we crossed a zero */\r
-               if (GraphBuffer[i]*sign < 0) {\r
-                        /* Crossed a zero, check if this is a ripple or not */\r
-                       if ( (i-t1) > n/4 ) {\r
-                               sign = -sign;\r
-                               t1=i;\r
-                               if (GraphBuffer[i]*c > 0){\r
-                                       GraphBuffer[i]=1;\r
-                               } else {\r
-                                       GraphBuffer[i]=0;\r
-                               }\r
-                       } else {\r
-                       /* This is a ripple, set the current sample value\r
-                          to the same as previous */\r
-                               GraphBuffer[i] = GraphBuffer[i-1];\r
-                       }\r
+               /* Transitions are detected at each peak\r
+                * Transitions are either:\r
+                * - we're low: transition if we hit a high\r
+                * - we're high: transition if we hit a low\r
+                * (we need to do it this way because some tags keep high or\r
+                * low for long periods, others just reach the peak and go\r
+                * down)\r
+                */\r
+               if ((GraphBuffer[i]==high) && (GraphBuffer[i-1] == c)) {\r
+                                       GraphBuffer[i]=1-c;\r
+               } else if ((GraphBuffer[i]==low) && (GraphBuffer[i-1] == (1-c))){\r
+                       GraphBuffer[i] = c;\r
                } else {\r
+                       /* No transition */\r
                        GraphBuffer[i] = GraphBuffer[i-1];\r
                }\r
        }\r
@@ -1917,7 +1930,7 @@ int detectclock(int peak)
                        lastpeak = i;\r
                }\r
        }\r
-       \r
+\r
        return clock;\r
 }\r
 \r
@@ -1925,7 +1938,7 @@ int detectclock(int peak)
 int GetClock(char *str, int peak)\r
 {\r
        int clock;\r
-       \r
+\r
        sscanf(str, "%i", &clock);\r
        if (!strcmp(str, ""))\r
                clock = 0;\r
@@ -1934,12 +1947,12 @@ int GetClock(char *str, int peak)
        if (!clock)\r
        {\r
                clock = detectclock(peak);\r
-               \r
+\r
                /* Only print this message if we're not looping something */\r
                if (!go)\r
                        PrintToScrollback("Auto-detected clock rate: %d", clock);\r
        }\r
-       \r
+\r
        return clock;\r
 }\r
 \r
@@ -1966,16 +1979,16 @@ static void Cmdbitstream(char *str) {
 \r
        /* Get our clock */\r
        clock = GetClock(str, high);\r
-       \r
+\r
        gtl = CmdClearGraph(0);\r
-       \r
+\r
        bit = 0;\r
        for (i = 0; i < (int)(gtl / clock); i++)\r
        {\r
                hithigh = 0;\r
                hitlow = 0;\r
                first = 1;\r
-               \r
+\r
                /* Find out if we hit both high and low peaks */\r
                for (j = 0; j < clock; j++)\r
                {\r
@@ -1983,18 +1996,18 @@ static void Cmdbitstream(char *str) {
                                hithigh = 1;\r
                        else if (GraphBuffer[(i * clock) + j] == low)\r
                                hitlow = 1;\r
-                       \r
+\r
                        /* it doesn't count if it's the first part of our read\r
                         because it's really just trailing from the last sequence */\r
                        if (first && (hithigh || hitlow))\r
                                hithigh = hitlow = 0;\r
                        else\r
                                first = 0;\r
-                       \r
+\r
                        if (hithigh && hitlow)\r
                                break;\r
                }\r
-               \r
+\r
                /* If we didn't hit both high and low peaks, we had a bit transition */\r
                if (!hithigh || !hitlow)\r
                        bit ^= 1;\r
@@ -2015,7 +2028,7 @@ static void Cmdmanchestermod(char *str)
        int i, j;\r
        int clock;\r
        int bit, lastbit, wave;\r
-       \r
+\r
        /* Get our clock */\r
        clock = GetClock(str, 0);\r
 \r
@@ -2024,17 +2037,17 @@ static void Cmdmanchestermod(char *str)
        for (i = 0; i < (int)(GraphTraceLen / clock); i++)\r
        {\r
                bit = GraphBuffer[i * clock] ^ 1;\r
-               \r
+\r
                for (j = 0; j < (int)(clock/2); j++)\r
                        GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;\r
                for (j = (int)(clock/2); j < clock; j++)\r
                        GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;\r
-               \r
+\r
                /* Keep track of how we start our wave and if we changed or not this time */\r
                wave ^= bit ^ lastbit;\r
                lastbit = bit;\r
        }\r
-       \r
+\r
        RepaintGraphWindow();\r
 }\r
 \r
@@ -2084,9 +2097,9 @@ static void Cmdmanchesterdemod(char *str) {
 \r
        /* Get our clock */\r
        clock = GetClock(str, high);\r
-       \r
+\r
        int tolerance = clock/4;\r
-       \r
+\r
        /* Detect first transition */\r
        /* Lo-Hi (arbitrary)       */\r
        for (i = 0; i < GraphTraceLen; i++)\r
@@ -2101,8 +2114,11 @@ static void Cmdmanchesterdemod(char *str) {
        /* If we're not working with 1/0s, demod based off clock */\r
        if (high != 1)\r
        {\r
-               bit = 0;\r
-               for (i = 0; i < (int)(GraphTraceLen / clock); i++)\r
+               bit = 0; /* We assume the 1st bit is zero, it may not be\r
+                         * the case: this routine (I think) has an init problem.\r
+                         * Ed.\r
+                         */\r
+               for (; i < (int)(GraphTraceLen / clock); i++)\r
                {\r
                        hithigh = 0;\r
                        hitlow = 0;\r
@@ -2387,6 +2403,7 @@ static struct {
        "autocorr",                     CmdAutoCorr,1,          "<window length> -- Autocorrelation over window",\r
        "bitsamples",           CmdBitsamples,0,        "    Get raw samples as bitstring",\r
        "bitstream",            Cmdbitstream,1,         "[clock rate] -- Convert waveform into a bitstream",\r
+       "buffclear",            CmdBuffClear,0,         "    Clear sample buffer and graph window",\r
        "dec",                          CmdDec,1,               "    Decimate samples",\r
        "detectclock",          Cmddetectclockrate,1, "    Detect clock rate",\r
        "em410xsim",            CmdEM410xsim,1,         "<UID> -- Simulate EM410x tag",\r
Impressum, Datenschutz