]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfti.c
dcb30746caac8bf67659b9dced847d88df4e2c57
[proxmark3-svn] / client / cmdlfti.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "crc16.h"
4 #include "proxusb.h"
5 #include "data.h"
6 #include "ui.h"
7 #include "graph.h"
8 #include "cmdparser.h"
9 #include "cmdlfti.h"
10
11 static int CmdHelp(const char *Cmd);
12
13 int CmdTIDemod(const char *Cmd)
14 {
15 /* MATLAB as follows:
16 f_s = 2000000; % sampling frequency
17 f_l = 123200; % low FSK tone
18 f_h = 134200; % high FSK tone
19
20 T_l = 119e-6; % low bit duration
21 T_h = 130e-6; % high bit duration
22
23 l = 2*pi*ones(1, floor(f_s*T_l))*(f_l/f_s);
24 h = 2*pi*ones(1, floor(f_s*T_h))*(f_h/f_s);
25
26 l = sign(sin(cumsum(l)));
27 h = sign(sin(cumsum(h)));
28 */
29
30 // 2M*16/134.2k = 238
31 static const int LowTone[] = {
32 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
33 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
34 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
35 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
36 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
37 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
38 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
39 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
40 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
41 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
42 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
43 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
44 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
45 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
46 1, 1, 1, 1, 1, 1, 1, 1, -1, -1
47 };
48 // 2M*16/123.2k = 260
49 static const int HighTone[] = {
50 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
51 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
52 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
53 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
54 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
55 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
56 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
57 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
58 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
59 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
60 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
61 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
62 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
63 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
64 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
65 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
66 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
67 1, 1, 1, 1, 1, 1, 1, 1
68 };
69 int lowLen = sizeof(LowTone)/sizeof(int);
70 int highLen = sizeof(HighTone)/sizeof(int);
71 int convLen = (highLen>lowLen)?highLen:lowLen;
72 uint16_t crc;
73 int i, j, TagType;
74 int lowSum = 0, highSum = 0;;
75 int lowTot = 0, highTot = 0;
76
77 for (i = 0; i < GraphTraceLen - convLen; i++) {
78 lowSum = 0;
79 highSum = 0;;
80
81 for (j = 0; j < lowLen; j++) {
82 lowSum += LowTone[j]*GraphBuffer[i+j];
83 }
84 for (j = 0; j < highLen; j++) {
85 highSum += HighTone[j]*GraphBuffer[i+j];
86 }
87 lowSum = abs((100*lowSum) / lowLen);
88 highSum = abs((100*highSum) / highLen);
89 lowSum = (lowSum<0)?-lowSum:lowSum;
90 highSum = (highSum<0)?-highSum:highSum;
91
92 GraphBuffer[i] = (highSum << 16) | lowSum;
93 }
94
95 for (i = 0; i < GraphTraceLen - convLen - 16; i++) {
96 lowTot = 0;
97 highTot = 0;
98 // 16 and 15 are f_s divided by f_l and f_h, rounded
99 for (j = 0; j < 16; j++) {
100 lowTot += (GraphBuffer[i+j] & 0xffff);
101 }
102 for (j = 0; j < 15; j++) {
103 highTot += (GraphBuffer[i+j] >> 16);
104 }
105 GraphBuffer[i] = lowTot - highTot;
106 }
107
108 GraphTraceLen -= (convLen + 16);
109
110 RepaintGraphWindow();
111
112 // TI tag data format is 16 prebits, 8 start bits, 64 data bits,
113 // 16 crc CCITT bits, 8 stop bits, 15 end bits
114
115 // the 16 prebits are always low
116 // the 8 start and stop bits of a tag must match
117 // the start/stop prebits of a ro tag are 01111110
118 // the start/stop prebits of a rw tag are 11111110
119 // the 15 end bits of a ro tag are all low
120 // the 15 end bits of a rw tag match bits 15-1 of the data bits
121
122 // Okay, so now we have unsliced soft decisions;
123 // find bit-sync, and then get some bits.
124 // look for 17 low bits followed by 6 highs (common pattern for ro and rw tags)
125 int max = 0, maxPos = 0;
126 for (i = 0; i < 6000; i++) {
127 int j;
128 int dec = 0;
129 // searching 17 consecutive lows
130 for (j = 0; j < 17*lowLen; j++) {
131 dec -= GraphBuffer[i+j];
132 }
133 // searching 7 consecutive highs
134 for (; j < 17*lowLen + 6*highLen; j++) {
135 dec += GraphBuffer[i+j];
136 }
137 if (dec > max) {
138 max = dec;
139 maxPos = i;
140 }
141 }
142
143 // place a marker in the buffer to visually aid location
144 // of the start of sync
145 GraphBuffer[maxPos] = 800;
146 GraphBuffer[maxPos+1] = -800;
147
148 // advance pointer to start of actual data stream (after 16 pre and 8 start bits)
149 maxPos += 17*lowLen;
150 maxPos += 6*highLen;
151
152 // place a marker in the buffer to visually aid location
153 // of the end of sync
154 GraphBuffer[maxPos] = 800;
155 GraphBuffer[maxPos+1] = -800;
156
157 PrintAndLog("actual data bits start at sample %d", maxPos);
158
159 PrintAndLog("length %d/%d", highLen, lowLen);
160
161 uint8_t bits[1+64+16+8+16];
162 bits[sizeof(bits)-1] = '\0';
163
164 uint32_t shift3 = 0x7e000000, shift2 = 0, shift1 = 0, shift0 = 0;
165
166 for (i = 0; i < arraylen(bits)-1; i++) {
167 int high = 0;
168 int low = 0;
169 int j;
170 for (j = 0; j < lowLen; j++) {
171 low -= GraphBuffer[maxPos+j];
172 }
173 for (j = 0; j < highLen; j++) {
174 high += GraphBuffer[maxPos+j];
175 }
176
177 if (high > low) {
178 bits[i] = '1';
179 maxPos += highLen;
180 // bitstream arrives lsb first so shift right
181 shift3 |= (1<<31);
182 } else {
183 bits[i] = '.';
184 maxPos += lowLen;
185 }
186
187 // 128 bit right shift register
188 shift0 = (shift0>>1) | (shift1 << 31);
189 shift1 = (shift1>>1) | (shift2 << 31);
190 shift2 = (shift2>>1) | (shift3 << 31);
191 shift3 >>= 1;
192
193 // place a marker in the buffer between bits to visually aid location
194 GraphBuffer[maxPos] = 800;
195 GraphBuffer[maxPos+1] = -800;
196 }
197 PrintAndLog("Info: raw tag bits = %s", bits);
198
199 TagType = (shift3>>8)&0xff;
200 if ( TagType != ((shift0>>16)&0xff) ) {
201 PrintAndLog("Error: start and stop bits do not match!");
202 return 0;
203 }
204 else if (TagType == 0x7e) {
205 PrintAndLog("Info: Readonly TI tag detected.");
206 return 0;
207 }
208 else if (TagType == 0xfe) {
209 PrintAndLog("Info: Rewriteable TI tag detected.");
210
211 // put 64 bit data into shift1 and shift0
212 shift0 = (shift0>>24) | (shift1 << 8);
213 shift1 = (shift1>>24) | (shift2 << 8);
214
215 // align 16 bit crc into lower half of shift2
216 shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
217
218 // align 16 bit "end bits" or "ident" into lower half of shift3
219 shift3 >>= 16;
220
221 // only 15 bits compare, last bit of ident is not valid
222 if ( (shift3^shift0)&0x7fff ) {
223 PrintAndLog("Error: Ident mismatch!");
224 }
225 // WARNING the order of the bytes in which we calc crc below needs checking
226 // i'm 99% sure the crc algorithm is correct, but it may need to eat the
227 // bytes in reverse or something
228 // calculate CRC
229 crc=0;
230 crc = update_crc16(crc, (shift0)&0xff);
231 crc = update_crc16(crc, (shift0>>8)&0xff);
232 crc = update_crc16(crc, (shift0>>16)&0xff);
233 crc = update_crc16(crc, (shift0>>24)&0xff);
234 crc = update_crc16(crc, (shift1)&0xff);
235 crc = update_crc16(crc, (shift1>>8)&0xff);
236 crc = update_crc16(crc, (shift1>>16)&0xff);
237 crc = update_crc16(crc, (shift1>>24)&0xff);
238 PrintAndLog("Info: Tag data = %08X%08X", shift1, shift0);
239 if (crc != (shift2&0xffff)) {
240 PrintAndLog("Error: CRC mismatch, calculated %04X, got ^04X", crc, shift2&0xffff);
241 } else {
242 PrintAndLog("Info: CRC %04X is good", crc);
243 }
244 }
245 else {
246 PrintAndLog("Unknown tag type.");
247 return 0;
248 }
249 return 0;
250 }
251
252 // read a TI tag and return its ID
253 int CmdTIRead(const char *Cmd)
254 {
255 UsbCommand c = {CMD_READ_TI_TYPE};
256 SendCommand(&c);
257 return 0;
258 }
259
260 // write new data to a r/w TI tag
261 int CmdTIWrite(const char *Cmd)
262 {
263 UsbCommand c = {CMD_WRITE_TI_TYPE};
264 int res = 0;
265
266 res = sscanf(Cmd, "0x%x 0x%x 0x%x ", &c.arg[0], &c.arg[1], &c.arg[2]);
267 if (res == 2) c.arg[2]=0;
268 if (res < 2)
269 PrintAndLog("Please specify the data as two hex strings, optionally the CRC as a third");
270 else
271 SendCommand(&c);
272 return 0;
273 }
274
275 static command_t CommandTable[] =
276 {
277 {"help", CmdHelp, 1, "This help"},
278 {"demod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag"},
279 {"read", CmdTIRead, 0, "Read and decode a TI 134 kHz tag"},
280 {"write", CmdTIWrite, 0, "Write new data to a r/w TI 134 kHz tag"},
281 {NULL, NULL, 0, NULL}
282 };
283
284 int CmdLFTI(const char *Cmd)
285 {
286 CmdsParse(CommandTable, Cmd);
287 return 0;
288 }
289
290 int CmdHelp(const char *Cmd)
291 {
292 CmdsHelp(CommandTable);
293 return 0;
294 }
Impressum, Datenschutz