} 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
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
- \r
+\r
BitStream[bit2idx++] = bit;\r
}\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
header = 0;\r
}\r
}\r
- \r
+\r
/* if we've already retested after flipping bits, return */\r
if (retested++)\r
return;\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
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
+ static char dummy[3];\r
+\r
+ dummy[0]= ' ';\r
+\r
+ UsbCommand c;\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, (char *) &c.d.asBytes,(char *) &dummy+1);\r
+ // in case they specified 'h'\r
+ strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);\r
+ SendCommand(&c, FALSE);\r
+}\r
+\r
static void CmdLosamples(char *str)\r
{\r
int cnt = 0;\r
RepaintGraphWindow();\r
}\r
\r
-\r
static int CmdHisamplest(char *str, int nrlow)\r
{\r
int cnt = 0;\r
{\r
int cnt = 0;\r
int i;\r
- for(i = 0; i < 1536; i += 12) {\r
+// for(i = 0; i < 1536; i += 12) {\r
+ for(i = 0; i < 4000; i += 12) {\r
UsbCommand c;\r
c.cmd = CMD_DOWNLOAD_RAW_BITS_TI_TYPE;\r
c.ext1 = i;\r
}\r
}\r
}\r
- GraphTraceLen = 1536*32;\r
+// GraphTraceLen = 1536*32;\r
+ GraphTraceLen = 4000*32;\r
RepaintGraphWindow();\r
}\r
\r
+static void CmdFSKdemod(char *cmdline)\r
+{\r
+ static const int LowTone[] = {\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1\r
+ };\r
+ static const int HighTone[] = {\r
+ 1, 1, 1, 1, 1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
+ };\r
+\r
+ int convLen = max(arraylen(HighTone), arraylen(LowTone));\r
+ DWORD hi = 0, lo = 0;\r
+\r
+ int i, j;\r
+ int minMark=0, maxMark=0;\r
+ int lowLen = arraylen(LowTone);\r
+ int highLen = arraylen(HighTone);\r
+\r
+ for(i = 0; i < GraphTraceLen - convLen; i++) {\r
+ int lowSum = 0, highSum = 0;\r
+\r
+ for(j = 0; j < lowLen; j++) {\r
+ lowSum += LowTone[j]*GraphBuffer[i+j];\r
+ }\r
+ for(j = 0; j < highLen; j++) {\r
+ highSum += HighTone[j]*GraphBuffer[i+j];\r
+ }\r
+ lowSum = abs((100*lowSum) / lowLen);\r
+ highSum = abs((100*highSum) / highLen);\r
+ GraphBuffer[i] = (highSum << 16) | lowSum;\r
+ }\r
+\r
+ for(i = 0; i < GraphTraceLen - convLen - 16; i++) {\r
+ int j;\r
+ int lowTot = 0, highTot = 0;\r
+ // 10 and 8 are f_s divided by f_l and f_h, rounded\r
+ for(j = 0; j < 10; j++) {\r
+ lowTot += (GraphBuffer[i+j] & 0xffff);\r
+ }\r
+ for(j = 0; j < 8; j++) {\r
+ highTot += (GraphBuffer[i+j] >> 16);\r
+ }\r
+ GraphBuffer[i] = lowTot - highTot;\r
+ if (GraphBuffer[i]>maxMark) maxMark=GraphBuffer[i];\r
+ if (GraphBuffer[i]<minMark) minMark=GraphBuffer[i];\r
+ }\r
+\r
+ GraphTraceLen -= (convLen + 16);\r
+\r
+ RepaintGraphWindow();\r
+\r
+ // Find bit-sync (3 lo followed by 3 high)\r
+ int max = 0, maxPos = 0;\r
+ for(i = 0; i < 6000; i++) {\r
+ int dec = 0;\r
+ for(j = 0; j < 3*arraylen(LowTone); j++) {\r
+ dec -= GraphBuffer[i+j];\r
+ }\r
+ for(; j < 3*(arraylen(LowTone) + arraylen(HighTone) ); j++) {\r
+ dec += GraphBuffer[i+j];\r
+ }\r
+ if(dec > max) {\r
+ max = dec;\r
+ maxPos = i;\r
+ }\r
+ }\r
+\r
+ // place start of bit sync marker in graph\r
+ GraphBuffer[maxPos] = maxMark;\r
+ GraphBuffer[maxPos+1] = minMark;\r
+\r
+ maxPos += j;\r
+\r
+ // place end of bit sync marker in graph\r
+ GraphBuffer[maxPos] = maxMark;\r
+ GraphBuffer[maxPos+1] = minMark;\r
+\r
+ PrintToScrollback("actual data bits start at sample %d", maxPos);\r
+ PrintToScrollback("length %d/%d", arraylen(HighTone), arraylen(LowTone));\r
+\r
+ BYTE bits[46];\r
+ bits[sizeof(bits)-1] = '\0';\r
+\r
+ // find bit pairs and manchester decode them\r
+ for(i = 0; i < arraylen(bits)-1; i++) {\r
+ int dec = 0;\r
+ for(j = 0; j < arraylen(LowTone); j++) {\r
+ dec -= GraphBuffer[maxPos+j];\r
+ }\r
+ for(; j < arraylen(LowTone) + arraylen(HighTone); j++) {\r
+ dec += GraphBuffer[maxPos+j];\r
+ }\r
+ maxPos += j;\r
+ // place inter bit marker in graph\r
+ GraphBuffer[maxPos] = maxMark;\r
+ GraphBuffer[maxPos+1] = minMark;\r
+\r
+ // hi and lo form a 64 bit pair\r
+ hi = (hi<<1)|(lo>>31);\r
+ lo = (lo<<1);\r
+ // store decoded bit as binary (in hi/lo) and text (in bits[])\r
+ if(dec<0) {\r
+ bits[i] = '1';\r
+ lo|=1;\r
+ } else {\r
+ bits[i] = '0';\r
+ }\r
+ }\r
+ PrintToScrollback("bits: '%s'", bits);\r
+ PrintToScrollback("hex: %08x %08x", hi, lo);\r
+}\r
+\r
static void CmdTidemod(char *cmdline)\r
{\r
/* MATLAB as follows:\r
l = sign(sin(cumsum(l)));\r
h = sign(sin(cumsum(h)));\r
*/\r
- static const int LowTone[] = {\r
- 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1,\r
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1,\r
- -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1,\r
- -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1,\r
- -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1,\r
- 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1,\r
- 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1,\r
- -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,\r
- -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
- -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1,\r
- 1, 1, 1, 1, 1, 1, 1, -1, -1, -1,\r
- };\r
- static const int HighTone[] = {\r
- 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,\r
- -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
- -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1,\r
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1,\r
- -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
- -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
- 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,\r
- -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,\r
- -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1,\r
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,\r
- 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1,\r
- };\r
+ static const int LowTone[] = {\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1,\r
+ };\r
+ static const int HighTone[] = {\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,\r
+ 1, 1, 1, 1, 1, 1, 1,\r
+ };\r
\r
int convLen = max(arraylen(HighTone), arraylen(LowTone));\r
\r
\r
PrintToScrollback("length %d/%d", arraylen(HighTone), arraylen(LowTone));\r
\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
-\r
BYTE bits[64+16+8+1];\r
bits[sizeof(bits)-1] = '\0';\r
\r
RepaintGraphWindow();\r
}\r
\r
+static void CmdThreshold(char *str)\r
+{\r
+ int i;\r
+ int threshold = atoi(str);\r
+\r
+ for(i = 0; i < GraphTraceLen; i++) {\r
+ if(GraphBuffer[i]>= threshold)\r
+ GraphBuffer[i]=1;\r
+ else\r
+ GraphBuffer[i]=-1;\r
+ }\r
+ RepaintGraphWindow();\r
+}\r
+\r
static void CmdLtrim(char *str)\r
{\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
return;\r
}\r
}\r
- } \r
+ }\r
}\r
\r
PrintToScrollback("Manchester decoded bitstream");\r
}\r
}\r
\r
-\r
-\r
/*\r
* Usage ???\r
*/\r
ShowGraphWindow();\r
}\r
\r
+static void CmdGrid(char *str)\r
+{\r
+ sscanf(str, "%i %i", &PlotGridX, &PlotGridY);\r
+ RepaintGraphWindow();\r
+}\r
+\r
static void CmdHide(char *str)\r
{\r
HideGraphWindow();\r
SendCommand(&c, FALSE);\r
}\r
\r
+static void CmdReadmem(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_READ_MEM;\r
+ c.ext1 = atoi(str);\r
+ SendCommand(&c, FALSE);\r
+}\r
+\r
static void CmdLcdReset(char *str)\r
{\r
UsbCommand c;\r
}\r
}\r
\r
-\r
-\r
-static void CmdTest(char *str)\r
-{\r
-}\r
-\r
/*\r
* Sets the divisor for LF frequency clock: lets the user choose any LF frequency below\r
* 600kHz.\r
}\r
}\r
\r
-static void CmdSweepLF(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SWEEP_LF;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-\r
typedef void HandlerFunction(char *cmdline);\r
\r
/* in alphabetic order */\r
int offline; // 1 if the command can be used when in offline mode\r
char *docString;\r
} CommandTable[] = {\r
- "askdemod", Cmdaskdemod,1, "<samples per bit> <0|1> -- Attempt to demodulate simple ASK tags",\r
- "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
- "em410xread", CmdEM410xread,1, "[clock rate] -- Extract ID from EM410x tag",\r
- "em410xwatch", CmdEM410xwatch,0, " Watches for EM410x tags",\r
- "exit", CmdQuit,1, " Exit program",\r
- "flexdemod", CmdFlexdemod,1, " Demodulate samples for FlexPass",\r
- "fpgaoff", CmdFPGAOff,0, " Set FPGA off", // ## FPGA Control\r
- "hexsamples", CmdHexsamples,0, "<blocks> -- Dump big buffer as hex bytes",\r
- "hi14alist", CmdHi14alist,0, " List ISO 14443a history", // ## New list command\r
- "hi14areader", CmdHi14areader,0, " Act like an ISO14443 Type A reader", // ## New reader command\r
- "hi14asim", CmdHi14asim,0, "<UID> -- Fake ISO 14443a tag", // ## Simulate 14443a tag\r
- "hi14asnoop", CmdHi14asnoop,0, " Eavesdrop ISO 14443 Type A", // ## New snoop command\r
- "hi14bdemod", CmdHi14bdemod,1, " Demodulate ISO14443 Type B from tag",\r
- "hi14list", CmdHi14list,0, " List ISO 14443 history",\r
- "hi14read", CmdHi14read,0, " Read HF tag (ISO 14443)",\r
- "hi14sim", CmdHi14sim,0, " Fake ISO 14443 tag",\r
- "hi14snoop", CmdHi14snoop,0, " Eavesdrop ISO 14443",\r
- "hi15demod", CmdHi15demod,1, " Demodulate ISO15693 from tag",\r
- "hi15read", CmdHi15read,0, " Read HF tag (ISO 15693)",\r
- "hi15reader", CmdHi15reader,0, " Act like an ISO15693 reader", // new command greg\r
- "hi15sim", CmdHi15tag,0, " Fake an ISO15693 tag", // new command greg\r
- "hiddemod", CmdHiddemod,1, " Demodulate HID Prox Card II (not optimal)",\r
- "hide", CmdHide,1, " Hide graph window",\r
- "hidfskdemod", CmdHIDdemodFSK,0, " Realtime HID FSK demodulator",\r
- "hidsimtag", CmdHIDsimTAG,0, "<ID> -- HID tag simulator",\r
- "higet", CmdHi14read_sim,0, "<samples> -- Get samples HF, 'analog'",\r
- "hisamples", CmdHisamples,0, " Get raw samples for HF tag",\r
- "hisampless", CmdHisampless,0, "<samples> -- Get signed raw samples, HF tag",\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
- "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
- "loread", CmdLoread,0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)",\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, "[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
- "quit", CmdQuit,1, " Quit program",\r
- "reset", CmdReset,0, " Reset the Proxmark3",\r
- "save", CmdSave,1, "<filename> -- Save trace (from graph window)",\r
- "scale", CmdScale,1, "<int> -- Set cursor display scale",\r
- "setlfdivisor", CmdSetDivisor,0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)",\r
- "sri512read", CmdSri512read,0, "<int> -- Read contents of a SRI512 tag",\r
- "sweeplf", CmdSweepLF,0, " Sweep through LF freq range and store results in buffer",\r
- "tibits", CmdTibits,0, " Get raw bits for TI-type LF tag",\r
- "tidemod", CmdTidemod,0, " Demodulate raw bits for TI-type LF tag",\r
- "tiread", CmdTiread,0, " Read a TI-type 134 kHz tag",\r
- "tune", CmdTune,0, " Measure antenna tuning",\r
- "vchdemod", CmdVchdemod,0, "['clone'] -- Demodulate samples for VeriChip",\r
- "zerocrossings", CmdZerocrossings,1, " Count time between zero-crossings",\r
+ {"askdemod", Cmdaskdemod, 1, "<samples per bit> <0|1> -- Attempt to demodulate simple ASK tags"},\r
+ {"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
+ {"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
+ {"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"},\r
+ {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},\r
+ {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},\r
+ {"hexsamples", CmdHexsamples, 0, "<blocks> -- Dump big buffer as hex bytes"},\r
+ {"hi14alist", CmdHi14alist, 0, "List ISO 14443a history"},\r
+ {"hi14areader", CmdHi14areader, 0, "Act like an ISO14443 Type A reader"},\r
+ {"hi14asim", CmdHi14asim, 0, "<UID> -- Fake ISO 14443a tag"},\r
+ {"hi14asnoop", CmdHi14asnoop, 0, "Eavesdrop ISO 14443 Type A"},\r
+ {"hi14bdemod", CmdHi14bdemod, 1, "Demodulate ISO14443 Type B from tag"},\r
+ {"hi14list", CmdHi14list, 0, "List ISO 14443 history"},\r
+ {"hi14read", CmdHi14read, 0, "Read HF tag (ISO 14443)"},\r
+ {"hi14sim", CmdHi14sim, 0, "Fake ISO 14443 tag"},\r
+ {"hi14snoop", CmdHi14snoop, 0, "Eavesdrop ISO 14443"},\r
+ {"hi15demod", CmdHi15demod, 1, "Demodulate ISO15693 from tag"},\r
+ {"hi15read", CmdHi15read, 0, "Read HF tag (ISO 15693)"},\r
+ {"hi15reader", CmdHi15reader, 0, "Act like an ISO15693 reader"},\r
+ {"hi15sim", CmdHi15tag, 0, "Fake an ISO15693 tag"},\r
+ {"hiddemod", CmdHiddemod, 1, "Demodulate HID Prox Card II (not optimal)"},\r
+ {"hide", CmdHide, 1, "Hide graph window"},\r
+ {"hidfskdemod", CmdHIDdemodFSK, 0, "Realtime HID FSK demodulator"},\r
+ {"hidsimtag", CmdHIDsimTAG, 0, "<ID> -- HID tag simulator"},\r
+ {"higet", CmdHi14read_sim, 0, "<samples> -- Get samples HF, 'analog'"},\r
+ {"hisamples", CmdHisamples, 0, "Get raw samples for HF tag"},\r
+ {"hisampless", CmdHisampless, 0, "<samples> -- Get signed raw samples, HF tag"},\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 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
+ {"locomread", CmdLoCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},\r
+ {"loread", CmdLoread, 0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"},\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, "[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
+ {"quit", CmdQuit, 1, "Quit program"},\r
+ {"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},\r
+ {"reset", CmdReset, 0, "Reset the Proxmark3"},\r
+ {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},\r
+ {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},\r
+ {"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},\r
+ {"sri512read", CmdSri512read, 0, "<int> -- Read contents of a SRI512 tag"},\r
+ {"tibits", CmdTibits, 0, "Get raw bits for TI-type LF tag"},\r
+ {"tidemod", CmdTidemod, 1, "Demodulate raw bits for TI-type LF tag"},\r
+ {"tiread", CmdTiread, 0, "Read a TI-type 134 kHz tag"},\r
+ {"threshold", CmdThreshold, 1, "Maximize/minimize every value in the graph window depending on threshold"},\r
+ {"tune", CmdTune, 0, "Measure antenna tuning"},\r
+ {"vchdemod", CmdVchdemod, 0, "['clone'] -- Demodulate samples for VeriChip"},\r
+ {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},\r
};\r
\r
+static struct {\r
+ char *name;\r
+ char *args;\r
+ char *argshelp;\r
+ char *description;\r
+ } CommandExtendedHelp[]= {\r
+ {"detectreader","'l'|'h'","'l' specifies LF antenna scan only, 'h' specifies HF antenna scan only.","Monitor antenna for changes in voltage. Output is in three fields: CHANGED, CURRENT, PERIOD,\nwhere CHANGED is the value just changed from, CURRENT is the current value and PERIOD is the\nnumber of program loops since the last change.\n\nThe RED LED indicates LF field detected, and the GREEN LED indicates HF field detected."},\r
+ {"tune","","","Drive LF antenna at all divisor range values (19 - 255) and store the results in the output\nbuffer. Issuing 'losamples' and then 'plot' commands will display the resulting peak. 12MHz\ndivided by the peak's position plus one gives the antenna's resonant frequency. For convenience,\nthis value is also printed out by the command."},\r
+ };\r
\r
//-----------------------------------------------------------------------------\r
// Entry point into our code: called whenever the user types a command and\r
void CommandReceived(char *cmd)\r
{\r
int i;\r
+ char line[256];\r
\r
PrintToScrollback("> %s", cmd);\r
\r
- if(strcmp(cmd, "help")==0) {\r
+ if(strcmp(cmd, "help") == 0 || strncmp(cmd,"help ",strlen("help ")) == 0) {\r
+ // check if we're doing extended help\r
+ if(strlen(cmd) > strlen("help ")) {\r
+ cmd += strlen("help ");\r
+ for(i = 0; i < sizeof(CommandExtendedHelp) / sizeof(CommandExtendedHelp[0]); i++) {\r
+ if(strcmp(CommandExtendedHelp[i].name,cmd) == 0) {\r
+ PrintToScrollback("\nExtended help for '%s':\n", cmd);\r
+ PrintToScrollback("Args: %s\t- %s\n",CommandExtendedHelp[i].args,CommandExtendedHelp[i].argshelp);\r
+ PrintToScrollback(CommandExtendedHelp[i].description);\r
+ PrintToScrollback("");\r
+ return;\r
+ }\r
+ }\r
+ PrintToScrollback("No extended help available for '%s'", cmd);\r
+ return;\r
+ }\r
if (offline) PrintToScrollback("Operating in OFFLINE mode (no device connected)");\r
PrintToScrollback("\r\nAvailable commands:");\r
for(i = 0; i < sizeof(CommandTable) / sizeof(CommandTable[0]); i++) {\r
if (offline && (CommandTable[i].offline==0)) continue;\r
- char line[256];\r
memset(line, ' ', sizeof(line));\r
strcpy(line+2, CommandTable[i].name);\r
line[strlen(line)] = ' ';\r
PrintToScrollback("%s", line);\r
}\r
PrintToScrollback("");\r
- PrintToScrollback("and also: help, cls");\r
+ PrintToScrollback("'help <command>' for extended help on that command\n");\r
return;\r
}\r
\r
break;\r
\r
case CMD_MEASURED_ANTENNA_TUNING: {\r
- int zLf, zHf;\r
+ int peakv, peakf;\r
int vLf125, vLf134, vHf;\r
vLf125 = c->ext1 & 0xffff;\r
vLf134 = c->ext1 >> 16;\r
- vHf = c->ext2;\r
- zLf = c->ext3 & 0xffff;\r
- zHf = c->ext3 >> 16;\r
- PrintToScrollback("# LF antenna @ %3d mA / %5d mV [%d ohms] 125Khz",\r
- vLf125/zLf, vLf125, zLf);\r
- PrintToScrollback("# LF antenna @ %3d mA / %5d mV [%d ohms] 134Khz",\r
- vLf134/((zLf*125)/134), vLf134, (zLf*125)/134);\r
- PrintToScrollback("# HF antenna @ %3d mA / %5d mV [%d ohms] 13.56Mhz",\r
- vHf/zHf, vHf, zHf);\r
+ vHf = c->ext2 & 0xffff;;\r
+ peakf = c->ext3 & 0xffff;\r
+ peakv = c->ext3 >> 16;\r
+ PrintToScrollback("");\r
+ PrintToScrollback("");\r
+ PrintToScrollback("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);\r
+ PrintToScrollback("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);\r
+ PrintToScrollback("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));\r
+ PrintToScrollback("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);\r
+ if (peakv<2000)\r
+ PrintToScrollback("# Your LF antenna is unusable.");\r
+ else if (peakv<10000)\r
+ PrintToScrollback("# Your LF antenna is marginal.");\r
+ if (vHf<2000)\r
+ PrintToScrollback("# Your HF antenna is unusable.");\r
+ else if (vHf<5000)\r
+ PrintToScrollback("# Your HF antenna is marginal.");\r
break;\r
}\r
default:\r