1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // Low frequency commands 
   9 //----------------------------------------------------------------------------- 
  15 #include "proxmark3.h" 
  17 #include "lfdemod.h"     // for psk2TOpsk1 
  18 #include "util.h"        // for parsing cli command utils 
  19 #include "ui.h"          // for show graph controls 
  20 #include "graph.h"       // for graph data 
  21 #include "cmdparser.h"   // for getting cli commands included in cmdmain.h 
  22 #include "cmdmain.h"     // for sending cmds to device 
  23 #include "data.h"        // for GetFromBigBuf 
  24 #include "cmddata.h"     // for `lf search` 
  25 #include "cmdlfawid.h"   // for awid menu 
  26 #include "cmdlfem4x.h"   // for em4x menu 
  27 #include "cmdlfhid.h"    // for hid menu 
  28 #include "cmdlfhitag.h"  // for hitag menu 
  29 #include "cmdlfio.h"     // for ioprox menu 
  30 #include "cmdlft55xx.h"  // for t55xx menu 
  31 #include "cmdlfti.h"     // for ti menu 
  32 #include "cmdlfpresco.h" // for presco menu 
  33 #include "cmdlfpcf7931.h"// for pcf7931 menu 
  34 #include "cmdlfpyramid.h"// for pyramid menu 
  35 #include "cmdlfviking.h" // for viking menu 
  36 #include "cmdlfcotag.h"  // for COTAG menu 
  39 static int CmdHelp(const char *Cmd
); 
  43 int usage_lf_cmdread(void) 
  45         PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] "); 
  46         PrintAndLog("Options:        "); 
  47         PrintAndLog("       h             This help"); 
  48         PrintAndLog("       L             Low frequency (125 KHz)"); 
  49         PrintAndLog("       H             High frequency (134 KHz)"); 
  50         PrintAndLog("       d <delay>     delay OFF period"); 
  51         PrintAndLog("       z <zero>      time period ZERO"); 
  52         PrintAndLog("       o <one>       time period ONE"); 
  53         PrintAndLog("       c <cmd>       Command bytes"); 
  54         PrintAndLog("       ************* All periods in microseconds"); 
  55         PrintAndLog("Examples:"); 
  56         PrintAndLog("      lf cmdread d 80 z 100 o 200 c 11000"); 
  57         PrintAndLog("      lf cmdread d 80 z 100 o 100 c 11000 H"); 
  61 /* send a command before reading */ 
  62 int CmdLFCommandRead(const char *Cmd
) 
  64         static char dummy
[3] = {0x20,0x00,0x00}; 
  65         UsbCommand c 
= {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
}; 
  67         //uint8_t divisor = 95; //125khz 
  69         while(param_getchar(Cmd
, cmdp
) != 0x00) 
  71                 switch(param_getchar(Cmd
, cmdp
)) 
  74                         return usage_lf_cmdread(); 
  84                         param_getstr(Cmd
, cmdp
+1, (char *)&c
.d
.asBytes
); 
  88                         c
.arg
[0] = param_get32ex(Cmd
, cmdp
+1, 0, 10); 
  92                         c
.arg
[1] = param_get32ex(Cmd
, cmdp
+1, 0, 10); 
  96                         c
