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" 
  19 #include "cmdparser.h" 
  26 #include "cmdlfem4x.h" 
  27 #include "cmdlfhitag.h" 
  28 #include "cmdlft55xx.h" 
  29 #include "cmdlfpcf7931.h" 
  33 static int CmdHelp(const char *Cmd
); 
  35 /* send a command before reading */ 
  36 int CmdLFCommandRead(const char *Cmd
) 
  42   UsbCommand c 
= {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
}; 
  43   sscanf(Cmd
, "%"lli
" %"lli
" %"lli
" %s %s", &c
.arg
[0], &c
.arg
[1], &c
.arg
[2],(char*)(&c
.d
.asBytes
),(char*)(&dummy
+1)); 
  44   // in case they specified 'h' 
  45   strcpy((char *)&c
.d
.asBytes 
+ strlen((char *)c
.d
.asBytes
), dummy
); 
  50 int CmdFlexdemod(const char *Cmd
) 
  53   for (i 
= 0; i 
< GraphTraceLen
; ++i
) { 
  54     if (GraphBuffer
[i
] < 0) { 
  63   for (start 
= 0; start 
< GraphTraceLen 
- LONG_WAIT
; start
++) { 
  64     int first 
= GraphBuffer
[start
]; 
  65     for (i 
= start
; i 
< start 
+ LONG_WAIT
; i
++) { 
  66       if (GraphBuffer
[i
] != first
) { 
  70     if (i 
== (start 
+ LONG_WAIT
)) { 
  74   if (start 
== GraphTraceLen 
- LONG_WAIT
) { 
  75     PrintAndLog("nothing to wait for"); 
  79   GraphBuffer
[start
] = 2; 
  80   GraphBuffer
[start
+1] = -2; 
  81         uint8_t bits
[64] = {0x00}; 
  85   for (bit 
= 0; bit 
< 64; bit
++) { 
  87                 for (int j 
= 0; j 
< 16; j
++) { 
  88       sum 
+= GraphBuffer
[i
++]; 
  91                 bits
[bit
] = (sum 
> 0) ? 1 : 0; 
  93     PrintAndLog("bit %d sum %d", bit
, sum
); 
  96   for (bit 
= 0; bit 
< 64; bit
++) { 
  99     for (j 
= 0; j 
< 16; j
++) { 
 100       sum 
+= GraphBuffer
[i
++]; 
 102     if (sum 
> 0 && bits
[bit
] != 1) { 
 103       PrintAndLog("oops1 at %d", bit
); 
 105     if (sum 
< 0 && bits
[bit
] != 0) { 
 106       PrintAndLog("oops2 at %d", bit
); 
 110         // HACK writing back to graphbuffer. 
 111   GraphTraceLen 
= 32*64; 
 114   for (bit 
= 0; bit 
< 64; bit
++) { 
 116                 phase 
= (bits
[bit
] == 0) ? 0 : 1; 
 119     for (j 
= 0; j 
< 32; j
++) { 
 120       GraphBuffer
[i
++] = phase
; 
 125   RepaintGraphWindow(); 
 129 int CmdIndalaDemod(const char *Cmd
) 
 131   // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID 
 137   // worst case with GraphTraceLen=64000 is < 4096 
 138   // under normal conditions it's < 2048 
 140   uint8_t rawbits
[4096]; 
 142   int worst 
= 0, worstPos 
= 0; 
 143  // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); 
 144   for (i 
= 0; i 
< GraphTraceLen
-1; i 
+= 2) { 
 146     if ((GraphBuffer
[i
] > GraphBuffer
[i 
+ 1]) && (state 
!= 1)) { 
 148         for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 149           rawbits
[rawbit
++] = 0; 
 151         if ((abs(count 
- j
)) > worst
) { 
 152           worst 
= abs(count 
- j
); 
 158     } else if ((GraphBuffer
[i
] < GraphBuffer
[i 
+ 1]) && (state 
!= 0)) { 
 160         for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 161           rawbits
[rawbit
++] = 1; 
 163         if ((abs(count 
- j
)) > worst
) { 
 164           worst 
= abs(count 
- j
); 
 174     PrintAndLog("Recovered %d raw bits, expected: %d", rawbit
, GraphTraceLen
/32); 
 175     PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst
, worstPos
); 
 180   // Finding the start of a UID 
 181   int uidlen
, long_wait
; 
 182   if (strcmp(Cmd
, "224") == 0) { 
 192   for (start 
= 0; start 
<= rawbit 
- uidlen
; start
++) { 
 193     first 
= rawbits
[start
]; 
 194     for (i 
= start
; i 
< start 
+ long_wait
; i
++) { 
 195       if (rawbits
[i
] != first
) { 
 199     if (i 
== (start 
+ long_wait
)) { 
 204   if (start 
== rawbit 
- uidlen 
+ 1) { 
 205     PrintAndLog("nothing to wait for"); 
 209   // Inverting signal if needed 
 211     for (i 
= start
; i 
< rawbit
; i
++) { 
 212       rawbits
[i
] = !rawbits
[i
]; 
 217         uint8_t bits
[224] = {0x00}; 
 218         char showbits
[225] = {0x00}; 
 223   if (uidlen 
> rawbit
) { 
 224     PrintAndLog("Warning: not enough raw bits to get a full UID"); 
 225     for (bit 
= 0; bit 
< rawbit
; bit
++) { 
 226       bits
[bit
] = rawbits
[i
++]; 
 227       // As we cannot know the parity, let's use "." and "/" 
 228       showbits
[bit
] = '.' + bits
[bit
]; 
 230     showbits
[bit
+1]='\0'; 
 231     PrintAndLog("Partial UID=%s", showbits
); 
 234     for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 235       bits
[bit
] = rawbits
[i
++]; 
 236       showbits
[bit
] = '0' + bits
[bit
]; 
 242   uint32_t uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 247     for( idx
=0; idx
<64; idx
++) { 
 248         if (showbits
[idx
] == '0') { 
 249         uid1
=(uid1
<<1)|(uid2
>>31); 
 252         uid1
=(uid1
<<1)|(uid2
>>31); 
 256     PrintAndLog("UID=%s (%x%08x)", showbits
, uid1
, uid2
); 
 259                 uid3 
= uid4 
= uid5 
= uid6 
= uid7 
= 0; 
 261     for( idx
=0; idx
<224; idx
++) { 
 262         uid1
=(uid1
<<1)|(uid2
>>31); 
 263         uid2
=(uid2
<<1)|(uid3
>>31); 
 264         uid3
=(uid3
<<1)|(uid4
>>31); 
 265         uid4
=(uid4
<<1)|(uid5
>>31); 
 266         uid5
=(uid5
<<1)|(uid6
>>31); 
 267         uid6
=(uid6
<<1)|(uid7
>>31); 
 269                         if (showbits
[idx
] == '0')  
 270                                 uid7 
= (uid7
<<1) | 0; 
 272                                 uid7 
= (uid7
<<1) | 1; 
 274     PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits
, uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 277   // Checking UID against next occurrences 
 279         for (; i 
+ uidlen 
<= rawbit
;) { 
 281     for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 282       if (bits
[bit
] != rawbits
[i
++]) { 
 293   PrintAndLog("Occurrences: %d (expected %d)", times
, (rawbit 
- start
) / uidlen
); 
 295   // Remodulating for tag cloning 
 296         // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)  
 297         // since this changes graphbuffer data. 
 298   GraphTraceLen 
= 32*uidlen
; 
 301   for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 302     if (bits
[bit
] == 0) { 
 308     for (j 
= 0; j 
< 32; j
++) { 
 309       GraphBuffer
[i
++] = phase
; 
 314   RepaintGraphWindow(); 
 318 int CmdIndalaClone(const char *Cmd
) 
 321         unsigned int uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 323         uid1 
=  uid2 
= uid3 
= uid4 
= uid5 
= uid6 
= uid7 
= 0; 
 326   if (strchr(Cmd
,'l') != 0) { 
 327     while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 328       uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 329       uid2 
= (uid2 
<< 4) | (uid3 
>> 28); 
 330       uid3 
= (uid3 
<< 4) | (uid4 
>> 28); 
 331       uid4 
= (uid4 
<< 4) | (uid5 
>> 28); 
 332       uid5 
= (uid5 
<< 4) | (uid6 
>> 28); 
 333       uid6 
= (uid6 
<< 4) | (uid7 
>> 28); 
 334         uid7 
= (uid7 
<< 4) | (n 
& 0xf); 
 336     PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 337     c
.cmd 
= CMD_INDALA_CLONE_TAG_L
; 
 338     c
.d
.asDwords
[0] = uid1
; 
 339     c
.d
.asDwords
[1] = uid2
; 
 340     c
.d
.asDwords
[2] = uid3
; 
 341     c
.d
.asDwords
[3] = uid4
; 
 342     c
.d
.asDwords
[4] = uid5
; 
 343     c
.d
.asDwords
[5] = uid6
; 
 344     c
.d
.asDwords
[6] = uid7
; 
 346     while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 347       uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 348       uid2 
= (uid2 
<< 4) | (n 
& 0xf); 
 350     PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1
, uid2
); 
 351     c
.cmd 
= CMD_INDALA_CLONE_TAG
; 
 362         PrintAndLog("Usage: lf read"); 
 363         PrintAndLog("Options:        "); 
 364         PrintAndLog("       h            This help"); 
 365         PrintAndLog("This function takes no arguments. "); 
 366         PrintAndLog("Use 'lf config' to set parameters."); 
 371         PrintAndLog("Usage: lf snoop"); 
 372         PrintAndLog("Options:        "); 
 373         PrintAndLog("       h            This help"); 
 374         PrintAndLog("This function takes no arguments. "); 
 375         PrintAndLog("Use 'lf config' to set parameters."); 
 379 int usage_lf_config() 
 381         PrintAndLog("Usage: lf config [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]"); 
 382         PrintAndLog("Options:        "); 
 383         PrintAndLog("       h             This help"); 
 384         PrintAndLog("       L             Low frequency (125 KHz)"); 
 385         PrintAndLog("       H             High frequency (134 KHz)"); 
 386         PrintAndLog("       q <divisor>   Manually set divisor. 88-> 134KHz, 95-> 125 Hz"); 
 387         PrintAndLog("       b <bps>       Sets resolution of bits per sample. Default (max): 8"); 
 388         PrintAndLog("       d <decim>     Sets decimation. A value of N saves only 1 in N samples. Default: 1"); 
 389         PrintAndLog("       a [0|1]       Averaging - if set, will average the stored sample value when decimating. Default: 1"); 
 390         PrintAndLog("       t <threshold> Sets trigger threshold. 0 means no threshold"); 
 391         PrintAndLog("Examples:"); 
 392         PrintAndLog("      lf config b 8 L"); 
 393         PrintAndLog("                    Samples at 125KHz, 8bps."); 
 394         PrintAndLog("      lf config H b 4 d 3"); 
 395         PrintAndLog("                    Samples at 134KHz, averages three samples into one, stored with "); 
 396         PrintAndLog("                    a resolution of 4 bits per sample."); 
 397         PrintAndLog("      lf read"); 
 398         PrintAndLog("                    Performs a read (active field)"); 
 399         PrintAndLog("      lf snoop"); 
 400         PrintAndLog("                    Performs a snoop (no active field)"); 
 404 int CmdLFSetConfig(const char *Cmd
) 
 407         uint8_t divisor 
=  0;//Frequency divisor 
 408         uint8_t bps 
= 0; // Bits per sample 
 409         uint8_t decimation 
= 0; //How many to keep 
 410         bool averaging 
= 1; // Defaults to true 
 412         int trigger_threshold 
=-1;//Means no change 
 413         uint8_t unsigned_trigg 
= 0; 
 416         while(param_getchar(Cmd
, cmdp
) != 0x00) 
 418                 switch(param_getchar(Cmd
, cmdp
)) 
 421                         return usage_lf_config(); 
 431                         errors 
|= param_getdec(Cmd
,cmdp
+1,&divisor
); 
 435                         errors 
|= param_getdec(Cmd
,cmdp
+1,&unsigned_trigg
); 
 437                         if(!errors
) trigger_threshold 
= unsigned_trigg
; 
 440                         errors 
|= param_getdec(Cmd
,cmdp
+1,&bps
); 
 444                         errors 
|= param_getdec(Cmd
,cmdp
+1,&decimation
); 
 448                         averaging 
= param_getchar(Cmd
,cmdp
+1) == '1'; 
 452                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 460                 errors 
= 1;// No args 
 466                 return usage_lf_config(); 
 468         //Bps is limited to 8, so fits in lower half of arg1 
 469         if(bps 
>> 8) bps 
= 8; 
 471         sample_config config 
= { 
 472                 decimation
,bps
,averaging
,divisor
,trigger_threshold
 
 474         //Averaging is a flag on high-bit of arg[1] 
 475         UsbCommand c 
= {CMD_SET_LF_SAMPLING_CONFIG
}; 
 476         memcpy(c
.d
.asBytes
,&config
,sizeof(sample_config
)); 
 481 int CmdLFRead(const char *Cmd
) 
 485         if(param_getchar(Cmd
, cmdp
) == 'h') 
 487                 return usage_lf_read(); 
 489         //And ship it to device 
 490         UsbCommand c 
= {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
}; 
 492         WaitForResponse(CMD_ACK
,NULL
); 
 496 int CmdLFSnoop(const char *Cmd
) 
 499         if(param_getchar(Cmd
, cmdp
) == 'h') 
 501                 return usage_lf_snoop(); 
 504         UsbCommand c 
= {CMD_LF_SNOOP_RAW_ADC_SAMPLES
}; 
 506         WaitForResponse(CMD_ACK
,NULL
); 
 510 static void ChkBitstream(const char *str
) 
 514   /* convert to bitstream if necessary */ 
 515         for (i 
= 0; i 
< (int)(GraphTraceLen 
/ 2); i
++){ 
 516                 if (GraphBuffer
[i
] > 1 || GraphBuffer
[i
] < 0) { 
 522 //appears to attempt to simulate manchester 
 523 int CmdLFSim(const char *Cmd
) 
 528   sscanf(Cmd
, "%i", &gap
); 
 530   /* convert to bitstream if necessary */ 
 534   //can send 512 bits at a time (1 byte sent per bit...) 
 535   printf("Sending [%d bytes]", GraphTraceLen
); 
 536   for (i 
= 0; i 
< GraphTraceLen
; i 
+= USB_CMD_DATA_SIZE
) { 
 537     UsbCommand c
={CMD_DOWNLOADED_SIM_SAMPLES_125K
, {i
, 0, 0}}; 
 539     for (j 
= 0; j 
< USB_CMD_DATA_SIZE
; j
++) { 
 540       c
.d
.asBytes
[j
] = GraphBuffer
[i
+j
]; 
 543     WaitForResponse(CMD_ACK
,NULL
); 
 548   PrintAndLog("Starting to simulate"); 
 549   UsbCommand c 
= {CMD_SIMULATE_TAG_125K
, {GraphTraceLen
, gap
, 0}}; 
 554 int usage_lf_simfsk(void) 
 557   PrintAndLog("Usage: lf simfsk [c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>]"); 
 558   PrintAndLog("Options:        "); 
 559   PrintAndLog("       h              This help"); 
 560   PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 561   PrintAndLog("       i              invert data"); 
 562   PrintAndLog("       H <fcHigh>     Manually set the larger Field Clock"); 
 563   PrintAndLog("       L <fcLow>      Manually set the smaller Field Clock"); 
 564   //PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap"); 
 565   PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 566   PrintAndLog("\n  NOTE: if you set one clock manually set them all manually"); 
 570 int usage_lf_simask(void) 
 573   PrintAndLog("Usage: lf simask [c <clock>] [i] [m|r] [s] [d <raw hex to sim>]"); 
 574   PrintAndLog("Options:        "); 
 575   PrintAndLog("       h              This help"); 
 576   PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 577   PrintAndLog("       i              invert data"); 
 578   PrintAndLog("       m              sim ask/manchester"); 
 579   PrintAndLog("       r              sim ask/raw"); 
 580   PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap"); 
 581   PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 585 int usage_lf_simpsk(void) 
 588   PrintAndLog("Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]"); 
 589   PrintAndLog("Options:        "); 
 590   PrintAndLog("       h              This help"); 
 591   PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer"); 
 592   PrintAndLog("       i              invert data"); 
 593   PrintAndLog("       1              set PSK1 (default)"); 
 594   PrintAndLog("       2              set PSK2"); 
 595   PrintAndLog("       3              set PSK3"); 
 596   PrintAndLog("       r <carrier>    2|4|8 are valid carriers: default = 2"); 
 597   PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer"); 
 601 // by marshmellow - sim ask data given clock, fcHigh, fcLow, invert  
 602 // - allow pull data from DemodBuffer 
 603 int CmdLFfskSim(const char *Cmd
) 
 605   //might be able to autodetect FC and clock from Graphbuffer if using demod buffer 
 606   //will need FChigh, FClow, Clock, and bitstream 
 607   uint8_t fcHigh
=0, fcLow
=0, clk
=0; 
 610   char hexData
[32] = {0x00}; // store entered hex data 
 611   uint8_t data
[255] = {0x00};  
 614   while(param_getchar(Cmd
, cmdp
) != 0x00) 
 616     switch(param_getchar(Cmd
, cmdp
)) 
 619       return usage_lf_simfsk(); 
 625       errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 629       errors 
|= param_getdec(Cmd
,cmdp
+1,&fcHigh
); 
 633       errors 
|= param_getdec(Cmd
,cmdp
+1,&fcLow
); 
 641       dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 645         dataLen 
= hextobinarray((char *)data
, hexData
); 
 647       if (dataLen
==0) errors
=TRUE
;  
 648       if (errors
) PrintAndLog ("Error getting hex data"); 
 652       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 658   if(cmdp 
== 0 && DemodBufferLen 
== 0) 
 660     errors 
= TRUE
;// No args 
 666     return usage_lf_simfsk(); 
 669   if (dataLen 
== 0){ //using DemodBuffer  
 670     if (clk
==0 || fcHigh
==0 || fcLow
==0){ //manual settings must set them all 
 671       uint8_t ans 
= fskClocks(&fcHigh
, &fcLow
, &clk
, 0); 
 673         if (!fcHigh
) fcHigh
=10; 
 679     setDemodBuf(data
, dataLen
, 0); 
 681   if (clk 
== 0) clk 
= 50; 
 682   if (fcHigh 
== 0) fcHigh 
= 10; 
 683   if (fcLow 
== 0) fcLow 
= 8; 
 686   arg1 
= fcHigh 
<< 8 | fcLow
; 
 687   arg2 
= invert 
<< 8 | clk
; 
 688   size_t size 
= DemodBufferLen
; 
 689   if (size 
> USB_CMD_DATA_SIZE
) { 
 690     PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 691     size 
= USB_CMD_DATA_SIZE
; 
 693   UsbCommand c 
= {CMD_FSK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 695   memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 700 // by marshmellow - sim ask data given clock, invert, manchester or raw, separator  
 701 // - allow pull data from DemodBuffer 
 702 int CmdLFaskSim(const char *Cmd
) 
 704   //autodetect clock from Graphbuffer if using demod buffer 
 705   //will need clock, invert, manchester/raw as m or r, separator as s, and bitstream 
 706   uint8_t manchester 
= 1, separator 
= 0; 
 707   //char cmdp = Cmd[0], par3='m', par4=0; 
 708   uint8_t clk
=0, invert
=0; 
 710   char hexData
[32] = {0x00};  
 711   uint8_t data
[255]= {0x00}; // store entered hex data 
 714   while(param_getchar(Cmd
, cmdp
) != 0x00) 
 716     switch(param_getchar(Cmd
, cmdp
)) 
 719       return usage_lf_simask(); 
 725       errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 741       dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 745         dataLen 
= hextobinarray((char *)data
, hexData
); 
 747       if (dataLen
==0) errors
=TRUE
;  
 748       if (errors
) PrintAndLog ("Error getting hex data, datalen: %d",dataLen
); 
 752       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 758   if(cmdp 
== 0 && DemodBufferLen 
== 0) 
 760     errors 
= TRUE
;// No args 
 766     return usage_lf_simask(); 
 768   if (dataLen 
== 0){ //using DemodBuffer 
 769     if (clk 
== 0) clk 
= GetAskClock("0", false, false); 
 771     setDemodBuf(data
, dataLen
, 0); 
 773   if (clk 
== 0) clk 
= 64; 
 774   if (manchester 
== 0) clk 
= clk
/2; //askraw needs to double the clock speed 
 776   size_t size
=DemodBufferLen
; 
 777   arg1 
= clk 
<< 8 | manchester
; 
 778   arg2 
= invert 
<< 8 | separator
; 
 779   if (size 
> USB_CMD_DATA_SIZE
) { 
 780     PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 781     size 
= USB_CMD_DATA_SIZE
; 
 783   UsbCommand c 
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 784   PrintAndLog("preparing to sim ask data: %d bits", size
); 
 785   memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 790 // by marshmellow - sim psk data given carrier, clock, invert  
 791 // - allow pull data from DemodBuffer or parameters 
 792 int CmdLFpskSim(const char *Cmd
) 
 794   //might be able to autodetect FC and clock from Graphbuffer if using demod buffer 
 795   //will need carrier, Clock, and bitstream 
 796   uint8_t carrier
=0, clk
=0; 
 799   char hexData
[32] = {0x00}; // store entered hex data 
 800   uint8_t data
[255] = {0x00};  
 804   while(param_getchar(Cmd
, cmdp
) != 0x00) 
 806     switch(param_getchar(Cmd
, cmdp
)) 
 809       return usage_lf_simpsk(); 
 815       errors 
|= param_getdec(Cmd
,cmdp
+1,&clk
); 
 819       errors 
|= param_getdec(Cmd
,cmdp
+1,&carrier
); 
 835       dataLen 
= param_getstr(Cmd
, cmdp
+1, hexData
); 
 839         dataLen 
= hextobinarray((char *)data
, hexData
); 
 841       if (dataLen
==0) errors
=TRUE
;  
 842       if (errors
) PrintAndLog ("Error getting hex data"); 
 846       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 852   if (cmdp 
== 0 && DemodBufferLen 
== 0) 
 854     errors 
= TRUE
;// No args 
 860     return usage_lf_simpsk(); 
 862   if (dataLen 
== 0){ //using DemodBuffer 
 863     PrintAndLog("Getting Clocks"); 
 864     if (clk
==0) clk 
= GetPskClock("", FALSE
, FALSE
); 
 865     PrintAndLog("clk: %d",clk
); 
 866     if (!carrier
) carrier 
= GetPskCarrier("", FALSE
, FALSE
);  
 867     PrintAndLog("carrier: %d", carrier
); 
 869     setDemodBuf(data
, dataLen
, 0); 
 872   if (clk 
<= 0) clk 
= 32; 
 873   if (carrier 
== 0) carrier 
= 2; 
 876       //need to convert psk2 to psk1 data before sim 
 877       psk2TOpsk1(DemodBuffer
, DemodBufferLen
); 
 879       PrintAndLog("Sorry, PSK3 not yet available"); 
 883   arg1 
= clk 
<< 8 | carrier
; 
 885   size_t size
=DemodBufferLen
; 
 886   if (size 
> USB_CMD_DATA_SIZE
) { 
 887     PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size
, USB_CMD_DATA_SIZE
); 
 888     size
=USB_CMD_DATA_SIZE
; 
 890   UsbCommand c 
= {CMD_PSK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 891   PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size
); 
 892   memcpy(c
.d
.asBytes
, DemodBuffer
, size
); 
 898 int CmdLFSimBidir(const char *Cmd
) 
 900   // Set ADC to twice the carrier for a slight supersampling 
 901   // HACK: not implemented in ARMSRC. 
 902   PrintAndLog("Not implemented yet."); 
 903   UsbCommand c 
= {CMD_LF_SIMULATE_BIDIR
, {47, 384, 0}}; 
 908 /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */ 
 910 int CmdLFSimManchester(const char *Cmd) 
 912   static int clock, gap; 
 913   static char data[1024], gapstring[8]; 
 915   sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); 
 919   for (int i = 0; i < strlen(data) ; ++i) 
 920     AppendGraph(0, clock, data[i]- '0'); 
 922   CmdManchesterMod(""); 
 924   RepaintGraphWindow(); 
 926   sprintf(&gapstring[0], "%i", gap); 
 932 int CmdVchDemod(const char *Cmd
) 
 934   // Is this the entire sync pattern, or does this also include some 
 935   // data bits that happen to be the same everywhere? That would be 
 937   static const int SyncPattern
[] = { 
 938     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 939     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 940     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 941     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 942     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 943     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 944     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 945     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 946     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 947     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 950   // So first, we correlate for the sync pattern, and mark that. 
 951   int bestCorrel 
= 0, bestPos 
= 0; 
 953   // It does us no good to find the sync pattern, with fewer than 
 954   // 2048 samples after it... 
 955   for (i 
= 0; i 
< (GraphTraceLen
-2048); i
++) { 
 958     for (j 
= 0; j 
< arraylen(SyncPattern
); j
++) { 
 959       sum 
+= GraphBuffer
[i
+j
]*SyncPattern
[j
]; 
 961     if (sum 
> bestCorrel
) { 
 966   PrintAndLog("best sync at %d [metric %d]", bestPos
, bestCorrel
); 
 974   for (i 
= 0; i 
< 2048; i 
+= 8) { 
 977     for (j 
= 0; j 
< 8; j
++) { 
 978       sum 
+= GraphBuffer
[bestPos
+i
+j
]; 
 985     if(abs(sum
) < worst
) { 
 990   PrintAndLog("bits:"); 
 991   PrintAndLog("%s", bits
); 
 992   PrintAndLog("worst metric: %d at pos %d", worst
, worstPos
); 
 994   if (strcmp(Cmd
, "clone")==0) { 
 997     for(s 
= bits
; *s
; s
++) { 
 999       for(j 
= 0; j 
< 16; j
++) { 
1000         GraphBuffer
[GraphTraceLen
++] = (*s 
== '1') ? 1 : 0; 
1003     RepaintGraphWindow(); 
1009 int CmdLFfind(const char *Cmd
) 
1012   char cmdp 
= param_getchar(Cmd
, 0); 
1013   char testRaw 
= param_getchar(Cmd
, 1); 
1014   if (strlen(Cmd
) > 2 || cmdp 
== 'h' || cmdp 
== 'H') { 
1015     PrintAndLog("Usage:  lf search <0|1> [u]"); 
1016     PrintAndLog("     <use data from Graphbuffer> , if not set, try reading data from tag."); 
1017     PrintAndLog("     [Search for Unknown tags] , if not set, reads only known tags."); 
1019     PrintAndLog("    sample: lf search     = try reading data from tag & search for known tags"); 
1020     PrintAndLog("          : lf search 1   = use data from GraphBuffer & search for known tags"); 
1021     PrintAndLog("          : lf search u   = try reading data from tag & search for known and unknown tags"); 
1022     PrintAndLog("          : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); 
1027   if (!offline 
&& (cmdp 
!= '1')){ 
1029     ans
=CmdSamples("20000"); 
1030   } else if (GraphTraceLen 
< 1000) { 
1031     PrintAndLog("Data in Graphbuffer was too small."); 
1034   if (cmdp 
== 'u' || cmdp 
== 'U') testRaw 
= 'u'; 
1035   PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag"); 
1036   PrintAndLog("False Positives ARE possible\n");   
1037   PrintAndLog("\nChecking for known tags:\n"); 
1038   ans
=CmdFSKdemodIO(""); 
1040     PrintAndLog("\nValid IO Prox ID Found!"); 
1043   ans
=CmdFSKdemodPyramid(""); 
1045     PrintAndLog("\nValid Pyramid ID Found!"); 
1048   ans
=CmdFSKdemodParadox(""); 
1050     PrintAndLog("\nValid Paradox ID Found!"); 
1053   ans
=CmdFSKdemodAWID(""); 
1055     PrintAndLog("\nValid AWID ID Found!"); 
1058   ans
=CmdFSKdemodHID(""); 
1060     PrintAndLog("\nValid HID Prox ID Found!"); 
1063   //add psk and indala 
1064   ans
=CmdIndalaDecode(""); 
1066     PrintAndLog("\nValid Indala ID Found!"); 
1069   ans
=CmdAskEM410xDemod(""); 
1071     PrintAndLog("\nValid EM410x ID Found!"); 
1074   ans
=CmdG_Prox_II_Demod(""); 
1076     PrintAndLog("\nValid G Prox II ID Found!"); 
1079   PrintAndLog("\nNo Known Tags Found!\n"); 
1080   if (testRaw
=='u' || testRaw
=='U'){ 
1081     //test unknown tag formats (raw mode) 
1082     PrintAndLog("\nChecking for Unknown tags:\n"); 
1083     ans
=AutoCorrelate(4000, FALSE
, FALSE
); 
1084     if (ans 
> 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans
); 
1085     ans
=CmdDetectClockRate("F"); //GetFSKClock("",TRUE,FALSE); 
1086     if (ans 
!= 0){ //fsk 
1087       ans
=CmdFSKrawdemod(""); 
1089         PrintAndLog("\nUnknown FSK Modulated Tag Found!"); 
1093     ans
=Cmdaskmandemod(""); 
1095       PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); 
1098     ans
=CmdPSK1rawDemod(""); 
1100       PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'"); 
1101       PrintAndLog("\nCould also be PSK3 - [currently not supported]"); 
1102       PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); 
1105     PrintAndLog("\nNo Data Found!\n"); 
1110 static command_t CommandTable
[] =  
1112   {"help",        CmdHelp
,            1, "This help"}, 
1113   {"cmdread",     CmdLFCommandRead
,   0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, 
1114   {"em4x",        CmdLFEM4X
,          1, "{ EM4X RFIDs... }"}, 
1115   {"config",      CmdLFSetConfig
,     0, "Set config for LF sampling, bit/sample, decimation, frequency"}, 
1116   {"flexdemod",   CmdFlexdemod
,       1, "Demodulate samples for FlexPass"}, 
1117   {"hid",         CmdLFHID
,           1, "{ HID RFIDs... }"}, 
1118   {"io",          CmdLFIO
,                1, "{ ioProx tags... }"}, 
1119   {"indalademod", CmdIndalaDemod
,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, 
1120   {"indalaclone", CmdIndalaClone
,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, 
1121   {"read",        CmdLFRead
,          0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, 
1122   {"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"}, 
1123   {"sim",         CmdLFSim
,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, 
1124   {"simask",      CmdLFaskSim
,        0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"}, 
1125   {"simfsk",      CmdLFfskSim
,        0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"}, 
1126   {"simpsk",      CmdLFpskSim
,        0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"}, 
1127   {"simbidir",    CmdLFSimBidir
,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, 
1128   //{"simman",      CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"}, 
1129   {"snoop",       CmdLFSnoop
,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, 
1130   {"ti",          CmdLFTI
,            1, "{ TI RFIDs... }"}, 
1131   {"hitag",       CmdLFHitag
,         1, "{ Hitag tags and transponders... }"}, 
1132   {"vchdemod",    CmdVchDemod
,        1, "['clone'] -- Demodulate samples for VeriChip"}, 
1133   {"t55xx",       CmdLFT55XX
,         1, "{ T55xx RFIDs... }"}, 
1134   {"pcf7931",     CmdLFPCF7931
,       1, "{PCF7931 RFIDs...}"}, 
1135   {NULL
, NULL
, 0, NULL
} 
1138 int CmdLF(const char *Cmd
) 
1140   CmdsParse(CommandTable
, Cmd
); 
1144 int CmdHelp(const char *Cmd
) 
1146   CmdsHelp(CommandTable
);