]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdlft55xx.c
Merge branch 'master' of https://github.com/Proxmark/proxmark3
[proxmark3-svn] / client / cmdlft55xx.c
... / ...
CommitLineData
1//-----------------------------------------------------------------------------\r
2//\r
3// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
4// at your option, any later version. See the LICENSE.txt file for the text of\r
5// the license.\r
6//-----------------------------------------------------------------------------\r
7// Low frequency T55xx commands\r
8//-----------------------------------------------------------------------------\r
9\r
10#include <stdio.h>\r
11#include <string.h>\r
12#include <inttypes.h>\r
13#include "proxmark3.h"\r
14#include "ui.h"\r
15#include "graph.h"\r
16#include "cmdmain.h"\r
17#include "cmdparser.h"\r
18#include "cmddata.h"\r
19#include "cmdlf.h"\r
20#include "cmdlft55xx.h"\r
21#include "util.h"\r
22#include "data.h"\r
23#include "lfdemod.h"\r
24\r
25#define LF_TRACE_BUFF_SIZE 20000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)\r
26#define LF_BITSSTREAM_LEN 1000 // more then 1000 bits shouldn't happend.. 8block * 4 bytes * 8bits = \r
27\r
28int usage_t55xx_read(){\r
29 PrintAndLog("Usage: lf t55xx read <block> <password>");\r
30 PrintAndLog(" <block>, block number to read. Between 0-7");\r
31 PrintAndLog(" <password>, OPTIONAL password (8 hex characters)");\r
32 PrintAndLog("");\r
33 PrintAndLog(" sample: lf t55xx read 0 = try reading data from block 0");\r
34 PrintAndLog(" : lf t55xx read 0 feedbeef = try reading data from block 0 using password");\r
35 PrintAndLog("");\r
36 return 0;\r
37}\r
38int usage_t55xx_write(){\r
39 PrintAndLog("Usage: lf t55xx wr <block> <data> [password]");\r
40 PrintAndLog(" <block>, block number to read. Between 0-7");\r
41 PrintAndLog(" <data>, 4 bytes of data to write (8 hex characters)");\r
42 PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)");\r
43 PrintAndLog("");\r
44 PrintAndLog(" sample: lf t55xx wd 3 11223344 = try writing data 11223344 to block 3");\r
45 PrintAndLog(" : lf t55xx wd 3 11223344 feedbeef = try writing data 11223344 to block 3 using password feedbeef");\r
46 PrintAndLog("");\r
47 return 0;\r
48}\r
49int usage_t55xx_trace() {\r
50 PrintAndLog("Usage: lf t55xx trace [graph buffer data]");\r
51 PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
52 PrintAndLog("");\r
53 PrintAndLog(" sample: lf t55xx trace");\r
54 PrintAndLog(" : lf t55xx trace 1");\r
55 PrintAndLog("");\r
56 return 0;\r
57}\r
58int usage_t55xx_info() {\r
59 PrintAndLog("Usage: lf t55xx info [graph buffer data]");\r
60 PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
61 PrintAndLog("");\r
62 PrintAndLog(" sample: lf t55xx info");\r
63 PrintAndLog(" : lf t55xx info 1");\r
64 PrintAndLog("");\r
65 return 0;\r
66}\r
67int usage_t55xx_dump(){\r
68 PrintAndLog("Usage: lf t55xx dump <password>");\r
69 PrintAndLog(" <password>, OPTIONAL password 4bytes (8 hex characters)");\r
70 PrintAndLog("");\r
71 PrintAndLog(" sample: lf t55xx dump");\r
72 PrintAndLog(" : lf t55xx dump feedbeef");\r
73 PrintAndLog("");\r
74 return 0;\r
75}\r
76\r
77static int CmdHelp(const char *Cmd);\r
78\r
79int CmdReadBlk(const char *Cmd)\r
80{\r
81 int i = 0;\r
82 int block = -1;\r
83 int password = 0xFFFFFFFF; //default to blank Block 7\r
84 size_t bitlen = 0;\r
85 uint32_t blockData = 0;\r
86 uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00};\r
87 \r
88 char cmdp = param_getchar(Cmd, 0);\r
89 if (cmdp == 'h' || cmdp == 'H') {\r
90 usage_t55xx_read();\r
91 return 0;\r
92 }\r
93\r
94 int res = sscanf(Cmd, "%d %x", &block, &password);\r
95\r
96 if ( res < 1 || res > 2 ){\r
97 usage_t55xx_read();\r
98 return 1;\r
99 }\r
100 \r
101 if ((block < 0) | (block > 7)) {\r
102 PrintAndLog("Block must be between 0 and 7");\r
103 return 1;\r
104 } \r
105\r
106 UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};\r
107 c.d.asBytes[0] = 0x0; \r
108\r
109 //Password mode\r
110 if ( res == 2 ) {\r
111 c.arg[2] = password;\r
112 c.d.asBytes[0] = 0x1; \r
113 }\r
114\r
115 SendCommand(&c);\r
116 if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
117 PrintAndLog("command execution time out");\r
118 return 2;\r
119 }\r
120 \r
121 uint8_t got[12000];\r
122 GetFromBigBuf(got,sizeof(got),0);\r
123 WaitForResponse(CMD_ACK,NULL);\r
124\r
125 setGraphBuf(got, 12000);\r
126 \r
127 bitlen = getFromGraphBuf(bits);\r
128\r
129 int ans = 0;\r
130 ans = CmdFSKrawdemod("");\r
131 ans = CmdFSKrawdemod("1"); //invert?\r
132 ans = Cmdaskmandemod("");\r
133 ans = Cmdaskrawdemod("");\r
134 ans = CmdNRZrawDemod("");\r
135 ans = CmdPSK1rawDemod("");\r
136 ans = CmdPSK2rawDemod("");\r
137 \r
138 // if ( !tryDemod(bits, bitlen) )\r
139 // return 3;\r
140 \r
141 // //move bits back to DemodBuffer\r
142 // setDemodBuf(bits, bitlen, 0);\r
143 // printBitStream(bits, bitlen);\r
144 if ( !DemodBufferLen) \r
145 return 0;\r
146 \r
147 for (;i<DemodBufferLen;++i)\r
148 bits[i]=DemodBuffer[i];\r
149 \r
150 blockData = PackBits(1, 32, bits);\r
151\r
152 if ( block < 0)\r
153 PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bits+1,32) );\r
154 else\r
155 PrintAndLog(" Block %d : 0x%08X %s", block, blockData, sprint_bin(bits+1,32) );\r
156 \r
157 return 0;\r
158}\r
159\r
160\r
161/*\r
162FSK1 / FSK1a\r
163size = fskdemod(dest, size, 32, 0, 8, 10); // fsk1 RF/32 \r
164size = fskdemod(dest, size, 32, 1, 8, 10); // fsk1a RF/32 \r
165\r
166FSK2 / FSK2a\r
167size = fskdemod(dest, size, 32, 0, 10, 8); // fsk2 RF/32 \r
168size = fskdemod(dest, size, 32, 1, 10, 8); // fsk2a RF/32 \r
169size = fskdemod(dest, size, 50, 1, 10, 8); // fsk2a RF/50 \r
170size = fskdemod(dest, size, 64, 1, 10, 8); // FSK2a RF/64 \r
171\r
172PSK1\r
173errCnt = pskRawDemod(bits, &bitlen, 32, 0);\r
174*/\r
175bool tryDemod(uint8_t bits[], size_t bitlen) {\r
176 \r
177 int invert = 0;\r
178 int clk = 0;\r
179 int errCnt, size;\r
180 int maxErr = 100;\r
181 uint8_t rflen, fchigh, fclow, dummy = 0;\r
182 uint16_t fcs=0;\r
183\r
184 // ASK - manchester demod\r
185 errCnt = askmandemod(bits, &bitlen, &clk, &invert, maxErr);\r
186 if ( analyseDemod(errCnt, bitlen, clk, invert) ) \r
187 return true;\r
188\r
189 // FSK demod\r
190 fcs = countFC(bits, bitlen, &dummy);\r
191 if (fcs == 0){\r
192 fchigh = 10;\r
193 fclow = 8;\r
194 }else{\r
195 fchigh = (fcs >> 8) & 0xFF;\r
196 fclow = fcs & 0xFF;\r
197 }\r
198 //get bit clock length\r
199 rflen = detectFSKClk(bits, bitlen, fchigh, fclow);\r
200 rflen = (rflen == 0) ? 50 : rflen;\r
201\r
202 size = fskdemod(bits, bitlen, rflen, invert, fchigh, fclow);\r
203 if ( analyseDemod(size, bitlen, clk, invert) ) \r
204 return true; \r
205 \r
206 // PSK demod\r
207 return false;\r
208}\r
209\r
210bool analyseDemod( int errCnt, size_t bitlen, uint8_t clock, uint8_t invert){\r
211 if (g_debugMode) \r
212 PrintAndLog("ErrorCount: %d, Bits Found: %d, Clock: %d, invert: %d", errCnt, bitlen, clock, invert);\r
213 //PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);\r
214 \r
215 //throw away static - allow 1 and -1 (in case of threshold command first)\r
216 if ( errCnt == -1 || bitlen < 32 ){ \r
217 PrintAndLog("no success demod");\r
218 return false;\r
219 }\r
220 return true;\r
221}\r
222\r
223int CmdWriteBlk(const char *Cmd)\r
224{\r
225 int block = 8; //default to invalid block\r
226 int data = 0xFFFFFFFF; //default to blank Block \r
227 int password = 0xFFFFFFFF; //default to blank Block 7\r
228 \r
229 char cmdp = param_getchar(Cmd, 0);\r
230 if (cmdp == 'h' || cmdp == 'H') {\r
231 usage_t55xx_write();\r
232 return 0;\r
233 }\r
234 \r
235 int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);\r
236 \r
237 if ( res < 2 || res > 3) {\r
238 usage_t55xx_write();\r
239 return 1;\r
240 }\r
241\r
242 if (block > 7) {\r
243 PrintAndLog("Block must be between 0 and 7");\r
244 return 1;\r
245 }\r
246 \r
247 UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
248 c.d.asBytes[0] = 0x0; \r
249\r
250 PrintAndLog("Writing to T55x7");\r
251 PrintAndLog("block : %d", block);\r
252 PrintAndLog("data : 0x%08X", data);\r
253\r
254 //Password mode\r
255 if (res == 3) {\r
256 c.arg[2] = password;\r
257 c.d.asBytes[0] = 0x1; \r
258 PrintAndLog("pwd : 0x%08X", password);\r
259 }\r
260 SendCommand(&c);\r
261 return 0;\r
262}\r
263\r
264int CmdReadTrace(const char *Cmd)\r
265{\r
266 size_t bitlen;\r
267 uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00};\r
268\r
269 char cmdp = param_getchar(Cmd, 0);\r
270 \r
271 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
272 usage_t55xx_trace();\r
273 return 0;\r
274 }\r
275\r
276 if ( strlen(Cmd)==0){\r
277 \r
278 UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};\r
279 SendCommand(&c);\r
280 if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
281 PrintAndLog("command execution time out");\r
282 return 1;\r
283 }\r
284 //darn\r
285 //CmdSamples("12000");\r
286 }\r
287 \r
288 bitlen = getFromGraphBuf(bits);\r
289\r
290\r
291 RepaintGraphWindow();\r
292\r
293 uint8_t si = 5;\r
294 uint32_t bl0 = PackBits(si, 32, bits);\r
295 uint32_t bl1 = PackBits(si+32, 32, bits);\r
296 \r
297 uint32_t acl = PackBits(si, 8, bits); si += 8;\r
298 uint32_t mfc = PackBits(si, 8, bits); si += 8;\r
299 uint32_t cid = PackBits(si, 5, bits); si += 5;\r
300 uint32_t icr = PackBits(si, 3, bits); si += 3;\r
301 uint32_t year = PackBits(si, 4, bits); si += 4;\r
302 uint32_t quarter = PackBits(si, 2, bits); si += 2;\r
303 uint32_t lotid = PackBits(si, 12, bits); si += 12;\r
304 uint32_t wafer = PackBits(si, 5, bits); si += 5;\r
305 uint32_t dw = PackBits(si, 15, bits); \r
306 \r
307 PrintAndLog("");\r
308 PrintAndLog("-- T55xx Trace Information ----------------------------------");\r
309 PrintAndLog("-------------------------------------------------------------");\r
310 PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl);\r
311 PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d)", mfc, mfc);\r
312 PrintAndLog(" CID : 0x%02X (%d)", cid, cid);\r
313 PrintAndLog(" ICR IC Revision : %d",icr );\r
314 PrintAndLog(" Manufactured");\r
315 PrintAndLog(" Year/Quarter : %d/%d",2000+year, quarter );\r
316 PrintAndLog(" Lot ID : %d", lotid );\r
317 PrintAndLog(" Wafer number : %d", wafer);\r
318 PrintAndLog(" Die Number : %d", dw);\r
319 PrintAndLog("-------------------------------------------------------------");\r
320 PrintAndLog(" Raw Data - Page 1");\r
321 PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bits+5,32) );\r
322 PrintAndLog(" Block 0 : 0x%08X %s", bl1, sprint_bin(bits+37,32) );\r
323 PrintAndLog("-------------------------------------------------------------");\r
324 /*\r
325 TRACE - BLOCK O\r
326 Bits Definition HEX\r
327 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 \r
328 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation\r
329 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 \r
330 22-24 ICR IC revision\r
331 25-28 YEAR (BCD encoded) 9 (= 2009)\r
332 29-30 QUARTER 1,2,3,4 \r
333 31-32 LOT ID\r
334 \r
335 TRACE - BLOCK 1\r
336 1-12 LOT ID \r
337 13-17 Wafer number\r
338 18-32 DW, die number sequential\r
339 */\r
340 \r
341 return 0;\r
342}\r
343\r
344int CmdInfo(const char *Cmd){\r
345 /*\r
346 Page 0 Block 0 Configuration data.\r
347 Normal mode\r
348 Extended mode\r
349 */\r
350 char cmdp = param_getchar(Cmd, 0);\r
351\r
352 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
353 usage_t55xx_info();\r
354 return 0;\r
355 } else {\r
356 CmdReadBlk("0");\r
357 } \r
358\r
359 uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};\r
360\r
361 manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN);\r
362 \r
363 uint8_t si = 5;\r
364 uint32_t bl0 = PackBits(si, 32, bits);\r
365 \r
366 uint32_t safer = PackBits(si, 4, bits); si += 4; \r
367 uint32_t resv = PackBits(si, 7, bits); si += 7;\r
368 uint32_t dbr = PackBits(si, 3, bits); si += 3;\r
369 uint32_t extend = PackBits(si, 1, bits); si += 1;\r
370 uint32_t datamodulation = PackBits(si, 5, bits); si += 5;\r
371 uint32_t pskcf = PackBits(si, 2, bits); si += 2;\r
372 uint32_t aor = PackBits(si, 1, bits); si += 1; \r
373 uint32_t otp = PackBits(si, 1, bits); si += 1; \r
374 uint32_t maxblk = PackBits(si, 3, bits); si += 3;\r
375 uint32_t pwd = PackBits(si, 1, bits); si += 1; \r
376 uint32_t sst = PackBits(si, 1, bits); si += 1; \r
377 uint32_t fw = PackBits(si, 1, bits); si += 1;\r
378 uint32_t inv = PackBits(si, 1, bits); si += 1; \r
379 uint32_t por = PackBits(si, 1, bits); si += 1;\r
380 \r
381 PrintAndLog("");\r
382 PrintAndLog("-- T55xx Configuration & Tag Information --------------------");\r
383 PrintAndLog("-------------------------------------------------------------");\r
384 PrintAndLog(" Safer key : %s", GetSaferStr(safer));\r
385 PrintAndLog(" reserved : %d", resv);\r
386 PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));\r
387 PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");\r
388 PrintAndLog(" Modulation : %s", GetModulationStr(datamodulation) );\r
389 PrintAndLog(" PSK clock freq : %d", pskcf);\r
390 PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No");\r
391 PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" );\r
392 PrintAndLog(" Max block : %d", maxblk);\r
393 PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No");\r
394 PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");\r
395 PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No");\r
396 PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No");\r
397 PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No");\r
398 PrintAndLog("-------------------------------------------------------------");\r
399 PrintAndLog(" Raw Data - Page 0");\r
400 PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bits+5,32) );\r
401 PrintAndLog("-------------------------------------------------------------");\r
402 \r
403 return 0;\r
404}\r
405\r
406int CmdDump(const char *Cmd){\r
407\r
408 char s[20] = {0x00};\r
409 uint8_t pwd[4] = {0x00};\r
410\r
411 char cmdp = param_getchar(Cmd, 0);\r
412 if ( cmdp == 'h' || cmdp == 'H') {\r
413 usage_t55xx_dump();\r
414 return 0;\r
415 }\r
416\r
417 bool hasPwd = ( strlen(Cmd) > 0); \r
418 if ( hasPwd ){\r
419 if (param_gethex(Cmd, 0, pwd, 8)) {\r
420 PrintAndLog("password must include 8 HEX symbols");\r
421 return 1;\r
422 }\r
423 }\r
424 \r
425 for ( int i = 0; i <8; ++i){\r
426 memset(s,0,sizeof(s));\r
427 if ( hasPwd ) {\r
428 sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);\r
429 } else {\r
430 sprintf(s,"%d", i);\r
431 }\r
432 CmdReadBlk(s);\r
433 }\r
434 return 0;\r
435}\r
436\r
437int CmdIceFsk(const char *Cmd){\r
438\r
439 if (!HasGraphData()) return 0;\r
440\r
441 iceFsk3(GraphBuffer, LF_TRACE_BUFF_SIZE);\r
442 RepaintGraphWindow();\r
443 return 0;\r
444}\r
445int CmdIceManchester(const char *Cmd){\r
446 ManchesterDemod( -1);\r
447 return 0;\r
448}\r
449int ManchesterDemod(int blockNum){\r
450\r
451 if (!HasGraphData()) return 0;\r
452 \r
453 uint8_t sizebyte = 32;\r
454 // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip.\r
455 uint8_t offset = 5;\r
456 uint32_t blockData;\r
457 uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};\r
458 uint8_t * bitstream = bits;\r
459 \r
460 manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN); \r
461 blockData = PackBits(offset, sizebyte, bits);\r
462\r
463 if ( blockNum < 0)\r
464 PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bitstream+offset,sizebyte) );\r
465 else\r
466 PrintAndLog(" Block %d : 0x%08X %s", blockNum, blockData, sprint_bin(bitstream+offset,sizebyte) );\r
467 \r
468 return 0;\r
469} \r
470\r
471char * GetBitRateStr(uint32_t id){\r
472 static char buf[40];\r
473 char *retStr = buf;\r
474 switch (id){\r
475 case 0: \r
476 sprintf(retStr,"%d - RF/8",id);\r
477 break;\r
478 case 1:\r
479 sprintf(retStr,"%d - RF/16",id);\r
480 break;\r
481 case 2: \r
482 sprintf(retStr,"%d - RF/32",id);\r
483 break;\r
484 case 3:\r
485 sprintf(retStr,"%d - RF/40",id);\r
486 break;\r
487 case 4:\r
488 sprintf(retStr,"%d - RF/50",id);\r
489 break;\r
490 case 5:\r
491 sprintf(retStr,"%d - RF/64",id);\r
492 break;\r
493 case 6:\r
494 sprintf(retStr,"%d - RF/100",id);\r
495 break;\r
496 case 7:\r
497 sprintf(retStr,"%d - RF/128",id);\r
498 break;\r
499 default:\r
500 sprintf(retStr,"%d - (Unknown)",id);\r
501 break;\r
502 }\r
503\r
504 return buf;\r
505}\r
506\r
507char * GetSaferStr(uint32_t id){\r
508 static char buf[40];\r
509 char *retStr = buf;\r
510 \r
511 sprintf(retStr,"%d",id);\r
512 if (id == 6) {\r
513 sprintf(retStr,"%d - pasdwd",id);\r
514 }\r
515 if (id == 9 ){\r
516 sprintf(retStr,"%d - testmode ",id);\r
517 }\r
518 \r
519 return buf;\r
520}\r
521char * GetModulationStr( uint32_t id){\r
522 static char buf[40];\r
523 char *retStr = buf;\r
524 \r
525 switch (id){\r
526 case 0: \r
527 sprintf(retStr,"%d - DIRECT (ASK/NRZ)",id);\r
528 break;\r
529 case 1:\r
530 sprintf(retStr,"%d - PSK 1 phase change when input changes",id);\r
531 break;\r
532 case 2: \r
533 sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id);\r
534 break;\r
535 case 3:\r
536 sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id);\r
537 break;\r
538 case 4:\r
539 sprintf(retStr,"%d - FSK 1 RF/8 RF/5",id);\r
540 break;\r
541 case 5:\r
542 sprintf(retStr,"%d - FSK 2 RF/8 RF/10",id);\r
543 break;\r
544 case 6:\r
545 sprintf(retStr,"%d - FSK 1a RF/5 RF/8",id);\r
546 break;\r
547 case 7:\r
548 sprintf(retStr,"%d - FSK 2a RF/10 RF/8",id);\r
549 break;\r
550 case 8:\r
551 sprintf(retStr,"%d - Manschester",id);\r
552 break;\r
553 case 16:\r
554 sprintf(retStr,"%d - Biphase",id);\r
555 break;\r
556 case 17:\r
557 sprintf(retStr,"%d - Reserved",id);\r
558 break;\r
559 default:\r
560 sprintf(retStr,"0x%02X (Unknown)",id);\r
561 break;\r
562 }\r
563 return buf;\r
564}\r
565\r
566\r
567uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){\r
568 \r
569 int i = start;\r
570 int j = len-1;\r
571 if (len > 32) {\r
572 return 0;\r
573 }\r
574 uint32_t tmp = 0;\r
575 for (; j >= 0; --j, ++i){\r
576 tmp |= bits[i] << j;\r
577 }\r
578 return tmp;\r
579}\r
580\r
581static command_t CommandTable[] =\r
582{\r
583 {"help", CmdHelp, 1, "This help"},\r
584 {"read", CmdReadBlk, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
585 {"write", CmdWriteBlk, 0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
586 {"trace", CmdReadTrace, 0, "[1] Read T55xx traceability data (page 1/ blk 0-1)"},\r
587 {"info", CmdInfo, 0, "[1] Read T55xx configuration data (page 0/ blk 0)"},\r
588 {"dump", CmdDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"},\r
589 {NULL, NULL, 0, NULL}\r
590};\r
591\r
592int CmdLFT55XX(const char *Cmd)\r
593{\r
594 CmdsParse(CommandTable, Cmd);\r
595 return 0;\r
596}\r
597\r
598int CmdHelp(const char *Cmd)\r
599{\r
600 CmdsHelp(CommandTable);\r
601 return 0;\r
602}\r
Impressum, Datenschutz