]>
 
 
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmddata.c 
 
 
 
 
 
 
 
   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  // Data and Graph commands  
   9  //-----------------------------------------------------------------------------  
  15  #include  "proxmark3.h"  
  19  #include  "cmdparser.h"  
  25  static int  CmdHelp ( const char  * Cmd
);  
  27  int  CmdAmp ( const char  * Cmd
)  
  29    int  i
,  rising
,  falling
;  
  30    int  max 
=  INT_MIN
,  min 
=  INT_MAX
;  
  32    for  ( i 
=  10 ;  i 
<  GraphTraceLen
; ++ i
) {  
  33      if  ( GraphBuffer
[ i
] >  max
)  
  35      if  ( GraphBuffer
[ i
] <  min
)  
  41      for  ( i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
) {  
  42        if  ( GraphBuffer
[ i 
+  1 ] <  GraphBuffer
[ i
]) {  
  49        if  ( GraphBuffer
[ i 
+  1 ] >  GraphBuffer
[ i
]) {  
  63   * Generic command to demodulate ASK.  
  65   * Argument is convention: positive or negative (High mod means zero  
  66   * or high mod means one)  
  68   * Updates the Graph trace with 0/1 values  
  73   //this method is dependant on all highs and lows to be the same(or clipped)  this creates issues[marshmellow] it also ignores the clock  
  74  int  Cmdaskdemod ( const char  * Cmd
)  
  77    int  c
,  high 
=  0 ,  low 
=  0 ;  
  79    // TODO: complain if we do not give 2 arguments here !  
  80    // (AL - this doesn't make sense! we're only using one argument!!!)  
  81    sscanf ( Cmd
,  " %i " , & c
);  
  83    /* Detect high and lows and clock */  
  85    for  ( i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
)  
  87      if  ( GraphBuffer
[ i
] >  high
)  
  88        high 
=  GraphBuffer
[ i
];  
  89      else if  ( GraphBuffer
[ i
] <  low
)  
  94    if  ( c 
!=  0  &&  c 
!=  1 ) {  
  95      PrintAndLog ( "Invalid argument:  %s " ,  Cmd
);  
  99    if  ( GraphBuffer
[ 0 ] >  0 ) {  
 100      GraphBuffer
[ 0 ] =  1 - c
;  
 104    for  ( i 
=  1 ;  i 
<  GraphTraceLen
; ++ i
) {  
 105      /* Transitions are detected at each peak  
 106       * Transitions are either:  
 107       * - we're low: transition if we hit a high  
 108       * - we're high: transition if we hit a low  
 109       * (we need to do it this way because some tags keep high or  
 110       * low for long periods, others just reach the peak and go  
 113      //[marhsmellow] change == to >= for high and <= for low for fuzz  
 114      if  (( GraphBuffer
[ i
] ==  high
) && ( GraphBuffer
[ i 
-  1 ] ==  c
)) {  
 115        GraphBuffer
[ i
] =  1  -  c
;  
 116      }  else if  (( GraphBuffer
[ i
] ==  low
) && ( GraphBuffer
[ i 
-  1 ] == ( 1  -  c
))){  
 120        GraphBuffer
[ i
] =  GraphBuffer
[ i 
-  1 ];  
 123    RepaintGraphWindow ();  
 128  void  printBitStream ( uint8_t  BitStream
[],  uint32_t  bitLen
)  
 132      PrintAndLog ( "Too few bits found:  %d " , bitLen
);  
 135    if  ( bitLen
> 512 )  bitLen
= 512 ;  
 136     for  ( i 
=  0 ;  i 
<= ( bitLen
- 16 );  i
+= 16 ) {  
 137      PrintAndLog ( " %i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i " ,  
 158  void  printEM410x ( uint64_t  id
)  
 162        uint64_t  id2lo
= 0 ;  //id2hi=0,  
 165        for  ( ii
= 5 ;  ii
> 0 ; ii
--){  
 167            id2lo
=( id2lo
<< 1LL )|(( id 
& ( iii
<<( i
+(( ii
- 1 )* 8 ))))>>( i
+(( ii
- 1 )* 8 )));  
 171        PrintAndLog ( "EM TAG ID    :  %0 10llx" ,  id
);  
 172        PrintAndLog ( "Unique TAG ID:  %0 10llx" ,   id2lo
);  //id2hi,  
 173        PrintAndLog ( "DEZ 8        :  %0 8lld" , id 
&  0xFFFFFF );  
 174        PrintAndLog ( "DEZ 10       :  %0 10lld" , id 
&  0xFFFFFF );  
 175        PrintAndLog ( "DEZ 5.5      :  %0 5lld. %0 5lld" ,( id
>> 16LL ) &  0xFFFF ,( id 
&  0xFFFF ));  
 176        PrintAndLog ( "DEZ 3.5A     :  %0 3lld. %0 5lld" ,( id
>> 32ll ),( id 
&  0xFFFF ));  
 177        PrintAndLog ( "DEZ 14/IK2   :  %0 14lld" , id
);  
 178        PrintAndLog ( "DEZ 15/IK3   :  %0 15lld" , id2lo
);  
 179        PrintAndLog ( "Other        :  %0 5lld_ %0 3lld_ %0 8lld" ,( id
& 0xFFFF ),(( id
>> 16LL ) &  0xFF ),( id 
&  0xFFFFFF ));  
 185  int  CmdEm410xDecode ( const char  * Cmd
)  
 188    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 190    i
= getFromGraphBuf ( BitStream
);  
 191    id 
=  Em410xDecode ( BitStream
, i
);  
 199  //takes 2 arguments - clock and invert both as integers  
 200  //attempts to demodulate ask while decoding manchester   
 201  //prints binary found and saves in graphbuffer for further commands  
 202  int  Cmdaskmandemod ( const char  * Cmd
)  
 206    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 207    sscanf ( Cmd
,  " %i %i " , & clk
, & invert
);      
 208    if  ( invert 
!=  0  &&  invert 
!=  1 ) {  
 209      PrintAndLog ( "Invalid argument:  %s " ,  Cmd
);  
 212    uint32_t  BitLen 
=  getFromGraphBuf ( BitStream
);  
 213    //  PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);  
 215     errCnt 
=  askmandemod ( BitStream
, & BitLen
,& clk
,& invert
);  
 216    if  ( errCnt
< 0 ){   //if fatal error (or -1)  
 217      // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);   
 220    if  ( BitLen
< 16 )  return  0 ;  
 221    PrintAndLog ( " \n Using Clock:  %d  - Invert:  %d  - Bits Found:  %d " , clk
, invert
, BitLen
);  
 225      PrintAndLog ( "# Errors during Demoding (shown as 77 in bit stream):  %d " , errCnt
);  
 227    PrintAndLog ( "ASK/Manchester decoded bitstream:" );  
 228    // Now output the bitstream to the scrollback by line of 16 bits  
 229    printBitStream ( BitStream
, BitLen
);  
 231    lo 
=  Em410xDecode ( BitStream
, BitLen
);  
 233      //set GraphBuffer for clone or sim command  
 234      setGraphBuf ( BitStream
, BitLen
);   
 235      PrintAndLog ( "EM410x pattern found: " );  
 239    //if (BitLen>16) return 1;  
 245  //stricktly take 10 and 01 and convert to 0 and 1  
 246  int  Cmdmandecoderaw ( const char  * Cmd
)  
 251    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 253    for  (; i
< GraphTraceLen
;++ i
){  
 254      if  ( GraphBuffer
[ i
]> high
)  high
= GraphBuffer
[ i
];  
 255      else if ( GraphBuffer
[ i
]< low
)  low
= GraphBuffer
[ i
];  
 256      BitStream
[ i
]= GraphBuffer
[ i
];  
 258    if  ( high
> 1  ||  low 
< 0  ){  
 259      PrintAndLog ( "Error: please raw demod the wave first then mancheseter raw decode" );  
 263    errCnt
= manrawdecode ( BitStream
,& bitnum
);  
 265      PrintAndLog ( "Too many errors:  %d " , errCnt
);  
 268    PrintAndLog ( "Manchester Decoded - # errors: %d  - data:" , errCnt
);  
 269    printBitStream ( BitStream
, bitnum
);  
 271      //put back in graphbuffer  
 273      for  ( i
= 0 ;  i
< bitnum
;++ i
){  
 274        GraphBuffer
[ i
]= BitStream
[ i
];  
 276      GraphTraceLen
= bitnum
;  
 277      RepaintGraphWindow ();  
 279      id 
=  Em410xDecode ( BitStream
, i
);  
 287  //take 01 or 10 = 0 and 11 or 00 = 1  
 288  //takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit  
 289  //  since it is not like manchester and doesn't have an incorrect bit pattern we   
 290  //  cannot determine if our decode is correct or if it should be shifted by one bit  
 291  //  the argument offset allows us to manually shift if the output is incorrect  
 292  //  (better would be to demod and decode at the same time so we can distinguish large  
 293  //    width waves vs small width waves to help the decode positioning) or askbiphdemod  
 294  int  CmdBiphaseDecodeRaw ( const char  * Cmd
)  
 301    sscanf ( Cmd
,  " %i " , & offset
);      
 302    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 303    //get graphbuffer & high and low  
 304    for  (; i
< GraphTraceLen
;++ i
){  
 305      if ( GraphBuffer
[ i
]> high
) high
= GraphBuffer
[ i
];  
 306      else if ( GraphBuffer
[ i
]< low
) low
= GraphBuffer
[ i
];  
 307      BitStream
[ i
]= GraphBuffer
[ i
];  
 309    if  ( high
> 1  ||  low 
< 0 ){  
 310      PrintAndLog ( "Error: please raw demod the wave first then decode" );  
 314    errCnt
= BiphaseRawDecode ( BitStream
,& bitnum
,  offset
);  
 316      PrintAndLog ( "Too many errors attempting to decode:  %d " , errCnt
);  
 319    PrintAndLog ( "Biphase Decoded using offset:  %d  - # errors: %d  - data:" , offset
, errCnt
);  
 320    printBitStream ( BitStream
, bitnum
);  
 321    PrintAndLog ( " \n if bitstream does not look right try offset=1" );  
 327  //takes 2 arguments - clock and invert both as integers  
 328  //attempts to demodulate ask only  
 329  //prints binary found and saves in graphbuffer for further commands  
 330  int  Cmdaskrawdemod ( const char  * Cmd
)  
 335    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 336    sscanf ( Cmd
,  " %i %i " , & clk
, & invert
);      
 337    if  ( invert 
!=  0  &&  invert 
!=  1 ) {  
 338      PrintAndLog ( "Invalid argument:  %s " ,  Cmd
);  
 341    int  BitLen 
=  getFromGraphBuf ( BitStream
);  
 343    errCnt 
=  askrawdemod ( BitStream
, & BitLen
,& clk
,& invert
);  
 344    if  ( errCnt
==- 1 ){   //throw away static - allow 1 and -1 (in case of threshold command first)  
 345      PrintAndLog ( "no data found" );   
 348    if  ( BitLen
< 16 )  return  0 ;  
 349    PrintAndLog ( "Using Clock:  %d  - invert:  %d  - Bits Found:  %d " , clk
, invert
, BitLen
);  
 350      //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);  
 351      //move BitStream back to GraphBuffer  
 354    for  ( i
= 0 ;  i 
<  BitLen
; ++ i
){  
 355      GraphBuffer
[ i
]= BitStream
[ i
];  
 357    GraphTraceLen
= BitLen
;  
 358    RepaintGraphWindow ();  
 362      PrintAndLog ( "# Errors during Demoding (shown as 77 in bit stream):  %d " , errCnt
);  
 364    PrintAndLog ( "ASK demoded bitstream:" );  
 365    // Now output the bitstream to the scrollback by line of 16 bits  
 366    printBitStream ( BitStream
, BitLen
);  
 371  int  CmdAutoCorr ( const char  * Cmd
)  
 373    static int  CorrelBuffer
[ MAX_GRAPH_TRACE_LEN
];  
 375    int  window 
=  atoi ( Cmd
);  
 378      PrintAndLog ( "needs a window" );  
 381    if  ( window 
>=  GraphTraceLen
) {  
 382      PrintAndLog ( "window must be smaller than trace ( %d  samples)" ,  
 387    PrintAndLog ( "performing  %d  correlations" ,  GraphTraceLen 
-  window
);  
 389    for  ( int  i 
=  0 ;  i 
<  GraphTraceLen 
-  window
; ++ i
) {  
 391      for  ( int  j 
=  0 ;  j 
<  window
; ++ j
) {  
 392        sum 
+= ( GraphBuffer
[ j
]* GraphBuffer
[ i 
+  j
]) /  256 ;  
 394      CorrelBuffer
[ i
] =  sum
;  
 396    GraphTraceLen 
=  GraphTraceLen 
-  window
;  
 397    memcpy ( GraphBuffer
,  CorrelBuffer
,  GraphTraceLen 
*  sizeof  ( int ));  
 399    RepaintGraphWindow ();  
 403  int  CmdBitsamples ( const char  * Cmd
)  
 408    GetFromBigBuf ( got
, sizeof ( got
), 0 );  
 409    WaitForResponse ( CMD_ACK
, NULL
);  
 411      for  ( int  j 
=  0 ;  j 
<  sizeof ( got
);  j
++) {  
 412        for  ( int  k 
=  0 ;  k 
<  8 ;  k
++) {  
 413          if ( got
[ j
] & ( 1  << ( 7  -  k
))) {  
 414            GraphBuffer
[ cnt
++] =  1 ;  
 416            GraphBuffer
[ cnt
++] =  0 ;  
 421    RepaintGraphWindow ();  
 426   * Convert to a bitstream  
 428  int  CmdBitstream ( const char  * Cmd
)  
 436    int  hithigh
,  hitlow
,  first
;  
 438    /* Detect high and lows and clock */  
 439    for  ( i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
)  
 441      if  ( GraphBuffer
[ i
] >  high
)  
 442        high 
=  GraphBuffer
[ i
];  
 443      else if  ( GraphBuffer
[ i
] <  low
)  
 444        low 
=  GraphBuffer
[ i
];  
 448    clock 
=  GetClock ( Cmd
,  high
,  1 );  
 452    for  ( i 
=  0 ;  i 
< ( int )( gtl 
/  clock
); ++ i
)  
 457      /* Find out if we hit both high and low peaks */  
 458      for  ( j 
=  0 ;  j 
<  clock
; ++ j
)  
 460        if  ( GraphBuffer
[( i 
*  clock
) +  j
] ==  high
)  
 462        else if  ( GraphBuffer
[( i 
*  clock
) +  j
] ==  low
)  
 464        /* it doesn't count if it's the first part of our read  
 465           because it's really just trailing from the last sequence */  
 466        if  ( first 
&& ( hithigh 
||  hitlow
))  
 467          hithigh 
=  hitlow 
=  0 ;  
 471        if  ( hithigh 
&&  hitlow
)  
 475      /* If we didn't hit both high and low peaks, we had a bit transition */  
 476      if  (! hithigh 
|| ! hitlow
)  
 479      AppendGraph ( 0 ,  clock
,  bit
);  
 480    //    for (j = 0; j < (int)(clock/2); j++)  
 481    //      GraphBuffer[(i * clock) + j] = bit ^ 1;  
 482    //    for (j = (int)(clock/2); j < clock; j++)  
 483    //      GraphBuffer[(i * clock) + j] = bit;  
 486    RepaintGraphWindow ();  
 490  int  CmdBuffClear ( const char  * Cmd
)  
 492    UsbCommand c 
= { CMD_BUFF_CLEAR
};  
 498  int  CmdDec ( const char  * Cmd
)  
 500    for  ( int  i 
=  0 ;  i 
< ( GraphTraceLen 
/  2 ); ++ i
)  
 501      GraphBuffer
[ i
] =  GraphBuffer
[ i 
*  2 ];  
 503    PrintAndLog ( "decimated by 2" );  
 504    RepaintGraphWindow ();  
 508  /* Print our clock rate */  
 509  // uses data from graphbuffer   
 510  int  CmdDetectClockRate ( const char  * Cmd
)  
 513    //int clock = DetectASKClock(0);  
 514    //PrintAndLog("Auto-detected clock rate: %d", clock);  
 519  //fsk raw demod and print binary  
 520  //takes 4 arguments - Clock, invert, rchigh, rclow  
 521  //defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))  
 522  int  CmdFSKrawdemod ( const char  * Cmd
)  
 524    //raw fsk demod  no manchester decoding no start bit finding just get binary from wave  
 530    //set options from parameters entered with the command  
 531    sscanf ( Cmd
,  " %i %i %i %i " , & rfLen
, & invert
, & fchigh
, & fclow
);      
 533    if  ( strlen ( Cmd
)> 0  &&  strlen ( Cmd
)<= 2 ) {  
 534       //rfLen=param_get8(Cmd, 0); //if rfLen option only is used  
 536        invert
= 1 ;    //if invert option only is used  
 538       }  else if ( rfLen
== 0 )  rfLen
= 50 ;  
 540    PrintAndLog ( "Args invert:  %d  - Clock: %d  - fchigh: %d  - fclow:  %d " , invert
, rfLen
, fchigh
,  fclow
);  
 542    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 543    uint32_t  BitLen 
=  getFromGraphBuf ( BitStream
);  
 544    int  size  
=  fskdemod ( BitStream
, BitLen
,( uint8_t ) rfLen
,( uint8_t ) invert
,( uint8_t ) fchigh
,( uint8_t ) fclow
);   
 546      PrintAndLog ( "FSK decoded bitstream:" );  
 548      for  ( i
= 0 ; i
< size
;++ i
){  
 549        GraphBuffer
[ i
]= BitStream
[ i
];  
 552      RepaintGraphWindow ();  
 554      // Now output the bitstream to the scrollback by line of 16 bits  
 555      if ( size 
> ( 8 * 32 )+ 2 )  size 
= ( 8 * 32 )+ 2 ;  //only output a max of 8 blocks of 32 bits  most tags will have full bit stream inside that sample size  
 556      printBitStream ( BitStream
, size
);  
 558      PrintAndLog ( "no FSK data found" );  
 563  //by marshmellow (based on existing demod + holiman's refactor)  
 564  //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)  
 565  //print full HID Prox ID and some bit format details if found  
 566  int  CmdFSKdemodHID ( const char  * Cmd
)  
 568    //raw fsk demod no manchester decoding no start bit finding just get binary from wave  
 569    uint32_t  hi2
= 0 ,  hi
= 0 ,  lo
= 0 ;  
 571    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 572    uint32_t  BitLen 
=  getFromGraphBuf ( BitStream
);  
 573    //get binary from fsk wave  
 574    size_t  size  
=  HIDdemodFSK ( BitStream
, BitLen
,& hi2
,& hi
,& lo
);   
 576      PrintAndLog ( "Error demoding fsk" );  
 579    if  ( hi2
== 0  &&  hi
== 0  &&  lo
== 0 )  return  0 ;  
 580    if  ( hi2 
!=  0 ){  //extra large HID tags  
 581      PrintAndLog ( "TAG ID:  %x%0 8x %0 8x ( %d )" ,  
 582         ( unsigned int )  hi2
, ( unsigned int )  hi
, ( unsigned int )  lo
, ( unsigned int ) ( lo
>> 1 ) &  0xFFFF );  
 583      setGraphBuf ( BitStream
, BitLen
);  
 586    else  {   //standard HID tags <38 bits  
 587      //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd  
 590      uint32_t  cardnum 
=  0 ;  
 591      if  ((( hi
>> 5 )& 1 )== 1 ){ //if bit 38 is set then < 37 bit format is used  
 593        lo2
=((( hi 
&  15 ) <<  12 ) | ( lo
>> 20 ));  //get bits 21-37 to check for format len bit  
 595        while ( lo2
> 1 ){  //find last bit set to 1 (format len bit)  
 603          cardnum 
= ( lo
>> 1 )& 0xFFFF ;  
 607          cardnum 
= ( lo
>> 1 )& 0x7FFFF ;  
 608          fc 
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );  
 611          cardnum 
= ( lo
>> 1 )& 0xFFFF ;  
 612          fc
= (( hi
& 1 )<< 15 )|( lo
>> 17 );  
 615          cardnum 
= ( lo
>> 1 )& 0xFFFFF ;  
 616          fc 
= (( hi
& 1 )<< 11 )|( lo
>> 21 );  
 619      else  {  //if bit 38 is not set then 37 bit format is used  
 624          cardnum 
= ( lo
>> 1 )& 0x7FFFF ;  
 625          fc 
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );  
 628      PrintAndLog ( "TAG ID:  %x%0 8x ( %d ) - Format Len:  %d bit - FC:  %d  - Card:  %d " ,  
 629        ( unsigned int )  hi
, ( unsigned int )  lo
, ( unsigned int ) ( lo
>> 1 ) &  0xFFFF ,  
 630        ( unsigned int )  fmtLen
, ( unsigned int )  fc
, ( unsigned int )  cardnum
);  
 631      setGraphBuf ( BitStream
, BitLen
);  
 638  //IO-Prox demod - FSK RF/64 with preamble of 000000001  
 639  //print ioprox ID and some format details  
 640  int  CmdFSKdemodIO ( const char  * Cmd
)  
 642    //raw fsk demod no manchester decoding no start bit finding just get binary from wave  
 645    //something in graphbuffer  
 646    if  ( GraphTraceLen 
<  65 )  return  0 ;  
 647    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };  
 648    uint32_t  BitLen 
=  getFromGraphBuf ( BitStream
);  
 649    //get binary from fsk wave  
 650   // PrintAndLog("DEBUG: got buff");  
 651    idx 
=  IOdemodFSK ( BitStream
, BitLen
);   
 653      //PrintAndLog("Error demoding fsk");  
 656   // PrintAndLog("DEBUG: Got IOdemodFSK");  
 658      //PrintAndLog("IO Prox Data not found - FSK Data:");  
 659      //if (BitLen > 92) printBitStream(BitStream,92);  
 663      //0           10          20          30          40          50          60  
 665      //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23  
 666      //-----------------------------------------------------------------------------  
 667      //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11  
 669      //XSF(version)facility:codeone+codetwo (raw)  
 671    if  ( idx
+ 64 > BitLen
)  return  0 ;  
 672    PrintAndLog ( " %d%d%d%d%d%d%d%d %d " , BitStream
[ idx
],     BitStream
[ idx
+ 1 ],   BitStream
[ idx
+ 2 ],  BitStream
[ idx
+ 3 ],  BitStream
[ idx
+ 4 ],  BitStream
[ idx
+ 5 ],  BitStream
[ idx
+ 6 ],  BitStream
[ idx
+ 7 ],  BitStream
[ idx
+ 8 ]);  
 673    PrintAndLog ( " %d%d%d%d%d%d%d%d %d " , BitStream
[ idx
+ 9 ],   BitStream
[ idx
+ 10 ],  BitStream
[ idx
+ 11 ], BitStream
[ idx
+ 12 ], BitStream
[ idx
+ 13 ], BitStream
[ idx
+ 14 ], BitStream
[ idx
+ 15 ], BitStream
[ idx
+ 16 ], BitStream
[ idx
+ 17 ]);         
 674    PrintAndLog ( " %d%d%d%d%d%d%d%d %d  facility" , BitStream
[ idx
+ 18 ],  BitStream
[ idx
+ 19 ],  BitStream
[ idx
+ 20 ], BitStream
[ idx
+ 21 ], BitStream
[ idx
+ 22 ], BitStream
[ idx
+ 23 ], BitStream
[ idx
+ 24 ], BitStream
[ idx
+ 25 ], BitStream
[ idx
+ 26 ]);  
 675    PrintAndLog ( " %d%d%d%d%d%d%d%d %d  version" , BitStream
[ idx
+ 27 ],  BitStream
[ idx
+ 28 ],  BitStream
[ idx
+ 29 ], BitStream
[ idx
+ 30 ], BitStream
[ idx
+ 31 ], BitStream
[ idx
+ 32 ], BitStream
[ idx
+ 33 ], BitStream
[ idx
+ 34 ], BitStream
[ idx
+ 35 ]);  
 676    PrintAndLog ( " %d%d%d%d%d%d%d%d %d  code1" , BitStream
[ idx
+ 36 ],  BitStream
[ idx
+ 37 ],  BitStream
[ idx
+ 38 ], BitStream
[ idx
+ 39 ], BitStream
[ idx
+ 40 ], BitStream
[ idx
+ 41 ], BitStream
[ idx
+ 42 ], BitStream
[ idx
+ 43 ], BitStream
[ idx
+ 44 ]);  
 677    PrintAndLog ( " %d%d%d%d%d%d%d%d %d  code2" , BitStream
[ idx
+ 45 ],  BitStream
[ idx
+ 46 ],  BitStream
[ idx
+ 47 ], BitStream
[ idx
+ 48 ], BitStream
[ idx
+ 49 ], BitStream
[ idx
+ 50 ], BitStream
[ idx
+ 51 ], BitStream
[ idx
+ 52 ], BitStream
[ idx
+ 53 ]);  
 678    PrintAndLog ( " %d%d%d%d%d%d%d%d %d%d  checksum" , BitStream
[ idx
+ 54 ], BitStream
[ idx
+ 55 ], BitStream
[ idx
+ 56 ], BitStream
[ idx
+ 57 ], BitStream
[ idx
+ 58 ], BitStream
[ idx
+ 59 ], BitStream
[ idx
+ 60 ], BitStream
[ idx
+ 61 ], BitStream
[ idx
+ 62 ], BitStream
[ idx
+ 63 ]);  
 680    uint32_t  code 
=  bytebits_to_byte ( BitStream
+ idx
, 32 );  
 681    uint32_t  code2 
=  bytebits_to_byte ( BitStream
+ idx
+ 32 , 32 );   
 682    uint8_t  version 
=  bytebits_to_byte ( BitStream
+ idx
+ 27 , 8 );  //14,4  
 683    uint8_t  facilitycode 
=  bytebits_to_byte ( BitStream
+ idx
+ 18 , 8 ) ;  
 684    uint16_t  number 
= ( bytebits_to_byte ( BitStream
+ idx
+ 36 , 8 )<< 8 )|( bytebits_to_byte ( BitStream
+ idx
+ 45 , 8 ));  //36,9  
 686    PrintAndLog ( "XSF( %0 2d) %0 2x: %0 5d ( %0 8x %0 8x)" , version
, facilitycode
, number
, code
, code2
);      
 687    setGraphBuf ( BitStream
, BitLen
);  
 690  int  CmdFSKdemod ( const char  * Cmd
)  //old CmdFSKdemod needs updating  
 692    static const int  LowTone
[]  = {  
 693      1 ,   1 ,   1 ,   1 ,   1 , - 1 , - 1 , - 1 , - 1 , - 1 ,  
 694      1 ,   1 ,   1 ,   1 ,   1 , - 1 , - 1 , - 1 , - 1 , - 1 ,  
 695      1 ,   1 ,   1 ,   1 ,   1 , - 1 , - 1 , - 1 , - 1 , - 1 ,  
 696      1 ,   1 ,   1 ,   1 ,   1 , - 1 , - 1 , - 1 , - 1 , - 1 ,  
 697      1 ,   1 ,   1 ,   1 ,   1 , - 1 , - 1 , - 1 , - 1 , - 1  
 699    static const int  HighTone
[] = {  
 700      1 ,   1 ,   1 ,   1 ,   1 ,     - 1 , - 1 , - 1 , - 1 ,  
 701      1 ,   1 ,   1 ,   1 ,         - 1 , - 1 , - 1 , - 1 ,  
 702      1 ,   1 ,   1 ,   1 ,         - 1 , - 1 , - 1 , - 1 ,  
 703      1 ,   1 ,   1 ,   1 ,         - 1 , - 1 , - 1 , - 1 ,  
 704      1 ,   1 ,   1 ,   1 ,         - 1 , - 1 , - 1 , - 1 ,  
 705      1 ,   1 ,   1 ,   1 ,     - 1 , - 1 , - 1 , - 1 , - 1 ,  
 708    int  lowLen 
=  sizeof  ( LowTone
) /  sizeof  ( int );  
 709    int  highLen 
=  sizeof  ( HighTone
) /  sizeof  ( int );  
 710    int  convLen 
= ( highLen 
>  lowLen
) ?  highLen 
:  lowLen
;  //if highlen > lowLen then highlen else lowlen  
 711    uint32_t  hi 
=  0 ,  lo 
=  0 ;  
 714    int  minMark 
=  0 ,  maxMark 
=  0 ;  
 716    for  ( i 
=  0 ;  i 
<  GraphTraceLen 
-  convLen
; ++ i
) {  
 717      int  lowSum 
=  0 ,  highSum 
=  0 ;  
 719      for  ( j 
=  0 ;  j 
<  lowLen
; ++ j
) {  
 720        lowSum 
+=  LowTone
[ j
]* GraphBuffer
[ i
+ j
];  
 722      for  ( j 
=  0 ;  j 
<  highLen
; ++ j
) {  
 723        highSum 
+=  HighTone
[ j
] *  GraphBuffer
[ i 
+  j
];  
 725      lowSum 
=  abs ( 100  *  lowSum 
/  lowLen
);  
 726      highSum 
=  abs ( 100  *  highSum 
/  highLen
);  
 727      GraphBuffer
[ i
] = ( highSum 
<<  16 ) |  lowSum
;  
 730    for ( i 
=  0 ;  i 
<  GraphTraceLen 
-  convLen 
-  16 ; ++ i
) {  
 731      int  lowTot 
=  0 ,  highTot 
=  0 ;  
 732      // 10 and 8 are f_s divided by f_l and f_h, rounded  
 733      for  ( j 
=  0 ;  j 
<  10 ; ++ j
) {  
 734        lowTot 
+= ( GraphBuffer
[ i
+ j
] &  0xffff );  
 736      for  ( j 
=  0 ;  j 
<  8 ;  j
++) {  
 737        highTot 
+= ( GraphBuffer
[ i 
+  j
] >>  16 );  
 739      GraphBuffer
[ i
] =  lowTot 
-  highTot
;  
 740      if  ( GraphBuffer
[ i
] >  maxMark
)  maxMark 
=  GraphBuffer
[ i
];  
 741      if  ( GraphBuffer
[ i
] <  minMark
)  minMark 
=  GraphBuffer
[ i
];  
 744    GraphTraceLen 
-= ( convLen 
+  16 );  
 745    RepaintGraphWindow ();  
 747    // Find bit-sync (3 lo followed by 3 high) (HID ONLY)  
 748    int  max 
=  0 ,  maxPos 
=  0 ;  
 749    for  ( i 
=  0 ;  i 
<  6000 ; ++ i
) {  
 751      for  ( j 
=  0 ;  j 
<  3  *  lowLen
; ++ j
) {  
 752        dec 
-=  GraphBuffer
[ i 
+  j
];  
 754      for  (;  j 
<  3  * ( lowLen 
+  highLen 
); ++ j
) {  
 755        dec 
+=  GraphBuffer
[ i 
+  j
];  
 763    // place start of bit sync marker in graph  
 764    GraphBuffer
[ maxPos
] =  maxMark
;  
 765    GraphBuffer
[ maxPos 
+  1 ] =  minMark
;  
 769    // place end of bit sync marker in graph  
 770    GraphBuffer
[ maxPos
] =  maxMark
;  
 771    GraphBuffer
[ maxPos
+ 1 ] =  minMark
;  
 773    PrintAndLog ( "actual data bits start at sample  %d " ,  maxPos
);  
 774    PrintAndLog ( "length  %d / %d " ,  highLen
,  lowLen
);  
 777    bits
[ sizeof ( bits
)- 1 ] =  '\0' ;  
 779    // find bit pairs and manchester decode them  
 780    for  ( i 
=  0 ;  i 
<  arraylen ( bits
) -  1 ; ++ i
) {  
 782      for  ( j 
=  0 ;  j 
<  lowLen
; ++ j
) {  
 783        dec 
-=  GraphBuffer
[ maxPos 
+  j
];  
 785      for  (;  j 
<  lowLen 
+  highLen
; ++ j
) {  
 786        dec 
+=  GraphBuffer
[ maxPos 
+  j
];  
 789      // place inter bit marker in graph  
 790      GraphBuffer
[ maxPos
] =  maxMark
;  
 791      GraphBuffer
[ maxPos 
+  1 ] =  minMark
;  
 793      // hi and lo form a 64 bit pair  
 794      hi 
= ( hi 
<<  1 ) | ( lo 
>>  31 );  
 796      // store decoded bit as binary (in hi/lo) and text (in bits[])  
 804    PrintAndLog ( "bits: ' %s '" ,  bits
);  
 805    PrintAndLog ( "hex:  %0 8x  %0 8x" ,  hi
,  lo
);  
 809  int  CmdGrid ( const char  * Cmd
)  
 811    sscanf ( Cmd
,  " %i %i " , & PlotGridX
, & PlotGridY
);  
 812    PlotGridXdefault
=  PlotGridX
;  
 813    PlotGridYdefault
=  PlotGridY
;  
 814    RepaintGraphWindow ();  
 818  int  CmdHexsamples ( const char  * Cmd
)  
 824    char *  string_ptr 
=  string_buf
;  
 827    sscanf ( Cmd
,  " %i %i " , & requested
, & offset
);  
 829    /* if no args send something */  
 830    if  ( requested 
==  0 ) {  
 833    if  ( offset 
+  requested 
>  sizeof ( got
)) {  
 834      PrintAndLog ( "Tried to read past end of buffer, <bytes> + <offset> > 40000" );  
 838    GetFromBigBuf ( got
, requested
, offset
);  
 839    WaitForResponse ( CMD_ACK
, NULL
);  
 842    for  ( j 
=  0 ;  j 
<  requested
;  j
++) {  
 844      string_ptr 
+=  sprintf ( string_ptr
,  " %0 2x " ,  got
[ j
]);  
 846        *( string_ptr 
-  1 ) =  '\0' ;     // remove the trailing space  
 847        PrintAndLog ( " %s " ,  string_buf
);  
 848        string_buf
[ 0 ] =  '\0' ;  
 849        string_ptr 
=  string_buf
;  
 852      if  ( j 
==  requested 
-  1  &&  string_buf
[ 0 ] !=  '\0' ) {  // print any remaining bytes  
 853        *( string_ptr 
-  1 ) =  '\0' ;  
 854        PrintAndLog ( " %s " ,  string_buf
);  
 855        string_buf
[ 0 ] =  '\0' ;  
 861  int  CmdHide ( const char  * Cmd
)  
 867  int  CmdHpf ( const char  * Cmd
)  
 872    for  ( i 
=  10 ;  i 
<  GraphTraceLen
; ++ i
)  
 873      accum 
+=  GraphBuffer
[ i
];  
 874    accum 
/= ( GraphTraceLen 
-  10 );  
 875    for  ( i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
)  
 876      GraphBuffer
[ i
] -=  accum
;  
 878    RepaintGraphWindow ();  
 882  int  CmdSamples ( const char  * Cmd
)  
 888    n 
=  strtol ( Cmd
,  NULL
,  0 );  
 889    if  ( n 
==  0 )  n 
=  6000 ;  
 890    if  ( n 
>  sizeof ( got
))  n 
=  sizeof ( got
);  
 892    PrintAndLog ( "Reading  %d  samples \n " ,  n
);  
 893    GetFromBigBuf ( got
, n
, 0 );  
 894    WaitForResponse ( CMD_ACK
, NULL
);  
 895    for  ( int  j 
=  0 ;  j 
<  n
;  j
++) {  
 896      GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) -  128 ;  
 899    PrintAndLog ( "Done! \n " );  
 901    RepaintGraphWindow ();  
 905  int  CmdTuneSamples ( const char  * Cmd
)  
 911    PrintAndLog ( "Reading  %d  samples \n " ,  n
);  
 912    GetFromBigBuf ( got
, n
, 7256 );  // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256  
 913    WaitForResponse ( CMD_ACK
, NULL
);  
 914    for  ( int  j 
=  0 ;  j 
<  n
;  j
++) {  
 915      GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) -  128 ;  
 918    PrintAndLog ( "Done! Divisor 89 is 134khz, 95 is 125khz. \n " );  
 921    RepaintGraphWindow ();  
 925  int  CmdLoad ( const char  * Cmd
)  
 927    FILE  * f 
=  fopen ( Cmd
,  "r" );  
 929      PrintAndLog ( "couldn't open ' %s '" ,  Cmd
);  
 935    while  ( fgets ( line
,  sizeof  ( line
),  f
)) {  
 936      GraphBuffer
[ GraphTraceLen
] =  atoi ( line
);  
 940    PrintAndLog ( "loaded  %d  samples" ,  GraphTraceLen
);  
 941    RepaintGraphWindow ();  
 945  int  CmdLtrim ( const char  * Cmd
)  
 949    for  ( int  i 
=  ds
;  i 
<  GraphTraceLen
; ++ i
)  
 950      GraphBuffer
[ i
- ds
] =  GraphBuffer
[ i
];  
 953    RepaintGraphWindow ();  
 956  int  CmdRtrim ( const char  * Cmd
)  
 962    RepaintGraphWindow ();  
 967   * Manchester demodulate a bitstream. The bitstream needs to be already in  
 968   * the GraphBuffer as 0 and 1 values  
 970   * Give the clock rate as argument in order to help the sync - the algorithm  
 971   * resyncs at each pulse anyway.  
 973   * Not optimized by any means, this is the 1st time I'm writing this type of  
 974   * routine, feel free to improve...  
 976   * 1st argument: clock rate (as number of samples per clock rate)  
 977   *               Typical values can be 64, 32, 128...  
 979  int  CmdManchesterDemod ( const char  * Cmd
)  
 987    int  hithigh
,  hitlow
,  first
;  
 993    /* check if we're inverting output */  
 996      PrintAndLog ( "Inverting output" );  
1001      while (* Cmd 
==  ' ' );  // in case a 2nd argument was given  
1004    /* Holds the decoded bitstream: each clock period contains 2 bits       */  
1005    /* later simplified to 1 bit after manchester decoding.                 */  
1006    /* Add 10 bits to allow for noisy / uncertain traces without aborting   */  
1007    /* int BitStream[GraphTraceLen*2/clock+10]; */  
1009    /* But it does not work if compiling on WIndows: therefore we just allocate a */  
1011    uint8_t  BitStream
[ MAX_GRAPH_TRACE_LEN
] = { 0 };  
1013    /* Detect high and lows */  
1014    for  ( i 
=  0 ;  i 
<  GraphTraceLen
;  i
++)  
1016      if  ( GraphBuffer
[ i
] >  high
)  
1017        high 
=  GraphBuffer
[ i
];  
1018      else if  ( GraphBuffer
[ i
] <  low
)  
1019        low 
=  GraphBuffer
[ i
];  
1023    clock 
=  GetClock ( Cmd
,  high
,  1 );  
1025    int  tolerance 
=  clock
/ 4 ;  
1027    /* Detect first transition */  
1028    /* Lo-Hi (arbitrary)       */  
1029    /* skip to the first high */  
1030    for  ( i
=  0 ;  i 
<  GraphTraceLen
;  i
++)  
1031      if  ( GraphBuffer
[ i
] ==  high
)  
1033    /* now look for the first low */  
1034    for  (;  i 
<  GraphTraceLen
;  i
++)  
1036      if  ( GraphBuffer
[ i
] ==  low
)  
1043    /* If we're not working with 1/0s, demod based off clock */  
1046      bit 
=  0 ;  /* We assume the 1st bit is zero, it may not be  
1047                * the case: this routine (I think) has an init problem.  
1050      for  (;  i 
< ( int )( GraphTraceLen 
/  clock
);  i
++)  
1056        /* Find out if we hit both high and low peaks */  
1057        for  ( j 
=  0 ;  j 
<  clock
;  j
++)  
1059          if  ( GraphBuffer
[( i 
*  clock
) +  j
] ==  high
)  
1061          else if  ( GraphBuffer
[( i 
*  clock
) +  j
] ==  low
)  
1064          /* it doesn't count if it's the first part of our read  
1065             because it's really just trailing from the last sequence */  
1066          if  ( first 
&& ( hithigh 
||  hitlow
))  
1067            hithigh 
=  hitlow 
=  0 ;  
1071          if  ( hithigh 
&&  hitlow
)  
1075        /* If we didn't hit both high and low peaks, we had a bit transition */  
1076        if  (! hithigh 
|| ! hitlow
)  
1079        BitStream
[ bit2idx
++] =  bit 
^  invert
;  
1083    /* standard 1/0 bitstream */  
1087      /* Then detect duration between 2 successive transitions */  
1088      for  ( bitidx 
=  1 ;  i 
<  GraphTraceLen
;  i
++)  
1090        if  ( GraphBuffer
[ i
- 1 ] !=  GraphBuffer
[ i
])  
1095          // Error check: if bitidx becomes too large, we do not  
1096          // have a Manchester encoded bitstream or the clock is really  
1098          if  ( bitidx 
> ( GraphTraceLen
* 2 / clock
+ 8 ) ) {  
1099            PrintAndLog ( "Error: the clock you gave is probably wrong, aborting." );  
1102          // Then switch depending on lc length:  
1103          // Tolerance is 1/4 of clock rate (arbitrary)  
1104          if  ( abs ( lc
- clock
/ 2 ) <  tolerance
) {  
1105            // Short pulse : either "1" or "0"  
1106            BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];  
1107          }  else if  ( abs ( lc
- clock
) <  tolerance
) {  
1108            // Long pulse: either "11" or "00"  
1109            BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];  
1110            BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];  
1114            PrintAndLog ( "Warning: Manchester decode error for pulse width detection." );  
1115            PrintAndLog ( "(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)" );  
1119              PrintAndLog ( "Error: too many detection errors, aborting." );  
1126      // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream  
1127      // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful  
1128      // to stop output at the final bitidx2 value, not bitidx  
1129      for  ( i 
=  0 ;  i 
<  bitidx
;  i 
+=  2 ) {  
1130        if  (( BitStream
[ i
] ==  0 ) && ( BitStream
[ i
+ 1 ] ==  1 )) {  
1131          BitStream
[ bit2idx
++] =  1  ^  invert
;  
1132        }  else if  (( BitStream
[ i
] ==  1 ) && ( BitStream
[ i
+ 1 ] ==  0 )) {  
1133          BitStream
[ bit2idx
++] =  0  ^  invert
;  
1135          // We cannot end up in this state, this means we are unsynchronized,  
1139          PrintAndLog ( "Unsynchronized, resync..." );  
1140          PrintAndLog ( "(too many of those messages mean the stream is not Manchester encoded)" );  
1144            PrintAndLog ( "Error: too many decode errors, aborting." );  
1151    PrintAndLog ( "Manchester decoded bitstream" );  
1152    // Now output the bitstream to the scrollback by line of 16 bits  
1153    for  ( i 
=  0 ;  i 
< ( bit2idx
- 16 );  i
+= 16 ) {  
1154      PrintAndLog ( " %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i " ,  
1175  /* Modulate our data into manchester */  
1176  int  CmdManchesterMod ( const char  * Cmd
)  
1180    int  bit
,  lastbit
,  wave
;  
1183    clock 
=  GetClock ( Cmd
,  0 ,  1 );  
1187    for  ( i 
=  0 ;  i 
< ( int )( GraphTraceLen 
/  clock
);  i
++)  
1189      bit 
=  GraphBuffer
[ i 
*  clock
] ^  1 ;  
1191      for  ( j 
=  0 ;  j 
< ( int )( clock
/ 2 );  j
++)  
1192        GraphBuffer
[( i 
*  clock
) +  j
] =  bit 
^  lastbit 
^  wave
;  
1193      for  ( j 
= ( int )( clock
/ 2 );  j 
<  clock
;  j
++)  
1194        GraphBuffer
[( i 
*  clock
) +  j
] =  bit 
^  lastbit 
^  wave 
^  1 ;  
1196      /* Keep track of how we start our wave and if we changed or not this time */  
1197      wave 
^=  bit 
^  lastbit
;  
1201    RepaintGraphWindow ();  
1205  int  CmdNorm ( const char  * Cmd
)  
1208    int  max 
=  INT_MIN
,  min 
=  INT_MAX
;  
1210    for  ( i 
=  10 ;  i 
<  GraphTraceLen
; ++ i
) {  
1211      if  ( GraphBuffer
[ i
] >  max
)  
1212        max 
=  GraphBuffer
[ i
];  
1213      if  ( GraphBuffer
[ i
] <  min
)  
1214        min 
=  GraphBuffer
[ i
];  
1218      for  ( i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
) {  
1219        GraphBuffer
[ i
] = ( GraphBuffer
[ i
] - (( max 
+  min
) /  2 )) *  1000  /  
1223    RepaintGraphWindow ();  
1227  int  CmdPlot ( const char  * Cmd
)  
1233  int  CmdSave ( const char  * Cmd
)  
1235    FILE  * f 
=  fopen ( Cmd
,  "w" );  
1237      PrintAndLog ( "couldn't open ' %s '" ,  Cmd
);  
1241    for  ( i 
=  0 ;  i 
<  GraphTraceLen
;  i
++) {  
1242      fprintf ( f
,  " %d \n " ,  GraphBuffer
[ i
]);  
1245    PrintAndLog ( "saved to ' %s '" ,  Cmd
);  
1249  int  CmdScale ( const char  * Cmd
)  
1251    CursorScaleFactor 
=  atoi ( Cmd
);  
1252    if  ( CursorScaleFactor 
==  0 ) {  
1253      PrintAndLog ( "bad, can't have zero scale" );  
1254      CursorScaleFactor 
=  1 ;  
1256    RepaintGraphWindow ();  
1260  int  CmdThreshold ( const char  * Cmd
)  
1262    int  threshold 
=  atoi ( Cmd
);  
1264    for  ( int  i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
) {  
1265      if  ( GraphBuffer
[ i
] >=  threshold
)  
1268        GraphBuffer
[ i
] = - 1 ;  
1270    RepaintGraphWindow ();  
1274  int  CmdDirectionalThreshold ( const char  * Cmd
)  
1276          int8_t  upThres 
=  param_get8 ( Cmd
,  0 );  
1277          int8_t  downThres 
=  param_get8 ( Cmd
,  1 );  
1279    printf ( "Applying Up Threshold:  %d , Down Threshold:  %d \n " ,  upThres
,  downThres
);  
1281    int  lastValue 
=  GraphBuffer
[ 0 ];  
1282    GraphBuffer
[ 0 ] =  0 ;  // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.  
1284    for  ( int  i 
=  1 ;  i 
<  GraphTraceLen
; ++ i
) {  
1285      // Apply first threshold to samples heading up  
1286      if  ( GraphBuffer
[ i
] >=  upThres 
&&  GraphBuffer
[ i
] >  lastValue
)  
1288        lastValue 
=  GraphBuffer
[ i
];  // Buffer last value as we overwrite it.  
1291      // Apply second threshold to samples heading down  
1292      else if  ( GraphBuffer
[ i
] <=  downThres 
&&  GraphBuffer
[ i
] <  lastValue
)  
1294        lastValue 
=  GraphBuffer
[ i
];  // Buffer last value as we overwrite it.  
1295        GraphBuffer
[ i
] = - 1 ;  
1299        lastValue 
=  GraphBuffer
[ i
];  // Buffer last value as we overwrite it.  
1300        GraphBuffer
[ i
] =  GraphBuffer
[ i
- 1 ];  
1304    GraphBuffer
[ 0 ] =  GraphBuffer
[ 1 ];  // Aline with first edited sample.  
1305    RepaintGraphWindow ();  
1309  int  CmdZerocrossings ( const char  * Cmd
)  
1311    // Zero-crossings aren't meaningful unless the signal is zero-mean.  
1318    for  ( int  i 
=  0 ;  i 
<  GraphTraceLen
; ++ i
) {  
1319      if  ( GraphBuffer
[ i
] *  sign 
>=  0 ) {  
1320        // No change in sign, reproduce the previous sample count.  
1322        GraphBuffer
[ i
] =  lastZc
;  
1324        // Change in sign, reset the sample count.  
1326        GraphBuffer
[ i
] =  lastZc
;  
1334    RepaintGraphWindow ();  
1338  static  command_t CommandTable
[] =   
1340    { "help" ,           CmdHelp
,             1 ,  "This help" },  
1341    { "amp" ,            CmdAmp
,              1 ,  "Amplify peaks" },  
1342    { "askdemod" ,       Cmdaskdemod
,         1 ,  "<0 or 1> -- Attempt to demodulate simple ASK tags" },  
1343    { "askmandemod" ,    Cmdaskmandemod
,      1 ,  "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])" },  
1344    { "askrawdemod" ,    Cmdaskrawdemod
,      1 ,  "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])" },  
1345    { "autocorr" ,       CmdAutoCorr
,         1 ,  "<window length> -- Autocorrelation over window" },  
1346    { "biphaserawdecode" , CmdBiphaseDecodeRaw
, 1 , "[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)" },  
1347    { "bitsamples" ,     CmdBitsamples
,       0 ,  "Get raw samples as bitstring" },  
1348    { "bitstream" ,      CmdBitstream
,        1 ,  "[clock rate] -- Convert waveform into a bitstream" },  
1349    { "buffclear" ,      CmdBuffClear
,        1 ,  "Clear sample buffer and graph window" },  
1350    { "dec" ,            CmdDec
,              1 ,  "Decimate samples" },  
1351    { "detectaskclock" , CmdDetectClockRate
,  1 ,  "Detect ASK clock rate" },  
1352    { "fskdemod" ,       CmdFSKdemod
,         1 ,  "Demodulate graph window as a HID FSK" },  
1353    { "fskhiddemod" ,    CmdFSKdemodHID
,      1 ,  "Demodulate graph window as a HID FSK using raw" },  
1354    { "fskiodemod" ,     CmdFSKdemodIO
,       1 ,  "Demodulate graph window as an IO Prox FSK using raw" },  
1355    { "fskrawdemod" ,    CmdFSKrawdemod
,      1 ,  "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)" },  
1356    { "grid" ,           CmdGrid
,             1 ,  "<x> <y> -- overlay grid on graph window, use zero value to turn off either" },  
1357    { "hexsamples" ,     CmdHexsamples
,       0 ,  "<bytes> [<offset>] -- Dump big buffer as hex bytes" },    
1358    { "hide" ,           CmdHide
,             1 ,  "Hide graph window" },  
1359    { "hpf" ,            CmdHpf
,              1 ,  "Remove DC offset from trace" },  
1360    { "load" ,           CmdLoad
,             1 ,  "<filename> -- Load trace (to graph window" },  
1361    { "ltrim" ,          CmdLtrim
,            1 ,  "<samples> -- Trim samples from left of trace" },  
1362    { "rtrim" ,          CmdRtrim
,            1 ,  "<location to end trace> -- Trim samples from right of trace" },  
1363    { "mandemod" ,       CmdManchesterDemod
,  1 ,  "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)" },  
1364    { "manrawdecode" ,   Cmdmandecoderaw
,     1 ,  "Manchester decode binary stream already in graph buffer" },  
1365    { "manmod" ,         CmdManchesterMod
,    1 ,  "[clock rate] -- Manchester modulate a binary stream" },  
1366    { "norm" ,           CmdNorm
,             1 ,  "Normalize max/min to +/-500" },  
1367    { "plot" ,           CmdPlot
,             1 ,  "Show graph window (hit 'h' in window for keystroke help)" },  
1368    { "samples" ,        CmdSamples
,          0 ,  "[512 - 40000] -- Get raw samples for graph window" },  
1369    { "tune" ,           CmdTuneSamples
,      0 ,  "Get hw tune samples for graph window" },  
1370    { "save" ,           CmdSave
,             1 ,  "<filename> -- Save trace (from graph window)" },  
1371    { "scale" ,          CmdScale
,            1 ,  "<int> -- Set cursor display scale" },  
1372    { "threshold" ,      CmdThreshold
,        1 ,  "<threshold> -- Maximize/minimize every value in the graph window depending on threshold" },  
1373    { "zerocrossings" ,  CmdZerocrossings
,    1 ,  "Count time between zero-crossings" },  
1374    { "dirthreshold" ,   CmdDirectionalThreshold
,    1 ,  "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev." },  
1375    { NULL
,  NULL
,  0 ,  NULL
}  
1378  int  CmdData ( const char  * Cmd
)  
1380    CmdsParse ( CommandTable
,  Cmd
);  
1384  int  CmdHelp ( const char  * Cmd
)  
1386    CmdsHelp ( CommandTable
);