]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlft55xx.c
CHG: @ematrix / @piwi fixes for 'hf snoop'
[proxmark3-svn] / client / cmdlft55xx.c
1 //-----------------------------------------------------------------------------
2 //
3 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
4 // at your option, any later version. See the LICENSE.txt file for the text of
5 // the license.
6 //-----------------------------------------------------------------------------
7 // Low frequency T55xx commands
8 //-----------------------------------------------------------------------------
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <inttypes.h>
13 #include <time.h>
14 #include "proxmark3.h"
15 #include "ui.h"
16 #include "graph.h"
17 #include "cmdmain.h"
18 #include "cmdparser.h"
19 #include "cmddata.h"
20 #include "cmdlf.h"
21 #include "cmdlft55xx.h"
22 #include "util.h"
23 #include "data.h"
24 #include "lfdemod.h"
25 #include "../common/crc.h"
26 #include "../common/iso14443crc.h"
27 #include "cmdhf14a.h"
28
29 #define T55x7_CONFIGURATION_BLOCK 0x00
30 #define T55x7_PAGE0 0x00
31 #define T55x7_PAGE1 0x01
32 #define T55x7_PWD 0x00000010
33 #define REGULAR_READ_MODE_BLOCK 0xFF
34
35 // Default configuration
36 t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};
37
38 int usage_t55xx_config(){
39 PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");
40 PrintAndLog("Options:");
41 PrintAndLog(" h This help");
42 PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");
43 PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
44 PrintAndLog(" i [1] Invert data signal, defaults to normal");
45 PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream");
46 PrintAndLog("");
47 PrintAndLog("Examples:");
48 PrintAndLog(" lf t55xx config d FSK - FSK demodulation");
49 PrintAndLog(" lf t55xx config d FSK i 1 - FSK demodulation, inverse data");
50 PrintAndLog(" lf t55xx config d FSK i 1 o 3 - FSK demodulation, inverse data, offset=3,start from position 3 to decode data");
51 PrintAndLog("");
52 return 0;
53 }
54 int usage_t55xx_read(){
55 PrintAndLog("Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");
56 PrintAndLog("Options:");
57 PrintAndLog(" b <block> - block number to read. Between 0-7");
58 PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
59 PrintAndLog(" o - OPTIONAL override safety check");
60 PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
61 PrintAndLog(" ****WARNING****");
62 PrintAndLog(" Use of read with password on a tag not configured for a pwd");
63 PrintAndLog(" can damage the tag");
64 PrintAndLog("");
65 PrintAndLog("Examples:");
66 PrintAndLog(" lf t55xx read b 0 - read data from block 0");
67 PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef");
68 PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");
69 PrintAndLog("");
70 return 0;
71 }
72 int usage_t55xx_write(){
73 PrintAndLog("Usage: lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");
74 PrintAndLog("Options:");
75 PrintAndLog(" b <block> - block number to write. Between 0-7");
76 PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");
77 PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
78 PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
79 PrintAndLog("");
80 PrintAndLog("Examples:");
81 PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
82 PrintAndLog(" lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");
83 PrintAndLog("");
84 return 0;
85 }
86 int usage_t55xx_trace() {
87 PrintAndLog("Usage: lf t55xx trace [1]");
88 PrintAndLog("Options:");
89 PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
90 PrintAndLog("");
91 PrintAndLog("Examples:");
92 PrintAndLog(" lf t55xx trace");
93 PrintAndLog(" lf t55xx trace 1");
94 PrintAndLog("");
95 return 0;
96 }
97 int usage_t55xx_info() {
98 PrintAndLog("Usage: lf t55xx info [1]");
99 PrintAndLog("Options:");
100 PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
101 PrintAndLog("");
102 PrintAndLog("Examples:");
103 PrintAndLog(" lf t55xx info");
104 PrintAndLog(" lf t55xx info 1");
105 PrintAndLog("");
106 return 0;
107 }
108 int usage_t55xx_dump(){
109 PrintAndLog("Usage: lf t55xx dump <password> [o]");
110 PrintAndLog("Options:");
111 PrintAndLog(" <password> - OPTIONAL password 4bytes (8 hex symbols)");
112 PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card");
113 PrintAndLog("");
114 PrintAndLog("Examples:");
115 PrintAndLog(" lf t55xx dump");
116 PrintAndLog(" lf t55xx dump feedbeef o");
117 PrintAndLog("");
118 return 0;
119 }
120 int usage_t55xx_detect(){
121 PrintAndLog("Usage: lf t55xx detect [1]");
122 PrintAndLog("Options:");
123 PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
124 PrintAndLog("");
125 PrintAndLog("Examples:");
126 PrintAndLog(" lf t55xx detect");
127 PrintAndLog(" lf t55xx detect 1");
128 PrintAndLog("");
129 return 0;
130 }
131 int usage_t55xx_wakup(){
132 PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");
133 PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
134 PrintAndLog("Options:");
135 PrintAndLog(" h - this help");
136 PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");
137 PrintAndLog("");
138 PrintAndLog("Examples:");
139 PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
140 return 0;
141 }
142
143 static int CmdHelp(const char *Cmd);
144
145 int CmdT55xxSetConfig(const char *Cmd) {
146
147 uint8_t offset = 0;
148 bool errors = FALSE;
149 uint8_t cmdp = 0;
150 char modulation[5] = {0x00};
151 char tmp = 0x00;
152 uint8_t bitRate = 0;
153 uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};
154 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
155 tmp = param_getchar(Cmd, cmdp);
156 switch(tmp)
157 {
158 case 'h':
159 case 'H':
160 return usage_t55xx_config();
161 case 'b':
162 errors |= param_getdec(Cmd, cmdp+1, &bitRate);
163 if ( !errors){
164 uint8_t i = 0;
165 for (; i < 9; i++){
166 if (rates[i]==bitRate) {
167 config.bitrate = i;
168 break;
169 }
170 }
171 if (i==9) errors = TRUE;
172 }
173 cmdp+=2;
174 break;
175 case 'd':
176 param_getstr(Cmd, cmdp+1, modulation);
177 cmdp += 2;
178
179 if ( strcmp(modulation, "FSK" ) == 0) {
180 config.modulation = DEMOD_FSK;
181 } else if ( strcmp(modulation, "FSK1" ) == 0) {
182 config.modulation = DEMOD_FSK1;
183 config.inverted=1;
184 } else if ( strcmp(modulation, "FSK1a" ) == 0) {
185 config.modulation = DEMOD_FSK1a;
186 config.inverted=0;
187 } else if ( strcmp(modulation, "FSK2" ) == 0) {
188 config.modulation = DEMOD_FSK2;
189 config.inverted=0;
190 } else if ( strcmp(modulation, "FSK2a" ) == 0) {
191 config.modulation = DEMOD_FSK2a;
192 config.inverted=1;
193 } else if ( strcmp(modulation, "ASK" ) == 0) {
194 config.modulation = DEMOD_ASK;
195 } else if ( strcmp(modulation, "NRZ" ) == 0) {
196 config.modulation = DEMOD_NRZ;
197 } else if ( strcmp(modulation, "PSK1" ) == 0) {
198 config.modulation = DEMOD_PSK1;
199 } else if ( strcmp(modulation, "PSK2" ) == 0) {
200 config.modulation = DEMOD_PSK2;
201 } else if ( strcmp(modulation, "PSK3" ) == 0) {
202 config.modulation = DEMOD_PSK3;
203 } else if ( strcmp(modulation, "BIa" ) == 0) {
204 config.modulation = DEMOD_BIa;
205 config.inverted=1;
206 } else if ( strcmp(modulation, "BI" ) == 0) {
207 config.modulation = DEMOD_BI;
208 config.inverted=0;
209 } else {
210 PrintAndLog("Unknown modulation '%s'", modulation);
211 errors = TRUE;
212 }
213 break;
214 case 'i':
215 config.inverted = param_getchar(Cmd,cmdp+1) == '1';
216 cmdp+=2;
217 break;
218 case 'o':
219 errors |= param_getdec(Cmd, cmdp+1, &offset);
220 if ( !errors )
221 config.offset = offset;
222 cmdp+=2;
223 break;
224 default:
225 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
226 errors = TRUE;
227 break;
228 }
229 }
230
231 // No args
232 if (cmdp == 0) return printConfiguration( config );
233
234 //Validations
235 if (errors) return usage_t55xx_config();
236
237 config.block0 = 0;
238 return printConfiguration ( config );
239 }
240
241 int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){
242 //Password mode
243 if ( usepwd ) {
244 // try reading the config block and verify that PWD bit is set before doing this!
245 if ( !override ) {
246
247 if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0 ) ) return 0;
248
249 if ( !tryDetectModulation() ) {
250 PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
251 return 0;
252 } else {
253 PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password...");
254 usepwd = false;
255 page1 = false;
256 }
257 } else {
258 PrintAndLog("Safety Check Overriden - proceeding despite risk");
259 }
260 }
261
262 if (!AquireData(page1, block, usepwd, password) ) return 0;
263 if (!DecodeT55xxBlock()) return 0;
264
265 char blk[10]={0};
266 sprintf(blk,"%d", block);
267 printT55xxBlock(blk);
268 return 1;
269 }
270
271 int CmdT55xxReadBlock(const char *Cmd) {
272 uint8_t block = REGULAR_READ_MODE_BLOCK;
273 uint32_t password = 0; //default to blank Block 7
274 bool usepwd = false;
275 bool override = false;
276 bool page1 = false;
277 bool errors = false;
278 uint8_t cmdp = 0;
279 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
280 switch(param_getchar(Cmd, cmdp)) {
281 case 'h':
282 case 'H':
283 return usage_t55xx_read();
284 case 'b':
285 case 'B':
286 errors |= param_getdec(Cmd, cmdp+1, &block);
287 cmdp += 2;
288 break;
289 case 'o':
290 case 'O':
291 override = TRUE;
292 cmdp++;
293 break;
294 case 'p':
295 case 'P':
296 password = param_get32ex(Cmd, cmdp+1, 0, 16);
297 usepwd = true;
298 cmdp += 2;
299 break;
300 case '1':
301 page1 = true;
302 cmdp++;
303 break;
304 default:
305 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
306 errors = true;
307 break;
308 }
309 }
310 if (errors) return usage_t55xx_read();
311
312 if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) {
313 PrintAndLog("Block must be between 0 and 7");
314 return 0;
315 }
316 PrintAndLog("Reading Page %d:", page1);
317 PrintAndLog("blk | hex data | binary");
318 return T55xxReadBlock(block, page1, usepwd, override, password);
319 }
320
321 bool DecodeT55xxBlock(){
322
323 char buf[30] = {0x00};
324 char *cmdStr = buf;
325 int ans = 0;
326 uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
327 DemodBufferLen = 0x00;
328
329 switch( config.modulation ){
330 case DEMOD_FSK:
331 snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );
332 ans = FSKrawDemod(cmdStr, FALSE);
333 break;
334 case DEMOD_FSK1:
335 case DEMOD_FSK1a:
336 snprintf(cmdStr, sizeof(buf),"%d %d 8 5", bitRate[config.bitrate], config.inverted );
337 ans = FSKrawDemod(cmdStr, FALSE);
338 break;
339 case DEMOD_FSK2:
340 case DEMOD_FSK2a:
341 snprintf(cmdStr, sizeof(buf),"%d %d 10 8", bitRate[config.bitrate], config.inverted );
342 ans = FSKrawDemod(cmdStr, FALSE);
343 break;
344 case DEMOD_ASK:
345 snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
346 ans = ASKDemod(cmdStr, FALSE, FALSE, 1);
347 break;
348 case DEMOD_PSK1:
349 snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
350 ans = PSKDemod(cmdStr, FALSE);
351 break;
352 case DEMOD_PSK2: //inverted won't affect this
353 case DEMOD_PSK3: //not fully implemented
354 snprintf(cmdStr, sizeof(buf),"%d 0 1", bitRate[config.bitrate] );
355 ans = PSKDemod(cmdStr, FALSE);
356 psk1TOpsk2(DemodBuffer, DemodBufferLen);
357 break;
358 case DEMOD_NRZ:
359 snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );
360 ans = NRZrawDemod(cmdStr, FALSE);
361 break;
362 case DEMOD_BI:
363 case DEMOD_BIa:
364 snprintf(cmdStr, sizeof(buf),"0 %d %d 0", bitRate[config.bitrate], config.inverted );
365 ans = ASKbiphaseDemod(cmdStr, FALSE);
366 break;
367 default:
368 return FALSE;
369 }
370 return (bool) ans;
371 }
372
373 int CmdT55xxDetect(const char *Cmd){
374
375 bool override = false;
376 //bool pwdmode = false;
377
378 uint32_t password = 0; //default to blank Block 7
379 bool usepwd = ( strlen(Cmd) > 0);
380 if ( usepwd ){
381 password = param_get32ex(Cmd, 0, 0, 16);
382 if (param_getchar(Cmd, 1) =='o' )
383 override = true;
384 }
385
386 char cmdp = param_getchar(Cmd, 0);
387 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_detect();
388
389 if (strlen(Cmd)==0) {
390 password = param_get32ex(Cmd, 0, 0, 16);
391 if (param_getchar(Cmd, 1) =='o' ) override = true;
392 }
393
394 if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) )
395 return 0;
396
397 if ( !tryDetectModulation() )
398 PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
399
400 return 1;
401 }
402
403 // detect configuration?
404 bool tryDetectModulation(){
405 uint8_t hits = 0;
406 t55xx_conf_block_t tests[15];
407 int bitRate=0;
408 uint8_t fc1 = 0, fc2 = 0, clk=0;
409 save_restoreGB(1);
410 if (GetFskClock("", FALSE, FALSE)){
411 fskClocks(&fc1, &fc2, &clk, FALSE);
412 if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
413 tests[hits].modulation = DEMOD_FSK;
414 if (fc1==8 && fc2 == 5)
415 tests[hits].modulation = DEMOD_FSK1a;
416 else if (fc1==10 && fc2 == 8)
417 tests[hits].modulation = DEMOD_FSK2;
418 tests[hits].bitrate = bitRate;
419 tests[hits].inverted = FALSE;
420 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
421 ++hits;
422 }
423 if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)) {
424 tests[hits].modulation = DEMOD_FSK;
425 if (fc1 == 8 && fc2 == 5)
426 tests[hits].modulation = DEMOD_FSK1;
427 else if (fc1 == 10 && fc2 == 8)
428 tests[hits].modulation = DEMOD_FSK2a;
429
430 tests[hits].bitrate = bitRate;
431 tests[hits].inverted = TRUE;
432 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
433 ++hits;
434 }
435 } else {
436 clk = GetAskClock("", FALSE, FALSE);
437 if (clk>0) {
438 if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
439 tests[hits].modulation = DEMOD_ASK;
440 tests[hits].bitrate = bitRate;
441 tests[hits].inverted = FALSE;
442 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
443 ++hits;
444 }
445 if ( ASKDemod("0 1 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
446 tests[hits].modulation = DEMOD_ASK;
447 tests[hits].bitrate = bitRate;
448 tests[hits].inverted = TRUE;
449 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
450 ++hits;
451 }
452 if ( ASKbiphaseDemod("0 0 0 0", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) {
453 tests[hits].modulation = DEMOD_BI;
454 tests[hits].bitrate = bitRate;
455 tests[hits].inverted = FALSE;
456 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
457 ++hits;
458 }
459 if ( ASKbiphaseDemod("0 0 1 0", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) {
460 tests[hits].modulation = DEMOD_BIa;
461 tests[hits].bitrate = bitRate;
462 tests[hits].inverted = TRUE;
463 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
464 ++hits;
465 }
466 }
467 //undo trim from ask
468 save_restoreGB(0);
469 clk = GetNrzClock("", FALSE, FALSE);
470 if (clk>0) {
471 if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
472 tests[hits].modulation = DEMOD_NRZ;
473 tests[hits].bitrate = bitRate;
474 tests[hits].inverted = FALSE;
475 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
476 ++hits;
477 }
478
479 if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
480 tests[hits].modulation = DEMOD_NRZ;
481 tests[hits].bitrate = bitRate;
482 tests[hits].inverted = TRUE;
483 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
484 ++hits;
485 }
486 }
487
488 //undo trim from nrz
489 save_restoreGB(0);
490 clk = GetPskClock("", FALSE, FALSE);
491 if (clk>0) {
492 if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
493 tests[hits].modulation = DEMOD_PSK1;
494 tests[hits].bitrate = bitRate;
495 tests[hits].inverted = FALSE;
496 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
497 ++hits;
498 }
499 if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
500 tests[hits].modulation = DEMOD_PSK1;
501 tests[hits].bitrate = bitRate;
502 tests[hits].inverted = TRUE;
503 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
504 ++hits;
505 }
506 // PSK2 - needs a call to psk1TOpsk2.
507 if ( PSKDemod("0 0 1", FALSE)) {
508 psk1TOpsk2(DemodBuffer, DemodBufferLen);
509 if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){
510 tests[hits].modulation = DEMOD_PSK2;
511 tests[hits].bitrate = bitRate;
512 tests[hits].inverted = FALSE;
513 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
514 ++hits;
515 }
516 } // inverse waves does not affect this demod
517 // PSK3 - needs a call to psk1TOpsk2.
518 if ( PSKDemod("0 0 1", FALSE)) {
519 psk1TOpsk2(DemodBuffer, DemodBufferLen);
520 if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){
521 tests[hits].modulation = DEMOD_PSK3;
522 tests[hits].bitrate = bitRate;
523 tests[hits].inverted = FALSE;
524 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
525 ++hits;
526 }
527 } // inverse waves does not affect this demod
528 }
529 }
530 if ( hits == 1) {
531 config.modulation = tests[0].modulation;
532 config.bitrate = tests[0].bitrate;
533 config.inverted = tests[0].inverted;
534 config.offset = tests[0].offset;
535 config.block0 = tests[0].block0;
536 printConfiguration( config );
537 return TRUE;
538 }
539
540 if ( hits > 1) {
541 PrintAndLog("Found [%d] possible matches for modulation.",hits);
542 for(int i=0; i<hits; ++i){
543 PrintAndLog("--[%d]---------------", i+1);
544 printConfiguration( tests[i] );
545 }
546 }
547 return FALSE;
548 }
549
550 bool testModulation(uint8_t mode, uint8_t modread){
551 switch( mode ){
552 case DEMOD_FSK:
553 if (modread > 3 && modread < 8) return TRUE;
554 break;
555 case DEMOD_ASK:
556 if (modread == DEMOD_ASK) return TRUE;
557 break;
558 case DEMOD_PSK1:
559 if (modread == DEMOD_PSK1) return TRUE;
560 break;
561 case DEMOD_PSK2:
562 if (modread == DEMOD_PSK2) return TRUE;
563 break;
564 case DEMOD_PSK3:
565 if (modread == DEMOD_PSK3) return TRUE;
566 break;
567 case DEMOD_NRZ:
568 if (modread == DEMOD_NRZ) return TRUE;
569 break;
570 case DEMOD_BI:
571 if (modread == DEMOD_BI) return TRUE;
572 break;
573 case DEMOD_BIa:
574 if (modread == DEMOD_BIa) return TRUE;
575 break;
576 default:
577 return FALSE;
578 }
579 return FALSE;
580 }
581
582 bool testBitRate(uint8_t readRate, uint8_t mod){
583 uint8_t expected[8] = {8, 16, 32, 40, 50, 64, 100, 128};
584 uint8_t detRate = 0;
585 switch( mod ){
586 case DEMOD_FSK:
587 case DEMOD_FSK1:
588 case DEMOD_FSK1a:
589 case DEMOD_FSK2:
590 case DEMOD_FSK2a:
591 detRate = GetFskClock("",FALSE, FALSE);
592 if (expected[readRate] == detRate)
593 return TRUE;
594 break;
595 case DEMOD_ASK:
596 case DEMOD_BI:
597 case DEMOD_BIa:
598 detRate = GetAskClock("",FALSE, FALSE);
599 if (expected[readRate] == detRate)
600 return TRUE;
601 break;
602 case DEMOD_PSK1:
603 case DEMOD_PSK2:
604 case DEMOD_PSK3:
605 detRate = GetPskClock("",FALSE, FALSE);
606 if (expected[readRate] == detRate)
607 return TRUE;
608 break;
609 case DEMOD_NRZ:
610 detRate = GetNrzClock("",FALSE, FALSE);
611 if (expected[readRate] == detRate)
612 return TRUE;
613 break;
614 default:
615 return FALSE;
616 }
617 return FALSE;
618 }
619
620 bool test(uint8_t mode, uint8_t *offset, int *fndBitRate){
621
622 if ( DemodBufferLen < 64 ) return FALSE;
623 uint8_t si = 0;
624 for (uint8_t idx = 0; idx < 64; idx++){
625 si = idx;
626 if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue;
627
628 uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key
629 uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode
630 // 2nibble must be zeroed.
631 // moved test to here, since this gets most faults first.
632 if ( resv > 0x00) continue;
633
634 uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate
635 int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate
636 if (bitRate > 7) continue;
637 uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode
638 uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1;
639 //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr
640 uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode
641 uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;
642
643 //if extended mode
644 bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? TRUE : FALSE;
645
646 if (!extMode){
647 if (nml01 || nml02 || xtRate) continue;
648 }
649 //test modulation
650 if (!testModulation(mode, modread)) continue;
651 if (!testBitRate(bitRate, mode)) continue;
652 *fndBitRate = bitRate;
653 *offset = idx;
654 return TRUE;
655 }
656 return FALSE;
657 }
658
659 void printT55xxBlock(const char *blockNum){
660
661 uint8_t i = config.offset;
662 uint8_t endpos = 32 + i;
663 uint32_t blockData = 0;
664 uint8_t bits[64] = {0x00};
665
666 if ( !DemodBufferLen) return;
667
668 if ( endpos > DemodBufferLen){
669 PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i, DemodBufferLen-32);
670 return;
671 }
672
673 for (; i < endpos; ++i)
674 bits[i - config.offset] = DemodBuffer[i];
675
676 blockData = PackBits(0, 32, bits);
677 PrintAndLog("%s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));
678 }
679
680 int special(const char *Cmd) {
681 uint32_t blockData = 0;
682 uint8_t bits[32] = {0x00};
683
684 PrintAndLog("OFFSET | DATA | BINARY");
685 PrintAndLog("----------------------------------------------------");
686 int i,j = 0;
687 for (; j < 64; ++j){
688
689 for (i = 0; i < 32; ++i)
690 bits[i]=DemodBuffer[j+i];
691
692 blockData = PackBits(0, 32, bits);
693
694 PrintAndLog("%02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32));
695 }
696 return 0;
697 }
698
699 int printConfiguration( t55xx_conf_block_t b){
700 PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
701 PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
702 PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
703 PrintAndLog("Offset : %d", b.offset);
704 PrintAndLog("Block0 : 0x%08X", b.block0);
705 PrintAndLog("");
706 return 0;
707 }
708
709 int CmdT55xxWakeUp(const char *Cmd) {
710 uint32_t password = 0;
711 uint8_t cmdp = 0;
712 bool errors = false;
713 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
714 switch(param_getchar(Cmd, cmdp)) {
715 case 'h':
716 case 'H':
717 return usage_t55xx_wakup();
718 case 'p':
719 case 'P':
720 password = param_get32ex(Cmd, cmdp+1, 0, 16);
721 cmdp += 2;
722 errors = false;
723 break;
724 default:
725 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
726 errors = true;
727 break;
728 }
729 }
730 if (errors) return usage_t55xx_wakup();
731
732 UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};
733 clearCommandBuffer();
734 SendCommand(&c);
735 PrintAndLog("Wake up command sent. Try read now");
736 return 0;
737 }
738
739 int CmdT55xxWriteBlock(const char *Cmd) {
740 uint8_t block = 0xFF; //default to invalid block
741 uint32_t data = 0; //default to blank Block
742 uint32_t password = 0; //default to blank Block 7
743 bool usepwd = false;
744 bool page1 = false;
745 bool gotdata = false;
746 bool errors = false;
747 uint8_t cmdp = 0;
748 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
749 switch(param_getchar(Cmd, cmdp)) {
750 case 'h':
751 case 'H':
752 return usage_t55xx_write();
753 case 'b':
754 case 'B':
755 errors |= param_getdec(Cmd, cmdp+1, &block);
756 cmdp += 2;
757 break;
758 case 'd':
759 case 'D':
760 data = param_get32ex(Cmd, cmdp+1, 0, 16);
761 gotdata = true;
762 cmdp += 2;
763 break;
764 case 'p':
765 case 'P':
766 password = param_get32ex(Cmd, cmdp+1, 0, 16);
767 usepwd = true;
768 cmdp += 2;
769 break;
770 case '1':
771 page1 = true;
772 cmdp++;
773 break;
774 default:
775 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
776 errors = true;
777 break;
778 }
779 }
780 if (errors || !gotdata) return usage_t55xx_write();
781
782 if (block > 7) {
783 PrintAndLog("Block number must be between 0 and 7");
784 return 0;
785 }
786
787 UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
788 UsbCommand resp;
789 c.d.asBytes[0] = (page1) ? 0x2 : 0;
790
791 PrintAndLog("Writing to page: %d block: %d data : 0x%08X", page1, block, data);
792
793 //Password mode
794 if (usepwd) {
795 c.arg[2] = password;
796 c.d.asBytes[0] |= 0x1;
797 PrintAndLog("pwd : 0x%08X", password);
798 }
799 clearCommandBuffer();
800 SendCommand(&c);
801 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
802 PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
803 return 0;
804 }
805 return 1;
806 }
807
808 int CmdT55xxReadTrace(const char *Cmd) {
809 char cmdp = param_getchar(Cmd, 0);
810 bool pwdmode = false;
811 uint32_t password = 0;
812 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_trace();
813
814 if (strlen(Cmd)==0)
815 if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )
816 return 0;
817
818 if (!DecodeT55xxBlock()) return 0;
819
820 if ( !DemodBufferLen) return 0;
821
822 RepaintGraphWindow();
823 uint8_t repeat = 0;
824 if (config.offset > 5)
825 repeat = 32;
826 uint8_t si = config.offset+repeat;
827 uint32_t bl1 = PackBits(si, 32, DemodBuffer);
828 uint32_t bl2 = PackBits(si+32, 32, DemodBuffer);
829
830 uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
831 uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
832 uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5;
833 uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3;
834 uint32_t year = PackBits(si, 4, DemodBuffer); si += 4;
835 uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2;
836 uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14;
837 uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5;
838 uint32_t dw = PackBits(si, 15, DemodBuffer);
839
840 time_t t = time(NULL);
841 struct tm tm = *localtime(&t);
842 if ( year > tm.tm_year-110)
843 year += 2000;
844 else
845 year += 2010;
846
847 if ( acl != 0xE0 ) {
848 PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
849 return 0;
850 }
851
852 PrintAndLog("");
853 PrintAndLog("-- T55xx Trace Information ----------------------------------");
854 PrintAndLog("-------------------------------------------------------------");
855 PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl);
856 PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", mfc, mfc, getTagInfo(mfc));
857 PrintAndLog(" CID : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid));
858 PrintAndLog(" ICR IC Revision : %d",icr );
859 PrintAndLog(" Manufactured");
860 PrintAndLog(" Year/Quarter : %d/%d",year, quarter);
861 PrintAndLog(" Lot ID : %d", lotid );
862 PrintAndLog(" Wafer number : %d", wafer);
863 PrintAndLog(" Die Number : %d", dw);
864 PrintAndLog("-------------------------------------------------------------");
865 PrintAndLog(" Raw Data - Page 1");
866 PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );
867 PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
868 PrintAndLog("-------------------------------------------------------------");
869
870 /*
871 TRACE - BLOCK O
872 Bits Definition HEX
873 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0
874 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation
875 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2
876 22-24 ICR IC revision
877 25-28 YEAR (BCD encoded) 9 (= 2009)
878 29-30 QUARTER 1,2,3,4
879 31-32 LOT ID
880
881 TRACE - BLOCK 1
882 1-12 LOT ID
883 13-17 Wafer number
884 18-32 DW, die number sequential
885 */
886
887 return 0;
888 }
889
890 int CmdT55xxInfo(const char *Cmd){
891 /*
892 Page 0 Block 0 Configuration data.
893 Normal mode
894 Extended mode
895 */
896 bool pwdmode = false;
897 uint32_t password = 0;
898 char cmdp = param_getchar(Cmd, 0);
899
900 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_info();
901
902 if (strlen(Cmd)==0)
903 if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password ) )
904 return 1;
905
906 if (!DecodeT55xxBlock()) return 1;
907
908 if ( DemodBufferLen < 32) return 1;
909
910 uint8_t si = config.offset;
911 uint32_t bl0 = PackBits(si, 32, DemodBuffer);
912
913 uint32_t safer = PackBits(si, 4, DemodBuffer); si += 4;
914 uint32_t resv = PackBits(si, 7, DemodBuffer); si += 7;
915 uint32_t dbr = PackBits(si, 3, DemodBuffer); si += 3;
916 uint32_t extend = PackBits(si, 1, DemodBuffer); si += 1;
917 uint32_t datamod = PackBits(si, 5, DemodBuffer); si += 5;
918 uint32_t pskcf = PackBits(si, 2, DemodBuffer); si += 2;
919 uint32_t aor = PackBits(si, 1, DemodBuffer); si += 1;
920 uint32_t otp = PackBits(si, 1, DemodBuffer); si += 1;
921 uint32_t maxblk = PackBits(si, 3, DemodBuffer); si += 3;
922 uint32_t pwd = PackBits(si, 1, DemodBuffer); si += 1;
923 uint32_t sst = PackBits(si, 1, DemodBuffer); si += 1;
924 uint32_t fw = PackBits(si, 1, DemodBuffer); si += 1;
925 uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1;
926 uint32_t por = PackBits(si, 1, DemodBuffer); si += 1;
927
928 PrintAndLog("");
929 PrintAndLog("-- T55xx Configuration & Tag Information --------------------");
930 PrintAndLog("-------------------------------------------------------------");
931 PrintAndLog(" Safer key : %s", GetSaferStr(safer));
932 PrintAndLog(" reserved : %d", resv);
933 PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));
934 PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");
935 PrintAndLog(" Modulation : %s", GetModulationStr(datamod));
936 PrintAndLog(" PSK clock frequency : %d", pskcf);
937 PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No");
938 PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" );
939 PrintAndLog(" Max block : %d", maxblk);
940 PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No");
941 PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");
942 PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No");
943 PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No");
944 PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No");
945 PrintAndLog("-------------------------------------------------------------");
946 PrintAndLog(" Raw Data - Page 0");
947 PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset,32) );
948 PrintAndLog("-------------------------------------------------------------");
949
950 return 0;
951 }
952
953 int CmdT55xxDump(const char *Cmd){
954
955 uint32_t password = 0;
956 bool override = false;
957 char cmdp = param_getchar(Cmd, 0);
958 if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();
959
960 bool usepwd = ( strlen(Cmd) > 0);
961 if ( usepwd ){
962 password = param_get32ex(Cmd, 0, 0, 16);
963 if (param_getchar(Cmd, 1) =='o' )
964 override = true;
965 }
966
967 PrintAndLog("Reading Page 0:");
968 PrintAndLog("blk | hex data | binary");
969 for ( uint8_t i = 0; i < 8; ++i){
970 T55xxReadBlock(i, 0, usepwd, override, password);
971 }
972 PrintAndLog("Reading Page 1:");
973 PrintAndLog("blk | hex data | binary");
974 for ( uint8_t i = 0; i < 4; i++){
975 T55xxReadBlock(i, 1, usepwd, override, password);
976 }
977 return 1;
978 }
979
980 int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
981 // arg0 bitmodes:
982 // bit0 = pwdmode
983 // bit1 = page to read from
984 uint8_t arg0 = (page<<1) | pwdmode;
985 UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
986
987 clearCommandBuffer();
988 SendCommand(&c);
989 if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
990 PrintAndLog("command execution time out");
991 return 0;
992 }
993
994 uint8_t got[12000];
995 GetFromBigBuf(got,sizeof(got),0);
996 WaitForResponse(CMD_ACK,NULL);
997 setGraphBuf(got, sizeof(got));
998 return 1;
999 }
1000
1001 char * GetBitRateStr(uint32_t id){
1002 static char buf[25];
1003
1004 char *retStr = buf;
1005 switch (id){
1006 case 0:
1007 snprintf(retStr,sizeof(buf),"%d - RF/8",id);
1008 break;
1009 case 1:
1010 snprintf(retStr,sizeof(buf),"%d - RF/16",id);
1011 break;
1012 case 2:
1013 snprintf(retStr,sizeof(buf),"%d - RF/32",id);
1014 break;
1015 case 3:
1016 snprintf(retStr,sizeof(buf),"%d - RF/40",id);
1017 break;
1018 case 4:
1019 snprintf(retStr,sizeof(buf),"%d - RF/50",id);
1020 break;
1021 case 5:
1022 snprintf(retStr,sizeof(buf),"%d - RF/64",id);
1023 break;
1024 case 6:
1025 snprintf(retStr,sizeof(buf),"%d - RF/100",id);
1026 break;
1027 case 7:
1028 snprintf(retStr,sizeof(buf),"%d - RF/128",id);
1029 break;
1030 default:
1031 snprintf(retStr,sizeof(buf),"%d - (Unknown)",id);
1032 break;
1033 }
1034
1035 return buf;
1036 }
1037
1038 char * GetSaferStr(uint32_t id){
1039 static char buf[40];
1040 char *retStr = buf;
1041
1042 snprintf(retStr,sizeof(buf),"%d",id);
1043 if (id == 6) {
1044 snprintf(retStr,sizeof(buf),"%d - passwd",id);
1045 }
1046 if (id == 9 ){
1047 snprintf(retStr,sizeof(buf),"%d - testmode",id);
1048 }
1049
1050 return buf;
1051 }
1052
1053 char * GetModulationStr( uint32_t id){
1054 static char buf[60];
1055 char *retStr = buf;
1056
1057 switch (id){
1058 case 0:
1059 snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id);
1060 break;
1061 case 1:
1062 snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id);
1063 break;
1064 case 2:
1065 snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id);
1066 break;
1067 case 3:
1068 snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id);
1069 break;
1070 case 4:
1071 snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id);
1072 break;
1073 case 5:
1074 snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id);
1075 break;
1076 case 6:
1077 snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id);
1078 break;
1079 case 7:
1080 snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id);
1081 break;
1082 case 8:
1083 snprintf(retStr,sizeof(buf),"%d - Manchester",id);
1084 break;
1085 case 16:
1086 snprintf(retStr,sizeof(buf),"%d - Biphase",id);
1087 break;
1088 case 0x18:
1089 snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);
1090 break;
1091 case 17:
1092 snprintf(retStr,sizeof(buf),"%d - Reserved",id);
1093 break;
1094 default:
1095 snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id);
1096 break;
1097 }
1098 return buf;
1099 }
1100
1101 char * GetModelStrFromCID(uint32_t cid){
1102
1103 static char buf[10];
1104 char *retStr = buf;
1105
1106 if (cid == 1) snprintf(retStr, sizeof(buf),"ATA5577M1");
1107 if (cid == 2) snprintf(retStr, sizeof(buf),"ATA5577M2");
1108 return buf;
1109 }
1110
1111 char * GetSelectedModulationStr( uint8_t id){
1112
1113 static char buf[20];
1114 char *retStr = buf;
1115
1116 switch (id){
1117 case DEMOD_FSK:
1118 snprintf(retStr,sizeof(buf),"FSK");
1119 break;
1120 case DEMOD_FSK1:
1121 snprintf(retStr,sizeof(buf),"FSK1");
1122 break;
1123 case DEMOD_FSK1a:
1124 snprintf(retStr,sizeof(buf),"FSK1a");
1125 break;
1126 case DEMOD_FSK2:
1127 snprintf(retStr,sizeof(buf),"FSK2");
1128 break;
1129 case DEMOD_FSK2a:
1130 snprintf(retStr,sizeof(buf),"FSK2a");
1131 break;
1132 case DEMOD_ASK:
1133 snprintf(retStr,sizeof(buf),"ASK");
1134 break;
1135 case DEMOD_NRZ:
1136 snprintf(retStr,sizeof(buf),"DIRECT/NRZ");
1137 break;
1138 case DEMOD_PSK1:
1139 snprintf(retStr,sizeof(buf),"PSK1");
1140 break;
1141 case DEMOD_PSK2:
1142 snprintf(retStr,sizeof(buf),"PSK2");
1143 break;
1144 case DEMOD_PSK3:
1145 snprintf(retStr,sizeof(buf),"PSK3");
1146 break;
1147 case DEMOD_BI:
1148 snprintf(retStr,sizeof(buf),"BIPHASE");
1149 break;
1150 case DEMOD_BIa:
1151 snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)");
1152 break;
1153 default:
1154 snprintf(retStr,sizeof(buf),"(Unknown)");
1155 break;
1156 }
1157 return buf;
1158 }
1159
1160 void t55x7_create_config_block( int tagtype ){
1161 //switch?
1162
1163
1164 }
1165
1166 /*
1167 uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
1168
1169 int i = start;
1170 int j = len-1;
1171
1172 if (len > 32) return 0;
1173
1174 uint32_t tmp = 0;
1175 for (; j >= 0; --j, ++i)
1176 tmp |= bits[i] << j;
1177
1178 return tmp;
1179 }
1180 */
1181 static command_t CommandTable[] =
1182 {
1183 {"help", CmdHelp, 1, "This help"},
1184 {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
1185 {"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},
1186 {"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data (page 0) [optional password]"},
1187 {"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data (page 0) [optional password]"},
1188 {"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},
1189 {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},
1190 {"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. [optional password]"},
1191 {"special", special, 0, "Show block changes with 64 different offsets"},
1192 {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
1193 {NULL, NULL, 0, NULL}
1194 };
1195
1196 int CmdLFT55XX(const char *Cmd)
1197 {
1198 CmdsParse(CommandTable, Cmd);
1199 return 0;
1200 }
1201
1202 int CmdHelp(const char *Cmd)
1203 {
1204 CmdsHelp(CommandTable);
1205 return 0;
1206 }
Impressum, Datenschutz