.arg
[2] = param_get32ex(Cmd
, cmdp
+1, 0, 10); 
 100                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 107         if(cmdp 
== 0) errors 
= 1; 
 110         if(errors
) return usage_lf_cmdread(); 
 112         // in case they specified 'H' 
 113         strcpy((char *)&c
.d
.asBytes 
+ strlen((char *)c
.d
.asBytes
), dummy
); 
 115         clearCommandBuffer(); 
 120 int CmdFlexdemod(const char *Cmd
) 
 123         for (i 
= 0; i 
< GraphTraceLen
; ++i
) { 
 124                 if (GraphBuffer
[i
] < 0) { 
 131  #define LONG_WAIT 100 
 133         for (start 
= 0; start 
< GraphTraceLen 
- LONG_WAIT
; start
++) { 
 134                 int first 
= GraphBuffer
[start
]; 
 135                 for (i 
= start
; i 
< start 
+ LONG_WAIT
; i
++) { 
 136                         if (GraphBuffer
[i
] != first
) { 
 140                 if (i 
== (start 
+ LONG_WAIT
)) { 
 144         if (start 
== GraphTraceLen 
- LONG_WAIT
) { 
 145                 PrintAndLog("nothing to wait for"); 
 149         GraphBuffer
[start
] = 2; 
 150         GraphBuffer
[start
+1] = -2; 
 151         uint8_t bits
[64] = {0x00}; 
 155         for (bit 
= 0; bit 
< 64; bit
++) { 
 157                 for (int j 
= 0; j 
< 16; j
++) { 
 158                         sum 
+= GraphBuffer
[i
++]; 
 161                 bits
[bit
] = (sum 
> 0) ? 1 : 0; 
 163                 PrintAndLog("bit %d sum %d", bit
, sum
); 
 166         for (bit 
= 0; bit 
< 64; bit
++) { 
 169                 for (j 
= 0; j 
< 16; j
++) { 
 170                         sum 
+= GraphBuffer
[i
++]; 
 172                 if (sum 
> 0 && bits
[bit
] != 1) { 
 173                         PrintAndLog("oops1 at %d", bit
); 
 175                 if (sum 
< 0 && bits
[bit
] != 0) { 
 176                         PrintAndLog("oops2 at %d", bit
); 
 180         // HACK writing back to graphbuffer. 
 181         GraphTraceLen 
= 32*64; 
 184         for (bit 
= 0; bit 
< 64; bit
++) { 
 186                 phase 
= (bits
[bit
] == 0) ? 0 : 1; 
 189                 for (j 
= 0; j 
< 32; j
++) { 
 190                         GraphBuffer
[i
++] = phase
; 
 195         RepaintGraphWindow(); 
 199 int CmdIndalaDemod(const char *Cmd
) 
 201         // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID 
 207         // worst case with GraphTraceLen=64000 is < 4096 
 208         // under normal conditions it's < 2048 
 210         uint8_t rawbits
[4096]; 
 212         int worst 
= 0, worstPos 
= 0; 
 213         // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); 
 215         // loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2) 
 216         for (i 
= 0; i 
< GraphTraceLen
-1; i 
+= 2) { 
 218                 if ((GraphBuffer
[i
] > GraphBuffer
[i 
+ 1]) && (state 
!= 1)) { 
 219                         // appears redundant - marshmellow 
 221                                 for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 222                                         rawbits
[rawbit
++] = 0; 
 224                                 if ((abs(count 
- j
)) > worst
) { 
 225                                         worst 
= abs(count 
- j
); 
 231                 } else if ((GraphBuffer
[i
] < GraphBuffer
[i 
+ 1]) && (state 
!= 0)) { 
 234                                 for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 235                                         rawbits
[rawbit
++] = 1; 
 237                                 if ((abs(count 
- j
)) > worst
) { 
 238                                         worst 
= abs(count 
- j
); 
 248                 PrintAndLog("Recovered %d raw bits, expected: %d", rawbit
, GraphTraceLen
/32); 
 249                 PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst
, worstPos
); 
 254         // Finding the start of a UID 
 255         int uidlen
, long_wait
; 
 256         if (strcmp(Cmd
, "224") == 0) { 
 266         for (start 
= 0; start 
<= rawbit 
- uidlen
; start
++) { 
 267                 first 
= rawbits
[start
]; 
 268                 for (i 
= start
; i 
< start 
+ long_wait
; i
++) { 
 269                         if (rawbits
[i
] != first
) { 
 273                 if (i 
== (start 
+ long_wait
)) { 
 278         if (start 
== rawbit 
- uidlen 
+ 1) { 
 279                 PrintAndLog("nothing to wait for"); 
 283         // Inverting signal if needed 
 285                 for (i 
= start
; i 
< rawbit
; i
++) { 
 286                         rawbits
[i
] = !rawbits
[i
]; 
 291         uint8_t bits
[224] = {0x00}; 
 292         char showbits
[225] = {0x00}; 
 297         if (uidlen 
> rawbit
) { 
 298                 PrintAndLog("Warning: not enough raw bits to get a full UID"); 
 299                 for (bit 
= 0; bit 
< rawbit
; bit
++) { 
 300                         bits
[bit
] = rawbits
[i
++]; 
 301                         // As we cannot know the parity, let's use "." and "/" 
 302                         showbits
[bit
] = '.' + bits
[bit
]; 
 304                 showbits
[bit
+1]='\0'; 
 305                 PrintAndLog("Partial UID=%s", showbits
); 
 308                 for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 309                         bits
[bit
] = rawbits
[i
++]; 
 310                         showbits
[bit
] = '0' + bits
[bit
]; 
 316         uint32_t uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 321                 for( idx
=0; idx
<64; idx
++) { 
 322                                 if (showbits
[idx
] == '0') { 
 323                                 uid1
=(uid1
<<1)|(uid2
>>31); 
 326                                 uid1
=(uid1
<<1)|(uid2
>>31); 
 330                 PrintAndLog("UID=%s (%x%08x)", showbits
, uid1
, uid2
); 
 333                 uid3 
= uid4 
= uid5 
= uid6 
= uid7 
= 0; 
 335                 for( idx
=0; idx
<224; idx
++) { 
 336                                 uid1
=(uid1
<<1)|(uid2
>>31); 
 337                                 uid2
=(uid2
<<1)|(uid3
>>31); 
 338                                 uid3
=(uid3
<<1)|(uid4
>>31); 
 339                                 uid4
=(uid4
<<1)|(uid5
>>31); 
 340                                 uid5
=(uid5
<<1)|(uid6
>>31); 
 341                                 uid6
=(uid6
<<1)|(uid7
>>31); 
 343                         if (showbits
[idx
] == '0')  
 344                                 uid7 
= (uid7
<<1) | 0; 
 346                                 uid7 
= (uid7
<<1) | 1; 
 348                 PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits
, uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 351         // Checking UID against next occurrences 
 353         for (; i 
+ uidlen 
<= rawbit
;) { 
 355                 for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 356                         if (bits
[bit
] != rawbits
[i
++]) { 
 367         PrintAndLog("Occurrences: %d (expected %d)", times
, (rawbit 
- start
) / uidlen
); 
 369         // Remodulating for tag cloning 
 370         // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)  
 371         // since this changes graphbuffer data. 
 372         GraphTraceLen 
= 32*uidlen
; 
 375         for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 376                 if (bits
[bit
] == 0) { 
 382                 for (j 
= 0; j 
< 32; j
++) { 
 383                         GraphBuffer
[i
++] = phase
; 
 388         RepaintGraphWindow(); 
 392 int CmdIndalaClone(const char *Cmd
) 
 395         unsigned int uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 397         uid1 
=  uid2 
= uid3 
= uid4 
= uid5 
= uid6 
= uid7 
= 0; 
 400         if (strchr(Cmd
,'l') != 0) { 
 401                 while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 402                         uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 403                         uid2 
= (uid2 
<< 4) | (uid3 
>> 28); 
 404                         uid3 
= (uid3 
<< 4) | (uid4 
>> 28); 
 405                         uid4 
= (uid4 
<< 4) | (uid5 
>> 28); 
 406                         uid5 
= (uid5 
<< 4) | (uid6 
>> 28); 
 407                         uid6 
= (uid6 
<< 4) | (uid7 
>> 28); 
 408                         uid7 
= (uid7 
<< 4) | (n 
& 0xf); 
 410                 PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 411                 c
.cmd 
= CMD_INDALA_CLONE_TAG_L
; 
 412                 c
.d
.asDwords
[0] = uid1
; 
 413                 c
.d
.asDwords
[1] = uid2
; 
 414                 c
.d
.asDwords
[2] = uid3
; 
 415                 c
.d
.asDwords
[3] = uid4
; 
 416                 c
.d
.asDwords
[4] = uid5
; 
 417                 c
.d
.asDwords
[5] = uid6
; 
 418                 c
.d
.asDwords
[6] = uid7
; 
 420                 while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 421                         uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 422                         uid2 
= (uid2 
<< 4) | (n 
& 0xf); 
 424                 PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1
, uid2
); 
 425                 c
.cmd 
= CMD_INDALA_CLONE_TAG
; 
 430         clearCommandBuffer(); 
 435 int usage_lf_read(void) 
 437         PrintAndLog("Usage: lf read"); 
 438         PrintAndLog("Options:        "); 
 439         PrintAndLog("       h            This help"); 
 440         PrintAndLog("       s            silent run no printout"); 
 441         PrintAndLog("This function takes no arguments. "); 
 442         PrintAndLog("Use 'lf config' to set parameters."); 
 445 int usage_lf_snoop(void) 
 447         PrintAndLog("Usage: lf snoop"); 
 448         PrintAndLog("Options:        "); 
 449         PrintAndLog("       h            This help"); 
 450         PrintAndLog("This function takes no arguments. "); 
 451         PrintAndLog("Use 'lf config' to set parameters."); 
 455 int usage_lf_config(void) 
 457         PrintAndLog("Usage: lf config [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]"); 
 458         PrintAndLog("Options:        "); 
 459         PrintAndLog("       h             This help"); 
 460         PrintAndLog("       L             Low frequency (125 KHz)"); 
 461         PrintAndLog("       H             High frequency (134 KHz)"); 
 462         PrintAndLog("       q <divisor>   Manually set divisor. 88-> 134KHz, 95-> 125 Hz"); 
 463         PrintAndLog("       b <bps>       Sets resolution of bits per sample. Default (max): 8"); 
 464         PrintAndLog("       d <decim>     Sets decimation. A value of N saves only 1 in N samples. Default: 1"); 
 465         PrintAndLog("       a [0|1]       Averaging - if set, will average the stored sample value when decimating. Default: 1"); 
 466         PrintAndLog("       t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)"); 
 467         PrintAndLog("Examples:"); 
 468         PrintAndLog("      lf config b 8 L"); 
 469         PrintAndLog("                    Samples at 125KHz, 8bps."); 
 470         PrintAndLog("      lf config H b 4 d 3"); 
 471         PrintAndLog("                    Samples at 134KHz, averages three samples into one, stored with "); 
 472         PrintAndLog("                    a resolution of 4 bits per sample."); 
 473         PrintAndLog("      lf read"); 
 474         PrintAndLog("                    Performs a read (active field)"); 
 475         PrintAndLog("      lf snoop"); 
 476         PrintAndLog("                    Performs a snoop (no active field)"); 
 480 int CmdLFSetConfig(const char *Cmd
) 
 483         uint8_t divisor 
=  0;//Frequency divisor 
 484         uint8_t bps 
= 0; // Bits per sample 
 485         uint8_t decimation 
= 0; //How many to keep 
 486         bool averaging 
= 1; // Defaults to true 
 488         int trigger_threshold 
=-1;//Means no change 
 489         uint8_t unsigned_trigg 
= 0; 
 492         while(param_getchar(Cmd
, cmdp
) != 0x00) 
 494                 switch(param_getchar(Cmd
, cmdp
)) 
 497                         return usage_lf_config(); 
 507                         errors 
|= param_getdec(Cmd
,cmdp
+1,&divisor
); 
 511                         errors 
|= param_getdec(Cmd
,cmdp
+1,&unsigned_trigg
); 
 513                         if(!errors
) trigger_threshold 
= unsigned_trigg
; 
 516                         errors 
|= param_getdec(Cmd
,cmdp
+1,&bps
); 
 520                         errors 
|= param_getdec(Cmd
,cmdp
+1,&decimation
); 
 524                         averaging 
= param_getchar(Cmd
,cmdp
+1) == '1'; 
 528                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 536                 errors 
= 1;// No args 
 542                 return usage_lf_config(); 
 544         //Bps is limited to 8, so fits in lower half of arg1 
 545         if(bps 
>> 4) bps 
= 8; 
 547         sample_config config 
= { 
 548                 decimation
,bps
,averaging
,divisor
,trigger_threshold
 
 550         //Averaging is a flag on high-bit of arg[1] 
 551         UsbCommand c 
= {CMD_SET_LF_SAMPLING_CONFIG
}; 
 552         memcpy(c
.d
.asBytes
,&config
,sizeof(sample_config
)); 
 553         clearCommandBuffer(); 
 558 int CmdLFRead(const char *Cmd
) 
 563         if (param_getchar(Cmd
, cmdp
) == 'h') 
 565                 return usage_lf_read(); 
 567         if (param_getchar(Cmd
, cmdp
) == 's') arg1 
= true; //suppress print 
 568         //And ship it to device 
 569         UsbCommand c 
= {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
, {arg1
,0,0}}; 
 570         clearCommandBuffer(); 
 572         //WaitForResponse(CMD_ACK,NULL);         
 573         if ( !WaitForResponseTimeout(CMD_ACK
,NULL
,2500) ) { 
 574                 PrintAndLog("command execution time out"); 
 581 int CmdLFSnoop(const char *Cmd
) 
 584         if(param_getchar(Cmd
, cmdp
) == 'h') 
 586                 return usage_lf_snoop(); 
 589         UsbCommand c 
= {CMD_LF_SNOOP_RAW_ADC_SAMPLES
}; 
 590         clearCommandBuffer(); 
 592         WaitForResponse(CMD_ACK
,NULL
); 
 596 static void ChkBitstream(const char *str
) 
 600         /* convert to bitstream if necessary */ 
 601         for (i 
= 0; i 
< (int)(GraphTraceLen 
/ 2); i
++){ 
 602                 if (GraphBuffer
[i
] > 1 || GraphBuffer
[i
] < 0) { 
 608 //Attempt to simulate any wave in buffer (one bit per output sample) 
 609 // converts GraphBuffer to bitstream (based on zero crossings) if needed. 
 610 int CmdLFSim(const char *Cmd
) 
 615         sscanf(Cmd
, "%i", &gap
); 
 617         // convert to bitstream if necessary  
 621         //can send only 512 bits at a time (1 byte sent per bit...) 
 622         printf("Sending [%d bytes]", GraphTraceLen
); 
 623         for (i 
= 0; i 
< GraphTraceLen
; i 
+= USB_CMD_DATA_SIZE
) { 
 624                 UsbCommand c
={CMD_DOWNLOADED_SIM_SAMPLES_125K
, {i
, 0, 0}}; 
 626                 for (j 
= 0; j 
< USB_CMD_DATA_SIZE
; j
++) { 
 627                         c
.d
.asBytes
[j
] = GraphBuffer
[i
+j
]; 
 630                 WaitForResponse(CMD_ACK
,NULL
); 
 635         PrintAndLog("Starting to simulate"); 
 636         UsbCommand c 
= {CMD_SIMULATE_TAG_125K
, {GraphTraceLen
, gap
, 0}}; 
 637         clearCommandBuffer(); 
 642 int usage_lf_simfsk(void) 
 645         PrintAndLog("Usage: lf simfsk [c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>]"); 
 646         PrintAndLog("Options:        "); 
 647         PrintAndLog("       h              This help"); 
 648         PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 649         PrintAndLog("       i              invert data"); 
 650         PrintAndLog("       H <fcHigh>     Manually set the larger Field Clock"); 
 651         PrintAndLog("       L <fcLow>      Manually set the smaller Field Clock"); 
 652         //PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap"); 
 653         PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 654         PrintAndLog("\n  NOTE: if you set one clock manually set them all manually"); 
 658 int usage_lf_simask(void) 
 661         PrintAndLog("Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]"); 
 662         PrintAndLog("Options:        "); 
 663         PrintAndLog("       h              This help"); 
 664         PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 665         PrintAndLog("       i              invert data"); 
 666         PrintAndLog("       b              sim ask/biphase"); 
 667         PrintAndLog("       m              sim ask/manchester - Default"); 
 668         PrintAndLog("       r              sim ask/raw"); 
 669         PrintAndLog("       s              add t55xx Sequence Terminator gap - default: no gaps (only manchester)"); 
 670         PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 674 int usage_lf_simpsk(void) 
 677         PrintAndLog("Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]"); 
 678         PrintAndLog("Options:        "); 
 679         PrintAndLog("       h              This help"); 
 680         PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 681         PrintAndLog("       i              invert data"); 
 682         PrintAndLog("       1              set PSK1 (default)"); 
 683         PrintAndLog("       2              set PSK2"); 
 684         PrintAndLog("       3              set PSK3"); 
 685         PrintAndLog("       r <carrier>    2|4|8 are valid carriers: default = 2"); 
 686         PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 690 // by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert  
 691 // - allow pull data from DemodBuffer 
 692 int CmdLFfskSim(const char *Cmd
) 
 694         //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer 
 695         // otherwise will need FChigh, FClow, Clock, and bitstream 
 696         uint8_t fcHigh
=0, fcLow
=0, clk
=0; 
 699         char hexData
[32] = {0x00}; // store entered hex data 
 700         uint8_t data
[255] = {0x00};  
 703         while(param_getchar(Cmd
, cmdp
) != 0x00) 
 705                 switch(param_getchar(Cmd
, cmdp
)) 
 708                         return usage_lf_simfsk(); 
 714                         errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 718                         errors 
|= param_getdec(Cmd
,cmdp
+1,&fcHigh
); 
 722                         errors 
|= param_getdec(Cmd
,cmdp
+1,&fcLow
); 
 730                         dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 734                                 dataLen 
= hextobinarray((char *)data
, hexData
); 
 736                         if (dataLen
==0) errors
=TRUE
;  
 737                         if (errors
) PrintAndLog ("Error getting hex data"); 
 741                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 747         if(cmdp 
== 0 && DemodBufferLen 
== 0) 
 749                 errors 
= TRUE
;// No args 
 755                 return usage_lf_simfsk(); 
 758         if (dataLen 
== 0){ //using DemodBuffer  
 759                 if (clk
==0 || fcHigh
==0 || fcLow
==0){ //manual settings must set them all 
 760                         uint8_t ans 
= fskClocks(&fcHigh
, &fcLow
, &clk
, 0); 
 762                                 if (!fcHigh
) fcHigh
=10; 
 768                 setDemodBuf(data
, dataLen
, 0); 
 771         //default if not found 
 772         if (clk 
== 0) clk 
= 50; 
 773         if (fcHigh 
== 0) fcHigh 
= 10; 
 774         if (fcLow 
== 0) fcLow 
= 8; 
 777         arg1 
= fcHigh 
<< 8 | fcLow
; 
 778         arg2 
= invert 
<< 8 | clk
; 
 779         size_t size 
= DemodBufferLen
; 
 780         if (size 
> USB_CMD_DATA_SIZE
) { 
 781                 PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 782                 size 
= USB_CMD_DATA_SIZE
; 
 784         UsbCommand c 
= {CMD_FSK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 786         memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 787         clearCommandBuffer(); 
 792 // by marshmellow - sim ask data given clock, invert, manchester or raw, separator  
 793 // - allow pull data from DemodBuffer 
 794 int CmdLFaskSim(const char *Cmd
) 
 796         //autodetect clock from Graphbuffer if using demod buffer 
 797         // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream 
 798         uint8_t encoding 
= 1, separator 
= 0; 
 799         uint8_t clk
=0, invert
=0; 
 801         char hexData
[32] = {0x00};  
 802         uint8_t data
[255]= {0x00}; // store entered hex data 
 805         while(param_getchar(Cmd
, cmdp
) != 0x00) 
 807                 switch(param_getchar(Cmd
, cmdp
)) 
 810                         return usage_lf_simask(); 
 816                         errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 820                         encoding
=2; //biphase 
 836                         dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 840                                 dataLen 
= hextobinarray((char *)data
, hexData
); 
 842                         if (dataLen
==0) errors
=TRUE
;  
 843                         if (errors
) PrintAndLog ("Error getting hex data, datalen: %d",dataLen
); 
 847                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 853         if(cmdp 
== 0 && DemodBufferLen 
== 0) 
 855                 errors 
= TRUE
;// No args 
 861                 return usage_lf_simask(); 
 863         if (dataLen 
== 0){ //using DemodBuffer 
 864                 if (clk 
== 0) clk 
= GetAskClock("0", false, false); 
 866                 setDemodBuf(data
, dataLen
, 0); 
 868         if (clk 
== 0) clk 
= 64; 
 869         if (encoding 
== 0) clk 
= clk
/2; //askraw needs to double the clock speed 
 871         size_t size
=DemodBufferLen
; 
 872         arg1 
= clk 
<< 8 | encoding
; 
 873         arg2 
= invert 
<< 8 | separator
; 
 874         if (size 
> USB_CMD_DATA_SIZE
) { 
 875                 PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 876                 size 
= USB_CMD_DATA_SIZE
; 
 878         UsbCommand c 
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 879         PrintAndLog("preparing to sim ask data: %d bits", size
); 
 880         memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 881         clearCommandBuffer(); 
 886 // by marshmellow - sim psk data given carrier, clock, invert  
 887 // - allow pull data from DemodBuffer or parameters 
 888 int CmdLFpskSim(const char *Cmd
) 
 890         //might be able to autodetect FC and clock from Graphbuffer if using demod buffer 
 891         //will need carrier, Clock, and bitstream 
 892         uint8_t carrier
=0, clk
=0; 
 895         char hexData
[32] = {0x00}; // store entered hex data 
 896         uint8_t data
[255] = {0x00};  
 900         while(param_getchar(Cmd
, cmdp
) != 0x00) 
 902                 switch(param_getchar(Cmd
, cmdp
)) 
 905                         return usage_lf_simpsk(); 
 911                         errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 915                         errors 
|= param_getdec(Cmd
,cmdp
+1,&carrier
); 
 931                         dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 935                                 dataLen 
= hextobinarray((char *)data
, hexData
); 
 937                         if (dataLen
==0) errors
=TRUE
;  
 938                         if (errors
) PrintAndLog ("Error getting hex data"); 
 942                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 948         if (cmdp 
== 0 && DemodBufferLen 
== 0) 
 950                 errors 
= TRUE
;// No args 
 956                 return usage_lf_simpsk(); 
 958         if (dataLen 
== 0){ //using DemodBuffer 
 959                 PrintAndLog("Getting Clocks"); 
 960                 if (clk
==0) clk 
= GetPskClock("", FALSE
, FALSE
); 
 961                 PrintAndLog("clk: %d",clk
); 
 962                 if (!carrier
) carrier 
= GetPskCarrier("", FALSE
, FALSE
);  
 963                 PrintAndLog("carrier: %d", carrier
); 
 965                 setDemodBuf(data
, dataLen
, 0); 
 968         if (clk 
<= 0) clk 
= 32; 
 969         if (carrier 
== 0) carrier 
= 2; 
 972                         //need to convert psk2 to psk1 data before sim 
 973                         psk2TOpsk1(DemodBuffer
, DemodBufferLen
); 
 975                         PrintAndLog("Sorry, PSK3 not yet available"); 
 979         arg1 
= clk 
<< 8 | carrier
; 
 981         size_t size
=DemodBufferLen
; 
 982         if (size 
> USB_CMD_DATA_SIZE
) { 
 983                 PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 984                 size
=USB_CMD_DATA_SIZE
; 
 986         UsbCommand c 
= {CMD_PSK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 987         PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size
); 
 988         memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 989         clearCommandBuffer(); 
 995 int CmdLFSimBidir(const char *Cmd
) 
 997         // Set ADC to twice the carrier for a slight supersampling 
 998         // HACK: not implemented in ARMSRC. 
 999         PrintAndLog("Not implemented yet."); 
1000         UsbCommand c 
= {CMD_LF_SIMULATE_BIDIR
, {47, 384, 0}}; 
1005 int CmdVchDemod(const char *Cmd
) 
1007         // Is this the entire sync pattern, or does this also include some 
1008         // data bits that happen to be the same everywhere? That would be 
1010         static const int SyncPattern
[] = { 
1011                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
1012                 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
1013                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
1014                 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
1015                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
1016                 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
1017                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
1018                 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
1019                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
1020                 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
1023         // So first, we correlate for the sync pattern, and mark that. 
1024         int bestCorrel 
= 0, bestPos 
= 0; 
1026         // It does us no good to find the sync pattern, with fewer than 
1027         // 2048 samples after it... 
1028         for (i 
= 0; i 
< (GraphTraceLen
-2048); i
++) { 
1031                 for (j 
= 0; j 
< arraylen(SyncPattern
); j
++) { 
1032                         sum 
+= GraphBuffer
[i
+j
]*SyncPattern
[j
]; 
1034                 if (sum 
> bestCorrel
) { 
1039         PrintAndLog("best sync at %d [metric %d]", bestPos
, bestCorrel
); 
1044         int worst 
= INT_MAX
; 
1047         for (i 
= 0; i 
< 2048; i 
+= 8) { 
1050                 for (j 
= 0; j 
< 8; j
++) { 
1051                         sum 
+= GraphBuffer
[bestPos
+i
+j
]; 
1058                 if(abs(sum
) < worst
) { 
1063         PrintAndLog("bits:"); 
1064         PrintAndLog("%s", bits
); 
1065         PrintAndLog("worst metric: %d at pos %d", worst
, worstPos
); 
1067         if (strcmp(Cmd
, "clone")==0) { 
1070                 for(s 
= bits
; *s
; s
++) { 
1072                         for(j 
= 0; j 
< 16; j
++) { 
1073                                 GraphBuffer
[GraphTraceLen
++] = (*s 
== '1') ? 1 : 0; 
1076                 RepaintGraphWindow(); 
1082 int CmdLFfind(const char *Cmd
) 
1085         size_t minLength 
= 1000; 
1086         char cmdp 
= param_getchar(Cmd
, 0); 
1087         char testRaw 
= param_getchar(Cmd
, 1); 
1088         if (strlen(Cmd
) > 3 || cmdp 
== 'h' || cmdp 
== 'H') { 
1089                 PrintAndLog("Usage:  lf search <0|1> [u]"); 
1090                 PrintAndLog("     <use data from Graphbuffer> , if not set, try reading data from tag."); 
1091                 PrintAndLog("     [Search for Unknown tags] , if not set, reads only known tags."); 
1093                 PrintAndLog("    sample: lf search     = try reading data from tag & search for known tags"); 
1094                 PrintAndLog("          : lf search 1   = use data from GraphBuffer & search for known tags"); 
1095                 PrintAndLog("          : lf search u   = try reading data from tag & search for known and unknown tags"); 
1096                 PrintAndLog("          : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); 
1101         if (!offline 
&& (cmdp 
!= '1')){ 
1103                 getSamples("30000",false); 
1104         } else if (GraphTraceLen 
< minLength
) { 
1105                 PrintAndLog("Data in Graphbuffer was too small."); 
1108         if (cmdp 
== 'u' || cmdp 
== 'U') testRaw 
= 'u'; 
1110         PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag"); 
1111         PrintAndLog("False Positives ARE possible\n");   
1112         PrintAndLog("\nChecking for known tags:\n"); 
1114         size_t testLen 
= minLength
; 
1115         // only run if graphbuffer is just noise as it should be for hitag/cotag 
1116         if (graphJustNoise(GraphBuffer
, testLen
)) { 
1117                 // only run these tests if we are in online mode  
1118                 if (!offline 
&& (cmdp 
!= '1')){ 
1119                         ans
=CmdLFHitagReader("26"); 
1123                         ans
=CmdCOTAGRead(""); 
1125                                 PrintAndLog("\nValid COTAG ID Found!"); 
1132         ans
=CmdFSKdemodIO(""); 
1134                 PrintAndLog("\nValid IO Prox ID Found!"); 
1138         ans
=CmdFSKdemodPyramid(""); 
1140                 PrintAndLog("\nValid Pyramid ID Found!"); 
1144         ans
=CmdFSKdemodParadox(""); 
1146                 PrintAndLog("\nValid Paradox ID Found!"); 
1150         ans
=CmdFSKdemodAWID(""); 
1152                 PrintAndLog("\nValid AWID ID Found!"); 
1156         ans
=CmdFSKdemodHID(""); 
1158                 PrintAndLog("\nValid HID Prox ID Found!"); 
1162         ans
=CmdAskEM410xDemod(""); 
1164                 PrintAndLog("\nValid EM410x ID Found!"); 
1168         ans
=CmdG_Prox_II_Demod(""); 
1170                 PrintAndLog("\nValid G Prox II ID Found!"); 
1174         ans
=CmdFDXBdemodBI(""); 
1176                 PrintAndLog("\nValid FDX-B ID Found!"); 
1180         ans
=EM4x50Read("", false); 
1182                 PrintAndLog("\nValid EM4x50 ID Found!"); 
1186         ans
=CmdVikingDemod(""); 
1188                 PrintAndLog("\nValid Viking ID Found!"); 
1192         ans
=CmdIndalaDecode(""); 
1194                 PrintAndLog("\nValid Indala ID Found!"); 
1198         ans
=CmdPSKNexWatch(""); 
1200                 PrintAndLog("\nValid NexWatch ID Found!"); 
1204         PrintAndLog("\nNo Known Tags Found!\n"); 
1205         if (testRaw
=='u' || testRaw
=='U'){ 
1206                 //test unknown tag formats (raw mode) 
1207                 PrintAndLog("\nChecking for Unknown tags:\n"); 
1208                 ans
=AutoCorrelate(4000, FALSE
, FALSE
); 
1209                 if (ans 
> 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans
); 
1210                 ans
=GetFskClock("",FALSE
,FALSE
);  
1211                 if (ans 
!= 0){ //fsk 
1212                         ans
=FSKrawDemod("",TRUE
); 
1214                                 PrintAndLog("\nUnknown FSK Modulated Tag Found!"); 
1219                 ans
=ASKDemod_ext("0 0 0",TRUE
,FALSE
,1,&st
); 
1221                         PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); 
1222                         PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'"); 
1225                 ans
=CmdPSK1rawDemod(""); 
1227                         PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'"); 
1228                         PrintAndLog("\nCould also be PSK3 - [currently not supported]"); 
1229                         PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); 
1232                 PrintAndLog("\nNo Data Found!\n"); 
1237 static command_t CommandTable
[] =  
1239         {"help",        CmdHelp
,            1, "This help"}, 
1240         {"awid",        CmdLFAWID
,          1, "{ AWID RFIDs...    }"}, 
1241         {"cotag",       CmdLFCOTAG
,         1, "{ COTAG RFIDs...   }"}, 
1242         {"em4x",        CmdLFEM4X
,          1, "{ EM4X RFIDs...    }"}, 
1243         {"hid",         CmdLFHID
,           1, "{ HID RFIDs...     }"}, 
1244         {"hitag",       CmdLFHitag
,         1, "{ Hitag tags and transponders... }"}, 
1245         {"io",          CmdLFIO
,            1, "{ ioProx tags...   }"}, 
1246         {"presco",      CmdLFPresco
,        1, "{ Presco RFIDs... }"}, 
1247         {"pcf7931",     CmdLFPCF7931
,       1, "{ PCF7931 RFIDs... }"}, 
1248         {"pyramid",     CmdLFPyramid
,       1, "{ Farpointe/Pyramid RFIDs... }"}, 
1249         {"t55xx",       CmdLFT55XX
,         1, "{ T55xx RFIDs...   }"}, 
1250         {"ti",          CmdLFTI
,            1, "{ TI RFIDs...      }"}, 
1251         {"viking",      CmdLFViking
,        1, "{ Viking tags...   }"}, 
1252         {"cmdread",     CmdLFCommandRead
,   0, "<d period> <z period> <o period> <c command> ['H'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'H' for 134)"}, 
1253         {"config",      CmdLFSetConfig
,     0, "Set config for LF sampling, bit/sample, decimation, frequency"}, 
1254         {"flexdemod",   CmdFlexdemod
,       1, "Demodulate samples for FlexPass"}, 
1255         {"indalademod", CmdIndalaDemod
,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, 
1256         {"indalaclone", CmdIndalaClone
,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, 
1257         {"read",        CmdLFRead
,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, 
1258         {"search",      CmdLFfind
,          1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, 
1259         {"sim",         CmdLFSim
,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, 
1260         {"simask",      CmdLFaskSim
,        0, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"}, 
1261         {"simfsk",      CmdLFfskSim
,        0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"}, 
1262         {"simpsk",      CmdLFpskSim
,        0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"}, 
1263         {"simbidir",    CmdLFSimBidir
,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, 
1264         {"snoop",       CmdLFSnoop
,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, 
1265         {"vchdemod",    CmdVchDemod
,        1, "['clone'] -- Demodulate samples for VeriChip"}, 
1266         {NULL
, NULL
, 0, NULL
} 
1269 int CmdLF(const char *Cmd
) 
1271         CmdsParse(CommandTable
, Cmd
); 
1275 int CmdHelp(const char *Cmd
) 
1277         CmdsHelp(CommandTable
);