+++ /dev/null
-//-----------------------------------------------------------------------------\r
-// The actual command interpeter for what the user types at the command line.\r
-// Jonathan Westhues, Sept 2005\r
-// Edits by Gerhard de Koning Gans, Sep 2007 (##)\r
-//-----------------------------------------------------------------------------\r
-#include <windows.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <stdio.h>\r
-#include <limits.h>\r
-#include <math.h>\r
-\r
-#include "prox.h"\r
-#include "../common/iso14443_crc.c"\r
-\r
-#define arraylen(x) (sizeof(x)/sizeof((x)[0]))\r
-#define BIT(x) GraphBuffer[x * clock]\r
-#define BITS (GraphTraceLen / clock)\r
-\r
-int go = 0;\r
-static int CmdHisamplest(char *str, int nrlow);\r
-\r
-static void GetFromBigBuf(BYTE *dest, int bytes)\r
-{\r
- int n = bytes/4;\r
-\r
- if(n % 48 != 0) {\r
- PrintToScrollback("bad len in GetFromBigBuf");\r
- return;\r
- }\r
-\r
- int i;\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
-\r
- memcpy(dest+(i*4), c.d.asBytes, 48);\r
- }\r
-}\r
-\r
-static void CmdReset(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_HARDWARE_RESET;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-\r
-static void CmdQuit(char *str)\r
-{\r
- exit(0);\r
-}\r
-\r
-static void CmdHIDdemodFSK(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_HID_DEMOD_FSK;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdTune(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_MEASURE_ANTENNA_TUNING;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi15read(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14read(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-\r
-/* New command to read the contents of a SRI512 tag\r
- * SRI512 tags are ISO14443-B modulated memory tags,\r
- * this command just dumps the contents of the memory/\r
- */\r
-static void CmdSri512read(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_READ_SRI512_TAG;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-// ## New command\r
-static void CmdHi14areader(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_READER_ISO_14443a;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-// ## New command\r
-static void CmdHi15reader(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_READER_ISO_15693;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-// ## New command\r
-static void CmdHi15tag(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SIMTAG_ISO_15693;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14read_sim(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14readt(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-\r
- //CmdHisamplest(str);\r
- while(CmdHisamplest(str,atoi(str))==0) {\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
- }\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdHisimlisten(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SIMULATE_TAG_HF_LISTEN;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14sim(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SIMULATE_TAG_ISO_14443;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14asim(char *str) // ## simulate iso14443a tag\r
-{ // ## greg - added ability to specify tag UID\r
-\r
- unsigned int hi=0, lo=0;\r
- int n=0, i=0;\r
- UsbCommand c;\r
-\r
- while (sscanf(&str[i++], "%1x", &n ) == 1) {\r
- hi=(hi<<4)|(lo>>28);\r
- lo=(lo<<4)|(n&0xf);\r
- }\r
-\r
- c.cmd = CMD_SIMULATE_TAG_ISO_14443a;\r
- // c.ext should be set to *str or convert *str to the correct format for a uid\r
- c.ext1 = hi;\r
- c.ext2 = lo;\r
- PrintToScrollback("Emulating 14443A TAG with UID %x%16x", hi, lo);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14snoop(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SNOOP_ISO_14443;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdHi14asnoop(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SNOOP_ISO_14443a;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdFPGAOff(char *str) // ## FPGA Control\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_FPGA_MAJOR_MODE_OFF;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-/* clear out our graph window */\r
-int CmdClearGraph(int redraw)\r
-{\r
- int gtl = GraphTraceLen;\r
- GraphTraceLen = 0;\r
-\r
- if (redraw)\r
- RepaintGraphWindow();\r
-\r
- return gtl;\r
-}\r
-\r
-/* write a bit to the graph */\r
-static void CmdAppendGraph(int redraw, int clock, int bit)\r
-{\r
- int i;\r
-\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
- GraphBuffer[GraphTraceLen++] = bit;\r
-\r
- if (redraw)\r
- RepaintGraphWindow();\r
-}\r
-\r
-/* Function is equivalent of loread + losamples + em410xread\r
- * looped until an EM410x tag is detected */\r
-static void CmdEM410xwatch(char *str)\r
-{\r
- char *zero = "";\r
- char *twok = "2000";\r
- go = 1;\r
-\r
- do\r
- {\r
- CmdLoread(zero);\r
- CmdLosamples(twok);\r
- CmdEM410xread(zero);\r
- } while (go);\r
-}\r
-\r
-/* Read the ID of an EM410x tag.\r
- * Format:\r
- * 1111 1111 1 <-- standard non-repeatable header\r
- * XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID\r
- * ....\r
- * CCCC <-- each bit here is parity for the 10 bits above in corresponding column\r
- * 0 <-- stop bit, end of tag\r
- */\r
-static void CmdEM410xread(char *str)\r
-{\r
- int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;\r
- int parity[4];\r
- char id[11];\r
- int BitStream[MAX_GRAPH_TRACE_LEN];\r
- high = low = 0;\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
- /* get clock */\r
- clock = GetClock(str, high);\r
-\r
- /* parity for our 4 columns */\r
- parity[0] = parity[1] = parity[2] = parity[3] = 0;\r
- header = rows = 0;\r
-\r
- /* manchester demodulate */\r
- bit = bit2idx = 0;\r
- for (i = 0; i < (int)(GraphTraceLen / clock); i++)\r
- {\r
- hithigh = 0;\r
- hitlow = 0;\r
- first = 1;\r
-\r
- /* Find out if we hit both high and low peaks */\r
- for (j = 0; j < clock; j++)\r
- {\r
- if (GraphBuffer[(i * clock) + j] == high)\r
- hithigh = 1;\r
- else if (GraphBuffer[(i * clock) + j] == low)\r
- hitlow = 1;\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
- if (hithigh && hitlow)\r
- break;\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
- BitStream[bit2idx++] = bit;\r
- }\r
-\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
- /* Step 2: We have our header but need our tag ID */\r
- if (header == 9 && rows < 10)\r
- {\r
- /* Confirm parity is correct */\r
- if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])\r
- {\r
- /* 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
- /* 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
- /* Move 4 bits ahead */\r
- i += 4;\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
- /* 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
- /* Step 3: Got our 40 bits! confirm column parity */\r
- else if (rows == 10)\r
- {\r
- /* We need to make sure our 4 bits of parity are correct and we have a stop bit */\r
- if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&\r
- BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&\r
- BitStream[i+4] == 0)\r
- {\r
- /* Sweet! */\r
- PrintToScrollback("EM410x Tag ID: %s", id);\r
-\r
- /* Stop any loops */\r
- go = 0;\r
- break;\r
- }\r
-\r
- /* Crap! Incorrect parity or no stop bit, start all over */\r
- else\r
- {\r
- rows = header = 0;\r
-\r
- /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */\r
- i -= 59;\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
- /* We don't have a header, not enough consecutive 1 bits */\r
- else\r
- header = 0;\r
- }\r
- }\r
-}\r
-\r
-/* emulate an EM410X tag\r
- * Format:\r
- * 1111 1111 1 <-- standard non-repeatable header\r
- * XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID\r
- * ....\r
- * CCCC <-- each bit here is parity for the 10 bits above in corresponding column\r
- * 0 <-- stop bit, end of tag\r
- */\r
-static void CmdEM410xsim(char *str)\r
-{\r
- int i, n, j, h, binary[4], parity[4];\r
- char *s = "0";\r
-\r
- /* clock is 64 in EM410x tags */\r
- int clock = 64;\r
-\r
- /* clear our graph */\r
- CmdClearGraph(0);\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
- /* for each hex char */\r
- parity[0] = parity[1] = parity[2] = parity[3] = 0;\r
- for (i = 0; i < 10; i++)\r
- {\r
- /* read each hex char */\r
- sscanf(&str[i], "%1x", &n);\r
- for (j = 3; j >= 0; j--, n/= 2)\r
- binary[j] = n % 2;\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
- /* append parity bit */\r
- CmdAppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);\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
- /* 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
- /* stop bit */\r
- CmdAppendGraph(0, clock, 0);\r
- }\r
-\r
- /* modulate that biatch */\r
- Cmdmanchestermod(s);\r
-\r
- /* booyah! */\r
- RepaintGraphWindow();\r
-\r
- CmdLosim(s);\r
-}\r
-\r
-static void ChkBitstream(char *str)\r
-{\r
- int i;\r
-\r
- /* convert to bitstream if necessary */\r
- for (i = 0; i < (int)(GraphTraceLen / 2); i++)\r
- {\r
- if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0)\r
- {\r
- Cmdbitstream(str);\r
- break;\r
- }\r
- }\r
-}\r
-\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
- for (i = 0; i < GraphTraceLen; i += 48) {\r
- UsbCommand c;\r
- int j;\r
- for(j = 0; j < 48; j++) {\r
- c.d.asBytes[j] = GraphBuffer[i+j];\r
- }\r
- c.cmd = CMD_DOWNLOADED_SIM_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- }\r
-\r
- UsbCommand c;\r
- c.cmd = CMD_SIMULATE_TAG_125K;\r
- c.ext1 = GraphTraceLen;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdLoread(char *str)\r
-{\r
- UsbCommand c;\r
- // 'h' means higher-low-frequency, 134 kHz\r
- if(*str == 'h') {\r
- c.ext1 = 1;\r
- } else if (*str == '\0') {\r
- c.ext1 = 0;\r
- } else {\r
- PrintToScrollback("use 'loread' or 'loread h'");\r
- return;\r
- }\r
- c.cmd = CMD_ACQUIRE_RAW_ADC_SAMPLES_125K;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdLosamples(char *str)\r
-{\r
- int cnt = 0;\r
- int i;\r
- int n;\r
-\r
- n=atoi(str);\r
- if (n==0) n=128;\r
- if (n>16000) n=16000;\r
-\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- if (!go)\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
- int j;\r
- for(j = 0; j < 48; j++) {\r
- GraphBuffer[cnt++] = ((int)c.d.asBytes[j]) - 128;\r
- }\r
- }\r
- GraphTraceLen = n*4;\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdBitsamples(char *str)\r
-{\r
- int cnt = 0;\r
- int i;\r
- int n;\r
-\r
- n = 3072;\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
- int j, k;\r
- for(j = 0; j < 48; j++) {\r
- for(k = 0; k < 8; k++) {\r
- if(c.d.asBytes[j] & (1 << (7 - k))) {\r
- GraphBuffer[cnt++] = 1;\r
- } else {\r
- GraphBuffer[cnt++] = 0;\r
- }\r
- }\r
- }\r
- }\r
- GraphTraceLen = cnt;\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdHisamples(char *str)\r
-{\r
- int cnt = 0;\r
- int i;\r
- int n;\r
- n = 1000;\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
- int j;\r
- for(j = 0; j < 48; j++) {\r
- GraphBuffer[cnt++] = (int)((BYTE)c.d.asBytes[j]);\r
- }\r
- }\r
- GraphTraceLen = n*4;\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-\r
-static int CmdHisamplest(char *str, int nrlow)\r
-{\r
- int cnt = 0;\r
- int t1, t2;\r
- int i;\r
- int n;\r
- int hasbeennull;\r
- int show;\r
-\r
-\r
- n = 1000;\r
- hasbeennull = 0;\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return 0;\r
- }\r
- int j;\r
- for(j = 0; j < 48; j++) {\r
- t2 = (int)((BYTE)c.d.asBytes[j]);\r
- if((t2 ^ 0xC0) & 0xC0) { hasbeennull++; }\r
-\r
- show = 0;\r
- switch(show) {\r
- case 0:\r
- // combined\r
- t1 = (t2 & 0x80) ^ (t2 & 0x20);\r
- t2 = ((t2 << 1) & 0x80) ^ ((t2 << 1) & 0x20);\r
- break;\r
-\r
- case 1:\r
- // only reader\r
- t1 = (t2 & 0x80);\r
- t2 = ((t2 << 1) & 0x80);\r
- break;\r
-\r
- case 2:\r
- // only tag\r
- t1 = (t2 & 0x20);\r
- t2 = ((t2 << 1) & 0x20);\r
- break;\r
-\r
- case 3:\r
- // both, but tag with other algorithm\r
- t1 = (t2 & 0x80) ^ (t2 & 0x08);\r
- t2 = ((t2 << 1) & 0x80) ^ ((t2 << 1) & 0x08);\r
- break;\r
- }\r
-\r
- GraphBuffer[cnt++] = t1;\r
- GraphBuffer[cnt++] = t2;\r
- }\r
- }\r
- GraphTraceLen = n*4;\r
-// 1130\r
- if(hasbeennull>nrlow || nrlow==0) {\r
- PrintToScrollback("hasbeennull=%d", hasbeennull);\r
- return 1;\r
- }\r
- else {\r
- return 0;\r
- }\r
-}\r
-\r
-\r
-static void CmdHexsamples(char *str)\r
-{\r
- int i;\r
- int n;\r
-\r
- if(atoi(str) == 0) {\r
- n = 12;\r
- } else {\r
- n = atoi(str)/4;\r
- }\r
-\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
- int j;\r
- for(j = 0; j < 48; j += 8) {\r
- PrintToScrollback("%02x %02x %02x %02x %02x %02x %02x %02x",\r
- c.d.asBytes[j+0],\r
- c.d.asBytes[j+1],\r
- c.d.asBytes[j+2],\r
- c.d.asBytes[j+3],\r
- c.d.asBytes[j+4],\r
- c.d.asBytes[j+5],\r
- c.d.asBytes[j+6],\r
- c.d.asBytes[j+7],\r
- c.d.asBytes[j+8]\r
- );\r
- }\r
- }\r
-}\r
-\r
-static void CmdHisampless(char *str)\r
-{\r
- int cnt = 0;\r
- int i;\r
- int n;\r
-\r
- if(atoi(str) == 0) {\r
- n = 1000;\r
- } else {\r
- n = atoi(str)/4;\r
- }\r
-\r
- for(i = 0; i < n; i += 12) {\r
- UsbCommand c;\r
- c.cmd = CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K;\r
- c.ext1 = i;\r
- SendCommand(&c, FALSE);\r
- ReceiveCommand(&c);\r
- if(c.cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {\r
- PrintToScrollback("bad resp");\r
- return;\r
- }\r
- int j;\r
- for(j = 0; j < 48; j++) {\r
- GraphBuffer[cnt++] = (int)((signed char)c.d.asBytes[j]);\r
- }\r
- }\r
- GraphTraceLen = cnt;\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static WORD Iso15693Crc(BYTE *v, int n)\r
-{\r
- DWORD reg;\r
- int i, j;\r
-\r
- reg = 0xffff;\r
- for(i = 0; i < n; i++) {\r
- reg = reg ^ ((DWORD)v[i]);\r
- for (j = 0; j < 8; j++) {\r
- if (reg & 0x0001) {\r
- reg = (reg >> 1) ^ 0x8408;\r
- } else {\r
- reg = (reg >> 1);\r
- }\r
- }\r
- }\r
-\r
- return (WORD)~reg;\r
-}\r
-\r
-static void CmdHi14bdemod(char *str)\r
-{\r
- int i, j, iold;\r
- int isum, qsum;\r
- int outOfWeakAt;\r
- BOOL negateI, negateQ;\r
-\r
- BYTE data[256];\r
- int dataLen=0;\r
-\r
- // As received, the samples are pairs, correlations against I and Q\r
- // square waves. So estimate angle of initial carrier (or just\r
- // quadrant, actually), and then do the demod.\r
-\r
- // First, estimate where the tag starts modulating.\r
- for(i = 0; i < GraphTraceLen; i += 2) {\r
- if(abs(GraphBuffer[i]) + abs(GraphBuffer[i+1]) > 40) {\r
- break;\r
- }\r
- }\r
- if(i >= GraphTraceLen) {\r
- PrintToScrollback("too weak to sync");\r
- return;\r
- }\r
- PrintToScrollback("out of weak at %d", i);\r
- outOfWeakAt = i;\r
-\r
- // Now, estimate the phase in the initial modulation of the tag\r
- isum = 0;\r
- qsum = 0;\r
- for(; i < (outOfWeakAt + 16); i += 2) {\r
- isum += GraphBuffer[i+0];\r
- qsum += GraphBuffer[i+1];\r
- }\r
- negateI = (isum < 0);\r
- negateQ = (qsum < 0);\r
-\r
- // Turn the correlation pairs into soft decisions on the bit.\r
- j = 0;\r
- for(i = 0; i < GraphTraceLen/2; i++) {\r
- int si = GraphBuffer[j];\r
- int sq = GraphBuffer[j+1];\r
- if(negateI) si = -si;\r
- if(negateQ) sq = -sq;\r
- GraphBuffer[i] = si + sq;\r
- j += 2;\r
- }\r
- GraphTraceLen = i;\r
-\r
- i = outOfWeakAt/2;\r
- while(GraphBuffer[i] > 0 && i < GraphTraceLen)\r
- i++;\r
- if(i >= GraphTraceLen) goto demodError;\r
-\r
- iold = i;\r
- while(GraphBuffer[i] < 0 && i < GraphTraceLen)\r
- i++;\r
- if(i >= GraphTraceLen) goto demodError;\r
- if((i - iold) > 23) goto demodError;\r
-\r
- PrintToScrollback("make it to demod loop");\r
-\r
- for(;;) {\r
- iold = i;\r
- while(GraphBuffer[i] >= 0 && i < GraphTraceLen)\r
- i++;\r
- if(i >= GraphTraceLen) goto demodError;\r
- if((i - iold) > 6) goto demodError;\r
-\r
- WORD shiftReg = 0;\r
- if(i + 20 >= GraphTraceLen) goto demodError;\r
-\r
- for(j = 0; j < 10; j++) {\r
- int soft = GraphBuffer[i] + GraphBuffer[i+1];\r
-\r
- if(abs(soft) < ((abs(isum) + abs(qsum))/20)) {\r
- PrintToScrollback("weak bit");\r
- }\r
-\r
- shiftReg >>= 1;\r
- if(GraphBuffer[i] + GraphBuffer[i+1] >= 0) {\r
- shiftReg |= 0x200;\r
- }\r
-\r
- i+= 2;\r
- }\r
-\r
- if( (shiftReg & 0x200) &&\r
- !(shiftReg & 0x001))\r
- {\r
- // valid data byte, start and stop bits okay\r
- PrintToScrollback(" %02x", (shiftReg >> 1) & 0xff);\r
- data[dataLen++] = (shiftReg >> 1) & 0xff;\r
- if(dataLen >= sizeof(data)) {\r
- return;\r
- }\r
- } else if(shiftReg == 0x000) {\r
- // this is EOF\r
- break;\r
- } else {\r
- goto demodError;\r
- }\r
- }\r
-\r
- BYTE first, second;\r
- ComputeCrc14443(CRC_14443_B, data, dataLen-2, &first, &second);\r
- PrintToScrollback("CRC: %02x %02x (%s)\n", first, second,\r
- (first == data[dataLen-2] && second == data[dataLen-1]) ?\r
- "ok" : "****FAIL****");\r
-\r
- RepaintGraphWindow();\r
- return;\r
-\r
-demodError:\r
- PrintToScrollback("demod error");\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdHi14list(char *str)\r
-{\r
- BYTE got[960];\r
- GetFromBigBuf(got, sizeof(got));\r
-\r
- PrintToScrollback("recorded activity:");\r
- PrintToScrollback(" time :rssi: who bytes");\r
- PrintToScrollback("---------+----+----+-----------");\r
-\r
- int i = 0;\r
- int prev = -1;\r
-\r
- for(;;) {\r
- if(i >= 900) {\r
- break;\r
- }\r
-\r
- BOOL isResponse;\r
- int timestamp = *((DWORD *)(got+i));\r
- if(timestamp & 0x80000000) {\r
- timestamp &= 0x7fffffff;\r
- isResponse = 1;\r
- } else {\r
- isResponse = 0;\r
- }\r
- int metric = *((DWORD *)(got+i+4));\r
-\r
- int len = got[i+8];\r
-\r
- if(len > 100) {\r
- break;\r
- }\r
- if(i + len >= 900) {\r
- break;\r
- }\r
-\r
- BYTE *frame = (got+i+9);\r
-\r
- char line[1000] = "";\r
- int j;\r
- for(j = 0; j < len; j++) {\r
- sprintf(line+(j*3), "%02x ", frame[j]);\r
- }\r
-\r
- char *crc;\r
- if(len > 2) {\r
- BYTE b1, b2;\r
- ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);\r
- if(b1 != frame[len-2] || b2 != frame[len-1]) {\r
- crc = "**FAIL CRC**";\r
- } else {\r
- crc = "";\r
- }\r
- } else {\r
- crc = "(SHORT)";\r
- }\r
-\r
- char metricString[100];\r
- if(isResponse) {\r
- sprintf(metricString, "%3d", metric);\r
- } else {\r
- strcpy(metricString, " ");\r
- }\r
-\r
- PrintToScrollback(" +%7d: %s: %s %s %s",\r
- (prev < 0 ? 0 : timestamp - prev),\r
- metricString,\r
- (isResponse ? "TAG" : " "), line, crc);\r
-\r
- prev = timestamp;\r
- i += (len + 9);\r
- }\r
-}\r
-\r
-static void CmdHi14alist(char *str)\r
-{\r
- BYTE got[1920];\r
- GetFromBigBuf(got, sizeof(got));\r
-\r
- PrintToScrollback("recorded activity:");\r
- PrintToScrollback(" ETU :rssi: who bytes");\r
- PrintToScrollback("---------+----+----+-----------");\r
-\r
- int i = 0;\r
- int prev = -1;\r
-\r
- for(;;) {\r
- if(i >= 1900) {\r
- break;\r
- }\r
-\r
- BOOL isResponse;\r
- int timestamp = *((DWORD *)(got+i));\r
- if(timestamp & 0x80000000) {\r
- timestamp &= 0x7fffffff;\r
- isResponse = 1;\r
- } else {\r
- isResponse = 0;\r
- }\r
-\r
- int metric = 0;\r
- int parityBits = *((DWORD *)(got+i+4));\r
- // 4 bytes of additional information...\r
- // maximum of 32 additional parity bit information\r
- //\r
- // TODO:\r
- // at each quarter bit period we can send power level (16 levels)\r
- // or each half bit period in 256 levels.\r
-\r
-\r
- int len = got[i+8];\r
-\r
- if(len > 100) {\r
- break;\r
- }\r
- if(i + len >= 1900) {\r
- break;\r
- }\r
-\r
- BYTE *frame = (got+i+9);\r
-\r
- // Break and stick with current result if buffer was not completely full\r
- if(frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }\r
-\r
- char line[1000] = "";\r
- int j;\r
- for(j = 0; j < len; j++) {\r
- int oddparity = 0x01;\r
- int k;\r
-\r
- for(k=0;k<8;k++) {\r
- oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);\r
- }\r
-\r
- //if((parityBits >> (len - j - 1)) & 0x01) {\r
- if(isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {\r
- sprintf(line+(j*4), "%02x! ", frame[j]);\r
- }\r
- else {\r
- sprintf(line+(j*4), "%02x ", frame[j]);\r
- }\r
- }\r
-\r
- char *crc;\r
- crc = "";\r
- if(len > 2) {\r
- BYTE b1, b2;\r
- for(j = 0; j < (len - 1); j++) {\r
- // gives problems... search for the reason..\r
- /*if(frame[j] == 0xAA) {\r
- switch(frame[j+1]) {\r
- case 0x01:\r
- crc = "[1] Two drops close after each other";\r
- break;\r
- case 0x02:\r
- crc = "[2] Potential SOC with a drop in second half of bitperiod";\r
- break;\r
- case 0x03:\r
- crc = "[3] Segment Z after segment X is not possible";\r
- break;\r
- case 0x04:\r
- crc = "[4] Parity bit of a fully received byte was wrong";\r
- break;\r
- default:\r
- crc = "[?] Unknown error";\r
- break;\r
- }\r
- break;\r
- }*/\r
- }\r
-\r
- if(strlen(crc)==0) {\r
- ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);\r
- if(b1 != frame[len-2] || b2 != frame[len-1]) {\r
- crc = (isResponse & (len < 6)) ? "" : " !crc";\r
- } else {\r
- crc = "";\r
- }\r
- }\r
- } else {\r
- crc = ""; // SHORT\r
- }\r
-\r
- char metricString[100];\r
- if(isResponse) {\r
- sprintf(metricString, "%3d", metric);\r
- } else {\r
- strcpy(metricString, " ");\r
- }\r
-\r
- PrintToScrollback(" +%7d: %s: %s %s %s",\r
- (prev < 0 ? 0 : (timestamp - prev)),\r
- metricString,\r
- (isResponse ? "TAG" : " "), line, crc);\r
-\r
- prev = timestamp;\r
- i += (len + 9);\r
- }\r
- CommandFinished = 1;\r
-}\r
-\r
-static void CmdHi15demod(char *str)\r
-{\r
- // The sampling rate is 106.353 ksps/s, for T = 18.8 us\r
-\r
- // SOF defined as\r
- // 1) Unmodulated time of 56.64us\r
- // 2) 24 pulses of 423.75khz\r
- // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)\r
-\r
- static const int FrameSOF[] = {\r
- -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,\r
- 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,\r
- -1, -1, -1, -1,\r
- -1, -1, -1, -1,\r
- 1, 1, 1, 1,\r
- 1, 1, 1, 1\r
- };\r
- static const int Logic0[] = {\r
- 1, 1, 1, 1,\r
- 1, 1, 1, 1,\r
- -1, -1, -1, -1,\r
- -1, -1, -1, -1\r
- };\r
- static const int Logic1[] = {\r
- -1, -1, -1, -1,\r
- -1, -1, -1, -1,\r
- 1, 1, 1, 1,\r
- 1, 1, 1, 1\r
- };\r
-\r
- // EOF defined as\r
- // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)\r
- // 2) 24 pulses of 423.75khz\r
- // 3) Unmodulated time of 56.64us\r
-\r
- static const int FrameEOF[] = {\r
- 1, 1, 1, 1,\r
- 1, 1, 1, 1,\r
- -1, -1, -1, -1,\r
- -1, -1, -1, -1,\r
- 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,\r
- -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\r
- };\r
-\r
- int i, j;\r
- int max = 0, maxPos;\r
-\r
- int skip = 4;\r
-\r
- if(GraphTraceLen < 1000) return;\r
-\r
- // First, correlate for SOF\r
- for(i = 0; i < 100; i++) {\r
- int corr = 0;\r
- for(j = 0; j < arraylen(FrameSOF); j += skip) {\r
- corr += FrameSOF[j]*GraphBuffer[i+(j/skip)];\r
- }\r
- if(corr > max) {\r
- max = corr;\r
- maxPos = i;\r
- }\r
- }\r
- PrintToScrollback("SOF at %d, correlation %d", maxPos,\r
- max/(arraylen(FrameSOF)/skip));\r
-\r
- i = maxPos + arraylen(FrameSOF)/skip;\r
- int k = 0;\r
- BYTE outBuf[20];\r
- memset(outBuf, 0, sizeof(outBuf));\r
- BYTE mask = 0x01;\r
- for(;;) {\r
- int corr0 = 0, corr1 = 0, corrEOF = 0;\r
- for(j = 0; j < arraylen(Logic0); j += skip) {\r
- corr0 += Logic0[j]*GraphBuffer[i+(j/skip)];\r
- }\r
- for(j = 0; j < arraylen(Logic1); j += skip) {\r
- corr1 += Logic1[j]*GraphBuffer[i+(j/skip)];\r
- }\r
- for(j = 0; j < arraylen(FrameEOF); j += skip) {\r
- corrEOF += FrameEOF[j]*GraphBuffer[i+(j/skip)];\r
- }\r
- // Even things out by the length of the target waveform.\r
- corr0 *= 4;\r
- corr1 *= 4;\r
-\r
- if(corrEOF > corr1 && corrEOF > corr0) {\r
- PrintToScrollback("EOF at %d", i);\r
- break;\r
- } else if(corr1 > corr0) {\r
- i += arraylen(Logic1)/skip;\r
- outBuf[k] |= mask;\r
- } else {\r
- i += arraylen(Logic0)/skip;\r
- }\r
- mask <<= 1;\r
- if(mask == 0) {\r
- k++;\r
- mask = 0x01;\r
- }\r
- if((i+(int)arraylen(FrameEOF)) >= GraphTraceLen) {\r
- PrintToScrollback("ran off end!");\r
- break;\r
- }\r
- }\r
- if(mask != 0x01) {\r
- PrintToScrollback("error, uneven octet! (discard extra bits!)");\r
- PrintToScrollback(" mask=%02x", mask);\r
- }\r
- PrintToScrollback("%d octets", k);\r
-\r
- for(i = 0; i < k; i++) {\r
- PrintToScrollback("# %2d: %02x ", i, outBuf[i]);\r
- }\r
- PrintToScrollback("CRC=%04x", Iso15693Crc(outBuf, k-2));\r
-}\r
-\r
-static void CmdTiread(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_ACQUIRE_RAW_BITS_TI_TYPE;\r
- SendCommand(&c, FALSE);\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
- }\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
- }\r
- }\r
- GraphTraceLen = 1536*32;\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdTidemod(char *cmdline)\r
-{\r
- /* MATLAB as follows:\r
-f_s = 2000000; % sampling frequency\r
-f_l = 123200; % low FSK tone\r
-f_h = 134200; % high FSK tone\r
-\r
-T_l = 119e-6; % low bit duration\r
-T_h = 130e-6; % high bit duration\r
-\r
-l = 2*pi*ones(1, floor(f_s*T_l))*(f_l/f_s);\r
-h = 2*pi*ones(1, floor(f_s*T_h))*(f_h/f_s);\r
-\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
-\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
-\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
- // 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
- for(j = 0; j < 15; j++) {\r
- highTot += (GraphBuffer[i+j] >> 16);\r
- }\r
- GraphBuffer[i] = lowTot - highTot;\r
- }\r
-\r
- GraphTraceLen -= (convLen + 16);\r
-\r
- RepaintGraphWindow();\r
-\r
- // Okay, so now we have unsliced soft decisions; find bit-sync, and then\r
- // get some bits.\r
-\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
- dec -= GraphBuffer[i+j];\r
- }\r
- for(; j < 8*arraylen(LowTone) + 8*arraylen(HighTone); j++) {\r
- dec += GraphBuffer[i+j];\r
- }\r
- if(dec > max) {\r
- max = dec;\r
- maxPos = i;\r
- }\r
- }\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
-\r
- maxPos += 8*arraylen(LowTone);\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
- maxPos += 8*arraylen(HighTone);\r
-\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
-\r
- BYTE bits[64+16+8+1];\r
- bits[sizeof(bits)-1] = '\0';\r
-\r
- for(i = 0; i < arraylen(bits); i++) {\r
- int high = 0;\r
- int low = 0;\r
- int j;\r
- for(j = 0; j < arraylen(LowTone); j++) {\r
- low -= GraphBuffer[maxPos+j];\r
- }\r
- for(j = 0; j < arraylen(HighTone); j++) {\r
- high += GraphBuffer[maxPos+j];\r
- }\r
- if(high > low) {\r
- bits[i] = '1';\r
- maxPos += arraylen(HighTone);\r
- } else {\r
- bits[i] = '.';\r
- maxPos += arraylen(LowTone);\r
- }\r
- GraphBuffer[maxPos] = 800;\r
- GraphBuffer[maxPos+1] = -800;\r
- }\r
- PrintToScrollback("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
- }\r
- for(i = 32; i < 64; i++) {\r
- if(bits[i] == '1') {\r
- h |= (1<<(i-32));\r
- }\r
- }\r
- PrintToScrollback("hex: %08x %08x", h, l);\r
-}\r
-\r
-static void CmdNorm(char *str)\r
-{\r
- int i;\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
- for(i = 0; i < GraphTraceLen; i++) {\r
- GraphBuffer[i] = (GraphBuffer[i] - ((max + min)/2))*1000/\r
- (max - min);\r
- }\r
- }\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdDec(char *str)\r
-{\r
- int i;\r
- for(i = 0; i < (GraphTraceLen/2); i++) {\r
- GraphBuffer[i] = GraphBuffer[i*2];\r
- }\r
- GraphTraceLen /= 2;\r
- PrintToScrollback("decimated by 2");\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdHpf(char *str)\r
-{\r
- int i;\r
- int accum = 0;\r
- for(i = 10; i < GraphTraceLen; i++) {\r
- accum += GraphBuffer[i];\r
- }\r
- accum /= (GraphTraceLen - 10);\r
- for(i = 0; i < GraphTraceLen; i++) {\r
- GraphBuffer[i] -= accum;\r
- }\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdZerocrossings(char *str)\r
-{\r
- int i;\r
- // Zero-crossings aren't meaningful unless the signal is zero-mean.\r
- CmdHpf("");\r
-\r
- int sign = 1;\r
- int zc = 0;\r
- int lastZc = 0;\r
- for(i = 0; i < GraphTraceLen; i++) {\r
- if(GraphBuffer[i]*sign >= 0) {\r
- // No change in sign, reproduce the previous sample count.\r
- zc++;\r
- GraphBuffer[i] = lastZc;\r
- } else {\r
- // Change in sign, reset the sample count.\r
- sign = -sign;\r
- GraphBuffer[i] = lastZc;\r
- if(sign > 0) {\r
- lastZc = zc;\r
- zc = 0;\r
- }\r
- }\r
- }\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdLtrim(char *str)\r
-{\r
- int i;\r
- int ds = atoi(str);\r
-\r
- for(i = ds; i < GraphTraceLen; i++) {\r
- GraphBuffer[i-ds] = GraphBuffer[i];\r
- }\r
- GraphTraceLen -= ds;\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdAutoCorr(char *str)\r
-{\r
- static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];\r
-\r
- int window = atoi(str);\r
-\r
- if(window == 0) {\r
- PrintToScrollback("needs a window");\r
- return;\r
- }\r
-\r
- if(window >= GraphTraceLen) {\r
- PrintToScrollback("window must be smaller than trace (%d samples)",\r
- GraphTraceLen);\r
- return;\r
- }\r
-\r
- PrintToScrollback("performing %d correlations", GraphTraceLen - window);\r
-\r
- int i;\r
- for(i = 0; i < GraphTraceLen - window; i++) {\r
- int sum = 0;\r
- int j;\r
- for(j = 0; j < window; j++) {\r
- sum += (GraphBuffer[j]*GraphBuffer[i+j]) / 256;\r
- }\r
- CorrelBuffer[i] = sum;\r
- }\r
- GraphTraceLen = GraphTraceLen - window;\r
- memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen*sizeof(int));\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdVchdemod(char *str)\r
-{\r
- // Is this the entire sync pattern, or does this also include some\r
- // data bits that happen to be the same everywhere? That would be\r
- // lovely to know.\r
- static const int SyncPattern[] = {\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,\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,\r
- };\r
-\r
- // So first, we correlate for the sync pattern, and mark that.\r
- int bestCorrel = 0, bestPos = 0;\r
- int i;\r
- // It does us no good to find the sync pattern, with fewer than\r
- // 2048 samples after it...\r
- for(i = 0; i < (GraphTraceLen-2048); i++) {\r
- int sum = 0;\r
- int j;\r
- for(j = 0; j < arraylen(SyncPattern); j++) {\r
- sum += GraphBuffer[i+j]*SyncPattern[j];\r
- }\r
- if(sum > bestCorrel) {\r
- bestCorrel = sum;\r
- bestPos = i;\r
- }\r
- }\r
- PrintToScrollback("best sync at %d [metric %d]", bestPos, bestCorrel);\r
-\r
- char bits[257];\r
- bits[256] = '\0';\r
-\r
- int worst = INT_MAX;\r
- int worstPos;\r
-\r
- for(i = 0; i < 2048; i += 8) {\r
- int sum = 0;\r
- int j;\r
- for(j = 0; j < 8; j++) {\r
- sum += GraphBuffer[bestPos+i+j];\r
- }\r
- if(sum < 0) {\r
- bits[i/8] = '.';\r
- } else {\r
- bits[i/8] = '1';\r
- }\r
- if(abs(sum) < worst) {\r
- worst = abs(sum);\r
- worstPos = i;\r
- }\r
- }\r
- PrintToScrollback("bits:");\r
- PrintToScrollback("%s", bits);\r
- PrintToScrollback("worst metric: %d at pos %d", worst, worstPos);\r
-\r
- if(strcmp(str, "clone")==0) {\r
- GraphTraceLen = 0;\r
- char *s;\r
- for(s = bits; *s; s++) {\r
- int j;\r
- for(j = 0; j < 16; j++) {\r
- GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0;\r
- }\r
- }\r
- RepaintGraphWindow();\r
- }\r
-}\r
-\r
-static void CmdIndalademod(char *str)\r
-{\r
- // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID\r
-\r
- int state = -1;\r
- int count = 0;\r
- int i, j;\r
- // worst case with GraphTraceLen=64000 is < 4096\r
- // under normal conditions it's < 2048\r
- BYTE rawbits[4096];\r
- int rawbit = 0;\r
- int worst = 0, worstPos = 0;\r
- PrintToScrollback("Expecting a bit less than %d raw bits", GraphTraceLen/32);\r
- for(i = 0; i < GraphTraceLen-1; i += 2) {\r
- count+=1;\r
- if((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {\r
- if (state == 0) {\r
- for(j = 0; j < count - 8; j += 16) {\r
- rawbits[rawbit++] = 0;\r
- }\r
- if ((abs(count - j)) > worst) {\r
- worst = abs(count - j);\r
- worstPos = i;\r
- }\r
- }\r
- state = 1;\r
- count=0;\r
- } else if((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {\r
- if (state == 1) {\r
- for(j = 0; j < count - 8; j += 16) {\r
- rawbits[rawbit++] = 1;\r
- }\r
- if ((abs(count - j)) > worst) {\r
- worst = abs(count - j);\r
- worstPos = i;\r
- }\r
- }\r
- state = 0;\r
- count=0;\r
- }\r
- }\r
- PrintToScrollback("Recovered %d raw bits", rawbit);\r
- PrintToScrollback("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);\r
-\r
- // Finding the start of a UID\r
- int uidlen, long_wait;\r
- if(strcmp(str, "224") == 0) {\r
- uidlen=224;\r
- long_wait=30;\r
- } else {\r
- uidlen=64;\r
- long_wait=29;\r
- }\r
- int start;\r
- int first = 0;\r
- for(start = 0; start <= rawbit - uidlen; start++) {\r
- first = rawbits[start];\r
- for(i = start; i < start + long_wait; i++) {\r
- if(rawbits[i] != first) {\r
- break;\r
- }\r
- }\r
- if(i == (start + long_wait)) {\r
- break;\r
- }\r
- }\r
- if(start == rawbit - uidlen + 1) {\r
- PrintToScrollback("nothing to wait for");\r
- return;\r
- }\r
-\r
- // Inverting signal if needed\r
- if(first == 1) {\r
- for(i = start; i < rawbit; i++) {\r
- rawbits[i] = !rawbits[i];\r
- }\r
- }\r
-\r
- // Dumping UID\r
- BYTE bits[224];\r
- char showbits[225];\r
- showbits[uidlen]='\0';\r
- int bit;\r
- i = start;\r
- int times = 0;\r
- if(uidlen > rawbit) {\r
- PrintToScrollback("Warning: not enough raw bits to get a full UID");\r
- for(bit = 0; bit < rawbit; bit++) {\r
- bits[bit] = rawbits[i++];\r
- // As we cannot know the parity, let's use "." and "/"\r
- showbits[bit] = '.' + bits[bit];\r
- }\r
- showbits[bit+1]='\0';\r
- PrintToScrollback("Partial UID=%s", showbits);\r
- return;\r
- } else {\r
- for(bit = 0; bit < uidlen; bit++) {\r
- bits[bit] = rawbits[i++];\r
- showbits[bit] = '0' + bits[bit];\r
- }\r
- times = 1;\r
- }\r
- PrintToScrollback("UID=%s", showbits);\r
-\r
- // Checking UID against next occurences\r
- for(; i + uidlen <= rawbit;) {\r
- int failed = 0;\r
- for(bit = 0; bit < uidlen; bit++) {\r
- if(bits[bit] != rawbits[i++]) {\r
- failed = 1;\r
- break;\r
- }\r
- }\r
- if (failed == 1) {\r
- break;\r
- }\r
- times += 1;\r
- }\r
- PrintToScrollback("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen);\r
-\r
- // Remodulating for tag cloning\r
- GraphTraceLen = 32*uidlen;\r
- i = 0;\r
- int phase = 0;\r
- for(bit = 0; bit < uidlen; bit++) {\r
- if(bits[bit] == 0) {\r
- phase = 0;\r
- } else {\r
- phase = 1;\r
- }\r
- int j;\r
- for(j = 0; j < 32; j++) {\r
- GraphBuffer[i++] = phase;\r
- phase = !phase;\r
- }\r
- }\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdFlexdemod(char *str)\r
-{\r
- int i;\r
- for(i = 0; i < GraphTraceLen; i++) {\r
- if(GraphBuffer[i] < 0) {\r
- GraphBuffer[i] = -1;\r
- } else {\r
- GraphBuffer[i] = 1;\r
- }\r
- }\r
-\r
-#define LONG_WAIT 100\r
- int start;\r
- for(start = 0; start < GraphTraceLen - LONG_WAIT; start++) {\r
- int first = GraphBuffer[start];\r
- for(i = start; i < start + LONG_WAIT; i++) {\r
- if(GraphBuffer[i] != first) {\r
- break;\r
- }\r
- }\r
- if(i == (start + LONG_WAIT)) {\r
- break;\r
- }\r
- }\r
- if(start == GraphTraceLen - LONG_WAIT) {\r
- PrintToScrollback("nothing to wait for");\r
- return;\r
- }\r
-\r
- GraphBuffer[start] = 2;\r
- GraphBuffer[start+1] = -2;\r
-\r
- BYTE bits[64];\r
-\r
- int bit;\r
- i = start;\r
- for(bit = 0; bit < 64; bit++) {\r
- int j;\r
- int sum = 0;\r
- for(j = 0; j < 16; j++) {\r
- sum += GraphBuffer[i++];\r
- }\r
- if(sum > 0) {\r
- bits[bit] = 1;\r
- } else {\r
- bits[bit] = 0;\r
- }\r
- PrintToScrollback("bit %d sum %d", bit, sum);\r
- }\r
-\r
- for(bit = 0; bit < 64; bit++) {\r
- int j;\r
- int sum = 0;\r
- for(j = 0; j < 16; j++) {\r
- sum += GraphBuffer[i++];\r
- }\r
- if(sum > 0 && bits[bit] != 1) {\r
- PrintToScrollback("oops1 at %d", bit);\r
- }\r
- if(sum < 0 && bits[bit] != 0) {\r
- PrintToScrollback("oops2 at %d", bit);\r
- }\r
- }\r
-\r
- GraphTraceLen = 32*64;\r
- i = 0;\r
- int phase = 0;\r
- for(bit = 0; bit < 64; bit++) {\r
- if(bits[bit] == 0) {\r
- phase = 0;\r
- } else {\r
- phase = 1;\r
- }\r
- int j;\r
- for(j = 0; j < 32; j++) {\r
- GraphBuffer[i++] = phase;\r
- phase = !phase;\r
- }\r
- }\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-/*\r
- * Generic command to demodulate ASK.\r
- *\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
- * c : 0 or 1\r
- */\r
-\r
-static void Cmdaskdemod(char *str) {\r
- int i;\r
- int n = 0;\r
- int c,high,low = 0;\r
-\r
- // TODO: complain if we do not give 2 arguments here !\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] > 0) {\r
- GraphBuffer[0] = 1-c;\r
- } else {\r
- GraphBuffer[0] = c;\r
- }\r
- for(i=1;i<GraphTraceLen;i++) {\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
- 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
- RepaintGraphWindow();\r
-}\r
-\r
-/* Print our clock rate */\r
-static void Cmddetectclockrate(char *str)\r
-{\r
- int clock = detectclock(0);\r
- PrintToScrollback("Auto-detected clock rate: %d", clock);\r
-}\r
-\r
-/*\r
- * Detect clock rate\r
- */\r
-int detectclock(int peak)\r
-{\r
- int i;\r
- int clock = 0xFFFF;\r
- int lastpeak = 0;\r
-\r
- /* Detect peak if we don't have one */\r
- if (!peak)\r
- for (i = 0; i < GraphTraceLen; i++)\r
- if (GraphBuffer[i] > peak)\r
- peak = GraphBuffer[i];\r
-\r
- for (i = 1; i < GraphTraceLen; i++)\r
- {\r
- /* If this is the beginning of a peak */\r
- if (GraphBuffer[i-1] != GraphBuffer[i] && GraphBuffer[i] == peak)\r
- {\r
- /* Find lowest difference between peaks */\r
- if (lastpeak && i - lastpeak < clock)\r
- {\r
- clock = i - lastpeak;\r
- }\r
- lastpeak = i;\r
- }\r
- }\r
-\r
- return clock;\r
-}\r
-\r
-/* Get or auto-detect clock rate */\r
-int GetClock(char *str, int peak)\r
-{\r
- int clock;\r
-\r
- sscanf(str, "%i", &clock);\r
- if (!strcmp(str, ""))\r
- clock = 0;\r
-\r
- /* Auto-detect clock */\r
- if (!clock)\r
- {\r
- clock = detectclock(peak);\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
- return clock;\r
-}\r
-\r
-/*\r
- * Convert to a bitstream\r
- */\r
-static void Cmdbitstream(char *str) {\r
- int i, j;\r
- int bit;\r
- int gtl;\r
- int clock;\r
- int low = 0;\r
- int high = 0;\r
- int hithigh, hitlow, first;\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
- /* Get our clock */\r
- clock = GetClock(str, high);\r
-\r
- gtl = CmdClearGraph(0);\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
- /* Find out if we hit both high and low peaks */\r
- for (j = 0; j < clock; j++)\r
- {\r
- if (GraphBuffer[(i * clock) + j] == high)\r
- hithigh = 1;\r
- else if (GraphBuffer[(i * clock) + j] == low)\r
- hitlow = 1;\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
- if (hithigh && hitlow)\r
- break;\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
- CmdAppendGraph(0, clock, bit);\r
-// for (j = 0; j < (int)(clock/2); j++)\r
-// GraphBuffer[(i * clock) + j] = bit ^ 1;\r
-// for (j = (int)(clock/2); j < clock; j++)\r
-// GraphBuffer[(i * clock) + j] = bit;\r
- }\r
-\r
- RepaintGraphWindow();\r
-}\r
-\r
-/* Modulate our data into manchester */\r
-static void Cmdmanchestermod(char *str)\r
-{\r
- int i, j;\r
- int clock;\r
- int bit, lastbit, wave;\r
-\r
- /* Get our clock */\r
- clock = GetClock(str, 0);\r
-\r
- wave = 0;\r
- lastbit = 1;\r
- for (i = 0; i < (int)(GraphTraceLen / clock); i++)\r
- {\r
- bit = GraphBuffer[i * clock] ^ 1;\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
- /* 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
- RepaintGraphWindow();\r
-}\r
-\r
-/*\r
- * Manchester demodulate a bitstream. The bitstream needs to be already in\r
- * the GraphBuffer as 0 and 1 values\r
- *\r
- * Give the clock rate as argument in order to help the sync - the algorithm\r
- * resyncs at each pulse anyway.\r
- *\r
- * Not optimized by any means, this is the 1st time I'm writing this type of\r
- * routine, feel free to improve...\r
- *\r
- * 1st argument: clock rate (as number of samples per clock rate)\r
- * Typical values can be 64, 32, 128...\r
- */\r
-static void Cmdmanchesterdemod(char *str) {\r
- int i, j;\r
- int bit;\r
- int clock;\r
- int lastval;\r
- int low = 0;\r
- int high = 0;\r
- int hithigh, hitlow, first;\r
- int lc = 0;\r
- int bitidx = 0;\r
- int bit2idx = 0;\r
- int warnings = 0;\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
- /* int BitStream[GraphTraceLen*2/clock+10]; */\r
-\r
- /* But it does not work if compiling on WIndows: therefore we just allocate a */\r
- /* large array */\r
- int BitStream[MAX_GRAPH_TRACE_LEN];\r
-\r
- /* Detect high and lows */\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
- /* Get our clock */\r
- clock = GetClock(str, high);\r
-\r
- int tolerance = clock/4;\r
-\r
- /* Detect first transition */\r
- /* Lo-Hi (arbitrary) */\r
- for (i = 0; i < GraphTraceLen; i++)\r
- {\r
- if (GraphBuffer[i] == low)\r
- {\r
- lastval = i;\r
- break;\r
- }\r
- }\r
-\r
- /* If we're not working with 1/0s, demod based off clock */\r
- if (high != 1)\r
- {\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
- first = 1;\r
-\r
- /* Find out if we hit both high and low peaks */\r
- for (j = 0; j < clock; j++)\r
- {\r
- if (GraphBuffer[(i * clock) + j] == high)\r
- hithigh = 1;\r
- else if (GraphBuffer[(i * clock) + j] == low)\r
- hitlow = 1;\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
- if (hithigh && hitlow)\r
- break;\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
- BitStream[bit2idx++] = bit;\r
- }\r
- }\r
-\r
- /* standard 1/0 bitstream */\r
- else\r
- {\r
-\r
- /* Then detect duration between 2 successive transitions */\r
- for (bitidx = 1; i < GraphTraceLen; i++)\r
- {\r
- if (GraphBuffer[i-1] != GraphBuffer[i])\r
- {\r
- lc = i-lastval;\r
- lastval = i;\r
-\r
- // Error check: if bitidx becomes too large, we do not\r
- // have a Manchester encoded bitstream or the clock is really\r
- // wrong!\r
- if (bitidx > (GraphTraceLen*2/clock+8) ) {\r
- PrintToScrollback("Error: the clock you gave is probably wrong, aborting.");\r
- return;\r
- }\r
- // Then switch depending on lc length:\r
- // Tolerance is 1/4 of clock rate (arbitrary)\r
- if (abs(lc-clock/2) < tolerance) {\r
- // Short pulse : either "1" or "0"\r
- BitStream[bitidx++]=GraphBuffer[i-1];\r
- } else if (abs(lc-clock) < tolerance) {\r
- // Long pulse: either "11" or "00"\r
- BitStream[bitidx++]=GraphBuffer[i-1];\r
- BitStream[bitidx++]=GraphBuffer[i-1];\r
- } else {\r
- // Error\r
- warnings++;\r
- PrintToScrollback("Warning: Manchester decode error for pulse width detection.");\r
- PrintToScrollback("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");\r
-\r
- if (warnings > 100)\r
- {\r
- PrintToScrollback("Error: too many detection errors, aborting.");\r
- return;\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
- } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {\r
- BitStream[bit2idx++] = 0;\r
- } else {\r
- // We cannot end up in this state, this means we are unsynchronized,\r
- // move up 1 bit:\r
- i++;\r
- warnings++;\r
- PrintToScrollback("Unsynchronized, resync...");\r
- PrintToScrollback("(too many of those messages mean the stream is not Manchester encoded)");\r
-\r
- if (warnings > 100)\r
- {\r
- PrintToScrollback("Error: too many decode errors, aborting.");\r
- return;\r
- }\r
- }\r
- }\r
- }\r
-\r
- PrintToScrollback("Manchester decoded bitstream");\r
- // Now output the bitstream to the scrollback by line of 16 bits\r
- for (i = 0; i < (bit2idx-16); i+=16) {\r
- PrintToScrollback("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",\r
- BitStream[i],\r
- BitStream[i+1],\r
- BitStream[i+2],\r
- BitStream[i+3],\r
- BitStream[i+4],\r
- BitStream[i+5],\r
- BitStream[i+6],\r
- BitStream[i+7],\r
- BitStream[i+8],\r
- BitStream[i+9],\r
- BitStream[i+10],\r
- BitStream[i+11],\r
- BitStream[i+12],\r
- BitStream[i+13],\r
- BitStream[i+14],\r
- BitStream[i+15]);\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * Usage ???\r
- */\r
-static void CmdHiddemod(char *str)\r
-{\r
- if(GraphTraceLen < 4800) {\r
- PrintToScrollback("too short; need at least 4800 samples");\r
- return;\r
- }\r
-\r
- GraphTraceLen = 4800;\r
- int i;\r
- for(i = 0; i < GraphTraceLen; i++) {\r
- if(GraphBuffer[i] < 0) {\r
- GraphBuffer[i] = 0;\r
- } else {\r
- GraphBuffer[i] = 1;\r
- }\r
- }\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdPlot(char *str)\r
-{\r
- ShowGraphWindow();\r
-}\r
-\r
-static void CmdHide(char *str)\r
-{\r
- HideGraphWindow();\r
-}\r
-\r
-static void CmdScale(char *str)\r
-{\r
- CursorScaleFactor = atoi(str);\r
- if(CursorScaleFactor == 0) {\r
- PrintToScrollback("bad, can't have zero scale");\r
- CursorScaleFactor = 1;\r
- }\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdSave(char *str)\r
-{\r
- FILE *f = fopen(str, "w");\r
- if(!f) {\r
- PrintToScrollback("couldn't open '%s'", str);\r
- return;\r
- }\r
- int i;\r
- for(i = 0; i < GraphTraceLen; i++) {\r
- fprintf(f, "%d\n", GraphBuffer[i]);\r
- }\r
- fclose(f);\r
- PrintToScrollback("saved to '%s'", str);\r
-}\r
-\r
-static void CmdLoad(char *str)\r
-{\r
- FILE *f = fopen(str, "r");\r
- if(!f) {\r
- PrintToScrollback("couldn't open '%s'", str);\r
- return;\r
- }\r
-\r
- GraphTraceLen = 0;\r
- char line[80];\r
- while(fgets(line, sizeof(line), f)) {\r
- GraphBuffer[GraphTraceLen] = atoi(line);\r
- GraphTraceLen++;\r
- }\r
- fclose(f);\r
- PrintToScrollback("loaded %d samples", GraphTraceLen);\r
- RepaintGraphWindow();\r
-}\r
-\r
-static void CmdHIDsimTAG(char *str)\r
-{\r
- unsigned int hi=0, lo=0;\r
- int n=0, i=0;\r
- UsbCommand c;\r
-\r
- while (sscanf(&str[i++], "%1x", &n ) == 1) {\r
- hi=(hi<<4)|(lo>>28);\r
- lo=(lo<<4)|(n&0xf);\r
- }\r
-\r
- PrintToScrollback("Emulating tag with ID %x%16x", hi, lo);\r
-\r
- c.cmd = CMD_HID_SIM_TAG;\r
- c.ext1 = hi;\r
- c.ext2 = lo;\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdLcdReset(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_LCD_RESET;\r
- c.ext1 = atoi(str);\r
- SendCommand(&c, FALSE);\r
-}\r
-\r
-static void CmdLcd(char *str)\r
-{\r
- int i, j;\r
- UsbCommand c;\r
- c.cmd = CMD_LCD;\r
- sscanf(str, "%x %d", &i, &j);\r
- while (j--) {\r
- c.ext1 = i&0x1ff;\r
- SendCommand(&c, FALSE);\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
-static void CmdSetDivisor(char *str)\r
-{\r
- UsbCommand c;\r
- c.cmd = CMD_SET_LF_DIVISOR;\r
- c.ext1 = atoi(str);\r
- if (( c.ext1<0) || (c.ext1>255)) {\r
- PrintToScrollback("divisor must be between 19 and 255");\r
- } else {\r
- SendCommand(&c, FALSE);\r
- PrintToScrollback("Divisor set, expected freq=%dHz", 12000000/(c.ext1+1));\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
-static struct {\r
- char *name;\r
- HandlerFunction *handler;\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
- "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, "[clock rate] -- Try a Manchester demodulation on a binary stream",\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
-};\r
-\r
-\r
-//-----------------------------------------------------------------------------\r
-// Entry point into our code: called whenever the user types a command and\r
-// then presses Enter, which the full command line that they typed.\r
-//-----------------------------------------------------------------------------\r
-void CommandReceived(char *cmd)\r
-{\r
- int i;\r
-\r
- PrintToScrollback("> %s", cmd);\r
-\r
- if(strcmp(cmd, "help")==0) {\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
- sprintf(line+15, " -- %s", CommandTable[i].docString);\r
- PrintToScrollback("%s", line);\r
- }\r
- PrintToScrollback("");\r
- PrintToScrollback("and also: help, cls");\r
- return;\r
- }\r
-\r
- for(i = 0; i < sizeof(CommandTable) / sizeof(CommandTable[0]); i++) {\r
- char *name = CommandTable[i].name;\r
- if(memcmp(cmd, name, strlen(name))==0 &&\r
- (cmd[strlen(name)] == ' ' || cmd[strlen(name)] == '\0'))\r
- {\r
- cmd += strlen(name);\r
- while(*cmd == ' ') {\r
- cmd++;\r
- }\r
- if (offline && (CommandTable[i].offline==0)) {\r
- PrintToScrollback("Offline mode, cannot use this command.");\r
- return;\r
- }\r
- (CommandTable[i].handler)(cmd);\r
- return;\r
- }\r
- }\r
- PrintToScrollback(">> bad command '%s'", cmd);\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// Entry point into our code: called whenever we received a packet over USB\r
-// that we weren't necessarily expecting, for example a debug print.\r
-//-----------------------------------------------------------------------------\r
-void UsbCommandReceived(UsbCommand *c)\r
-{\r
- switch(c->cmd) {\r
- case CMD_DEBUG_PRINT_STRING: {\r
- char s[100];\r
- if(c->ext1 > 70 || c->ext1 < 0) {\r
- c->ext1 = 0;\r
- }\r
- memcpy(s, c->d.asBytes, c->ext1);\r
- s[c->ext1] = '\0';\r
- PrintToScrollback("#db# %s", s);\r
- break;\r
- }\r
-\r
- case CMD_DEBUG_PRINT_INTEGERS:\r
- PrintToScrollback("#db# %08x, %08x, %08x\r\n", c->ext1, c->ext2, c->ext3);\r
- break;\r
-\r
- case CMD_MEASURED_ANTENNA_TUNING: {\r
- int zLf, zHf;\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
- break;\r
- }\r
- default:\r
- PrintToScrollback("unrecognized command %08x\n", c->cmd);\r
- break;\r
- }\r
-}\r