\r
#include "prox.h"\r
#include "../common/iso14443_crc.c"\r
+#include "../common/crc16.c"\r
\r
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))\r
#define BIT(x) GraphBuffer[x * clock]\r
SendCommand(&c, FALSE);\r
}\r
\r
+static void CmdLegicRfSim(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_SIMULATE_TAG_LEGIC_RF;\r
+ SendCommand(&c, FALSE);\r
+}\r
+\r
static void CmdFPGAOff(char *str) // ## FPGA Control\r
{\r
UsbCommand c;\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
+ * 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
+ */\r
static void CmdEM4x50read(char *str)\r
{\r
int i, j, startblock, clock, skip, block, start, end, low, high;\r
/* first get high and low values */\r
for (i = 0; i < GraphTraceLen; i++)\r
{\r
- if (GraphBuffer[i] > high) \r
+ if (GraphBuffer[i] > high)\r
high = GraphBuffer[i];\r
else if (GraphBuffer[i] < low)\r
low = GraphBuffer[i];\r
while(i < GraphTraceLen)\r
{\r
// measure from low to low\r
- while(GraphBuffer[i] > low)\r
+ while((GraphBuffer[i] > low) && (i<GraphTraceLen))\r
++i;\r
start= i;\r
- while(GraphBuffer[i] < high)\r
+ while((GraphBuffer[i] < high) && (i<GraphTraceLen))\r
++i;\r
- while(GraphBuffer[i] > low)\r
+ while((GraphBuffer[i] > low) && (i<GraphTraceLen))\r
++i;\r
+ if (j>(MAX_GRAPH_TRACE_LEN/64)) {\r
+ break;\r
+ }\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
\r
/* skip over the remainder of the LW */\r
skip += tmpbuff[i+1]+tmpbuff[i+2];\r
- while(GraphBuffer[skip] > low)\r
+ while(skip < MAX_GRAPH_TRACE_LEN && GraphBuffer[skip] > low)\r
++skip;\r
skip += 8;\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
- \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
SendCommand(&c, FALSE);\r
}\r
\r
+static void CmdLosimBidir(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_LF_SIMULATE_BIDIR;\r
+ c.ext1 = 47; /* Set ADC to twice the carrier for a slight supersampling */\r
+ c.ext2 = 384;\r
+ SendCommand(&c, FALSE);\r
+}\r
+\r
static void CmdLoread(char *str)\r
{\r
UsbCommand c;\r
static char dummy[3];\r
\r
dummy[0]= ' ';\r
- \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
RepaintGraphWindow();\r
}\r
\r
-\r
static int CmdHisamplest(char *str, int nrlow)\r
{\r
int cnt = 0;\r
PrintToScrollback("CRC=%04x", Iso15693Crc(outBuf, k-2));\r
}\r
\r
-static void CmdTiread(char *str)\r
+static void CmdFSKdemod(char *cmdline)\r
{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_BITS_TI_TYPE;\r
- SendCommand(&c, FALSE);\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
-static void CmdTibits(char *str)\r
-{\r
- int cnt = 0;\r
- int i;\r
- for(i = 0; i < 1536; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_BITS_TI_TYPE;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_BITS_TI_TYPE) {\r
- PrintToScrollback("bad resp");\r
- return;\r
+ int lowLen = sizeof(LowTone)/sizeof(int);\r
+ int highLen = sizeof(HighTone)/sizeof(int);\r
+ int convLen = (highLen>lowLen)?highLen:lowLen;\r
+ DWORD hi = 0, lo = 0;\r
+\r
+ int i, j;\r
+ int minMark=0, maxMark=0;\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
- for(j = 0; j < 12; j++) {\r
- int k;\r
- for(k = 31; k >= 0; k--) {\r
- if(c.d.asDwords[j] & (1 << k)) {\r
- GraphBuffer[cnt++] = 1;\r
- } else {\r
- GraphBuffer[cnt++] = -1;\r
- }\r
- }\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
- GraphTraceLen = 1536*32;\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*lowLen; j++) {\r
+ dec -= GraphBuffer[i+j];\r
+ }\r
+ for(; j < 3*(lowLen + highLen ); 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", highLen, lowLen);\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 < lowLen; j++) {\r
+ dec -= GraphBuffer[maxPos+j];\r
+ }\r
+ for(; j < lowLen + highLen; 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
+// read a TI tag and return its ID\r
+static void CmdTIRead(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_READ_TI_TYPE;\r
+ SendCommand(&c, FALSE);\r
}\r
\r
-static void CmdTidemod(char *cmdline)\r
+// write new data to a r/w TI tag\r
+static void CmdTIWrite(char *str)\r
+{\r
+ UsbCommand c;\r
+ int res=0;\r
+\r
+ c.cmd = CMD_WRITE_TI_TYPE;\r
+ res = sscanf(str, "0x%x 0x%x 0x%x ", &c.ext1, &c.ext2, &c.ext3);\r
+ if (res == 2) c.ext3=0;\r
+ if (res<2)\r
+ PrintToScrollback("Please specify the data as two hex strings, optionally the CRC as a third");\r
+ else\r
+ SendCommand(&c, FALSE);\r
+}\r
+\r
+static void CmdTIDemod(char *cmdline)\r
{\r
/* MATLAB as follows:\r
f_s = 2000000; % sampling frequency\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
\r
- int convLen = max(arraylen(HighTone), arraylen(LowTone));\r
+// 2M*16/134.2k = 238\r
+ static const int LowTone[] = {\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, -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\r
+ };\r
+// 2M*16/123.2k = 260\r
+ static const int HighTone[] = {\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,\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\r
+ };\r
+ int lowLen = sizeof(LowTone)/sizeof(int);\r
+ int highLen = sizeof(HighTone)/sizeof(int);\r
+ int convLen = (highLen>lowLen)?highLen:lowLen;\r
+ WORD crc;\r
+ int i, j, TagType;\r
+ int lowSum = 0, highSum = 0;;\r
+ int lowTot = 0, highTot = 0;\r
\r
- int i;\r
for(i = 0; i < GraphTraceLen - convLen; i++) {\r
- int j;\r
- int lowSum = 0, highSum = 0;;\r
- int lowLen = arraylen(LowTone);\r
- int highLen = arraylen(HighTone);\r
+ lowSum = 0;\r
+ highSum = 0;;\r
\r
for(j = 0; j < lowLen; j++) {\r
lowSum += LowTone[j]*GraphBuffer[i+j];\r
}\r
lowSum = abs((100*lowSum) / lowLen);\r
highSum = abs((100*highSum) / highLen);\r
+ lowSum = (lowSum<0)?-lowSum:lowSum;\r
+ highSum = (highSum<0)?-highSum:highSum;\r
+\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
+ lowTot = 0;\r
+ highTot = 0;\r
// 16 and 15 are f_s divided by f_l and f_h, rounded\r
for(j = 0; j < 16; j++) {\r
lowTot += (GraphBuffer[i+j] & 0xffff);\r
\r
RepaintGraphWindow();\r
\r
- // Okay, so now we have unsliced soft decisions; find bit-sync, and then\r
- // get some bits.\r
+ // TI tag data format is 16 prebits, 8 start bits, 64 data bits,\r
+ // 16 crc CCITT bits, 8 stop bits, 15 end bits\r
+\r
+ // the 16 prebits are always low\r
+ // the 8 start and stop bits of a tag must match\r
+ // the start/stop prebits of a ro tag are 01111110\r
+ // the start/stop prebits of a rw tag are 11111110\r
+ // the 15 end bits of a ro tag are all low\r
+ // the 15 end bits of a rw tag match bits 15-1 of the data bits\r
\r
+ // Okay, so now we have unsliced soft decisions;\r
+ // find bit-sync, and then get some bits.\r
+ // look for 17 low bits followed by 6 highs (common pattern for ro and rw tags)\r
int max = 0, maxPos = 0;\r
for(i = 0; i < 6000; i++) {\r
int j;\r
int dec = 0;\r
- for(j = 0; j < 8*arraylen(LowTone); j++) {\r
+ // searching 17 consecutive lows\r
+ for(j = 0; j < 17*lowLen; j++) {\r
dec -= GraphBuffer[i+j];\r
}\r
- for(; j < 8*arraylen(LowTone) + 8*arraylen(HighTone); j++) {\r
+ // searching 7 consecutive highs\r
+ for(; j < 17*lowLen + 6*highLen; j++) {\r
dec += GraphBuffer[i+j];\r
}\r
if(dec > max) {\r
maxPos = i;\r
}\r
}\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
\r
- maxPos += 8*arraylen(LowTone);\r
+ // place a marker in the buffer to visually aid location\r
+ // of the start of sync\r
GraphBuffer[maxPos] = 800;\r
GraphBuffer[maxPos+1] = -800;\r
- maxPos += 8*arraylen(HighTone);\r
\r
+ // advance pointer to start of actual data stream (after 16 pre and 8 start bits)\r
+ maxPos += 17*lowLen;\r
+ maxPos += 6*highLen;\r
+\r
+ // place a marker in the buffer to visually aid location\r
+ // of the end of sync\r
GraphBuffer[maxPos] = 800;\r
GraphBuffer[maxPos+1] = -800;\r
\r
PrintToScrollback("actual data bits start at sample %d", maxPos);\r
\r
- PrintToScrollback("length %d/%d", arraylen(HighTone), arraylen(LowTone));\r
-\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
+ PrintToScrollback("length %d/%d", highLen, lowLen);\r
\r
- BYTE bits[64+16+8+1];\r
+ BYTE bits[1+64+16+8+16];\r
bits[sizeof(bits)-1] = '\0';\r
\r
- for(i = 0; i < arraylen(bits); i++) {\r
+ DWORD shift3 = 0x7e000000, shift2 = 0, shift1 = 0, shift0 = 0;\r
+\r
+ for(i = 0; i < arraylen(bits)-1; i++) {\r
int high = 0;\r
int low = 0;\r
int j;\r
- for(j = 0; j < arraylen(LowTone); j++) {\r
+ for(j = 0; j < lowLen; j++) {\r
low -= GraphBuffer[maxPos+j];\r
}\r
- for(j = 0; j < arraylen(HighTone); j++) {\r
+ for(j = 0; j < highLen; j++) {\r
high += GraphBuffer[maxPos+j];\r
}\r
+\r
if(high > low) {\r
bits[i] = '1';\r
- maxPos += arraylen(HighTone);\r
+ maxPos += highLen;\r
+ // bitstream arrives lsb first so shift right\r
+ shift3 |= (1<<31);\r
} else {\r
bits[i] = '.';\r
- maxPos += arraylen(LowTone);\r
+ maxPos += lowLen;\r
}\r
+\r
+ // 128 bit right shift register\r
+ shift0 = (shift0>>1) | (shift1 << 31);\r
+ shift1 = (shift1>>1) | (shift2 << 31);\r
+ shift2 = (shift2>>1) | (shift3 << 31);\r
+ shift3 >>= 1;\r
+\r
+ // place a marker in the buffer between bits to visually aid location\r
GraphBuffer[maxPos] = 800;\r
GraphBuffer[maxPos+1] = -800;\r
}\r
- PrintToScrollback("bits: '%s'", bits);\r
+ PrintToScrollback("Info: raw tag bits = %s", bits);\r
\r
- DWORD h = 0, l = 0;\r
- for(i = 0; i < 32; i++) {\r
- if(bits[i] == '1') {\r
- l |= (1<<i);\r
- }\r
+ TagType = (shift3>>8)&0xff;\r
+ if ( TagType != ((shift0>>16)&0xff) ) {\r
+ PrintToScrollback("Error: start and stop bits do not match!");\r
+ return;\r
+ }\r
+ else if (TagType == 0x7e) {\r
+ PrintToScrollback("Info: Readonly TI tag detected.");\r
+ return;\r
}\r
- for(i = 32; i < 64; i++) {\r
- if(bits[i] == '1') {\r
- h |= (1<<(i-32));\r
+ else if (TagType == 0xfe) {\r
+ PrintToScrollback("Info: Rewriteable TI tag detected.");\r
+\r
+ // put 64 bit data into shift1 and shift0\r
+ shift0 = (shift0>>24) | (shift1 << 8);\r
+ shift1 = (shift1>>24) | (shift2 << 8);\r
+\r
+ // align 16 bit crc into lower half of shift2\r
+ shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;\r
+\r
+ // align 16 bit "end bits" or "ident" into lower half of shift3\r
+ shift3 >>= 16;\r
+\r
+ // only 15 bits compare, last bit of ident is not valid\r
+ if ( (shift3^shift0)&0x7fff ) {\r
+ PrintToScrollback("Error: Ident mismatch!");\r
+ }\r
+ // WARNING the order of the bytes in which we calc crc below needs checking\r
+ // i'm 99% sure the crc algorithm is correct, but it may need to eat the\r
+ // bytes in reverse or something\r
+ // calculate CRC\r
+ crc=0;\r
+ crc = update_crc16(crc, (shift0)&0xff);\r
+ crc = update_crc16(crc, (shift0>>8)&0xff);\r
+ crc = update_crc16(crc, (shift0>>16)&0xff);\r
+ crc = update_crc16(crc, (shift0>>24)&0xff);\r
+ crc = update_crc16(crc, (shift1)&0xff);\r
+ crc = update_crc16(crc, (shift1>>8)&0xff);\r
+ crc = update_crc16(crc, (shift1>>16)&0xff);\r
+ crc = update_crc16(crc, (shift1>>24)&0xff);\r
+ PrintToScrollback("Info: Tag data = %08X%08X", shift1, shift0);\r
+ if (crc != (shift2&0xffff)) {\r
+ PrintToScrollback("Error: CRC mismatch, calculated %04X, got ^04X", crc, shift2&0xffff);\r
+ } else {\r
+ PrintToScrollback("Info: CRC %04X is good", crc);\r
}\r
}\r
- PrintToScrollback("hex: %08x %08x", h, l);\r
+ else {\r
+ PrintToScrollback("Unknown tag type.");\r
+ return;\r
+ }\r
}\r
\r
static void CmdNorm(char *str)\r
RepaintGraphWindow();\r
}\r
\r
+static void CmdAmp(char *str)\r
+{\r
+ int i, rising, falling;\r
+ int max = INT_MIN, min = INT_MAX;\r
+ for(i = 10; i < GraphTraceLen; i++) {\r
+ if(GraphBuffer[i] > max) {\r
+ max = GraphBuffer[i];\r
+ }\r
+ if(GraphBuffer[i] < min) {\r
+ min = GraphBuffer[i];\r
+ }\r
+ }\r
+ if(max != min) {\r
+ rising= falling= 0;\r
+ for(i = 0; i < GraphTraceLen; i++) {\r
+ if(GraphBuffer[i+1] < GraphBuffer[i]) {\r
+ if(rising) {\r
+ GraphBuffer[i]= max;\r
+ rising= 0;\r
+ }\r
+ falling= 1;\r
+ }\r
+ if(GraphBuffer[i+1] > GraphBuffer[i]) {\r
+ if(falling) {\r
+ GraphBuffer[i]= min;\r
+ falling= 0;\r
+ }\r
+ rising= 1;\r
+ }\r
+ }\r
+ }\r
+ RepaintGraphWindow();\r
+}\r
+\r
static void CmdDec(char *str)\r
{\r
int i;\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
int c, high = 0, low = 0;\r
\r
// TODO: complain if we do not give 2 arguments here !\r
+ // (AL - this doesn't make sense! we're only using one argument!!!)\r
sscanf(str, "%i", &c);\r
\r
/* Detect high and lows and clock */\r
+ // (AL - clock???)\r
for (i = 0; i < GraphTraceLen; i++)\r
{\r
if (GraphBuffer[i] > high)\r
else if (GraphBuffer[i] < low)\r
low = GraphBuffer[i];\r
}\r
+ if(c != 0 && c != 1) {\r
+ PrintToScrollback("Invalid argument: %s",str);\r
+ return;\r
+ }\r
\r
if (GraphBuffer[0] > 0) {\r
GraphBuffer[0] = 1-c;\r
\r
/* Detect first transition */\r
/* Lo-Hi (arbitrary) */\r
- for (i = 0; i < GraphTraceLen; i++)\r
+ /* skip to the first high */\r
+ for (i= 0; i < GraphTraceLen; i++)\r
+ if(GraphBuffer[i] == high)\r
+ break;\r
+ /* now look for the first low */\r
+ for (; i < GraphTraceLen; i++)\r
{\r
if (GraphBuffer[i] == low)\r
{\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 CmdVersion(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_VERSION;\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 CmdSetMux(char *str)\r
+{\r
+ UsbCommand c;\r
+ c.cmd = CMD_SET_ADC_MUX;\r
+ if(strcmp(str, "lopkd") == 0) {\r
+ c.ext1 = 0;\r
+ } else if(strcmp(str, "loraw") == 0) {\r
+ c.ext1 = 1;\r
+ } else if(strcmp(str, "hipkd") == 0) {\r
+ c.ext1 = 2;\r
+ } else if(strcmp(str, "hiraw") == 0) {\r
+ c.ext1 = 3;\r
+ }\r
+ SendCommand(&c, FALSE);\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
- {"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"}, // ## 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 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,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
+ {"amp", CmdAmp, 1, "Amplify peaks"},\r
+ {"askdemod", Cmdaskdemod, 1, "<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, 1, "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
+ {"legicrfsim", CmdLegicRfSim, 0, "Start the LEGIC RF tag simulator"},\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
+ {"losimbidir", CmdLosimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and 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
+ {"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},\r
+ {"sri512read", CmdSri512read, 0, "<int> -- Read contents of a SRI512 tag"},\r
+ {"tidemod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag"},\r
+ {"tiread", CmdTIRead, 0, "Read and decode a TI 134 kHz tag"},\r
+ {"tiwrite", CmdTIWrite, 0, "Write new data to a r/w TI 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
+ {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"},\r
+ {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},\r
};\r
\r
static struct {\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
+ 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
+ PrintToScrollback("# Your HF antenna is unusable.");\r
else if (vHf<5000)\r
PrintToScrollback("# Your HF antenna is marginal.");\r
break;\r