1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2009 Michael Gernoth <michael at gernoth.net> 
   3 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   5 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   6 // at your option, any later version. See the LICENSE.txt file for the text of 
   8 //----------------------------------------------------------------------------- 
  10 //----------------------------------------------------------------------------- 
  17 #include <readline/readline.h> 
  19 #include "loclass/cipherutils.h" 
  24 //#include <liquid/liquid.h> 
  25 #define M_PI 3.14159265358979323846264338327 
  27 double CursorScaleFactor
; 
  28 int PlotGridX
, PlotGridY
, PlotGridXdefault
= 64, PlotGridYdefault
= 64; 
  30 int flushAfterWrite 
= 0; 
  31 extern pthread_mutex_t print_lock
; 
  33 static char *logfilename 
= "proxmark3.log"; 
  35 void PrintAndLog(char *fmt
, ...) 
  39         va_list argptr
, argptr2
; 
  40         static FILE *logfile 
= NULL
; 
  41         static int logging 
= 1; 
  43         // lock this section to avoid interlacing prints from different threats 
  44         pthread_mutex_lock(&print_lock
); 
  46         if (logging 
&& !logfile
) { 
  47                 logfile 
= fopen(logfilename
, "a"); 
  49                         fprintf(stderr
, "Can't open logfile, logging disabled!\n"); 
  54         int need_hack 
= (rl_readline_state 
& RL_STATE_READCMD
) > 0; 
  57                 saved_point 
= rl_point
; 
  58                 saved_line 
= rl_copy_text(0, rl_end
); 
  60                 rl_replace_line("", 0); 
  64         va_start(argptr
, fmt
); 
  65         va_copy(argptr2
, argptr
); 
  67         printf("          "); // cleaning prompt 
  73                 rl_replace_line(saved_line
, 0); 
  74                 rl_point 
= saved_point
; 
  79         if (logging 
&& logfile
) { 
  80                 vfprintf(logfile
, fmt
, argptr2
); 
  81                 fprintf(logfile
,"\n"); 
  86         if (flushAfterWrite 
== 1) { 
  90         pthread_mutex_unlock(&print_lock
);   
  93 void SetLogFilename(char *fn
) 
  98 int manchester_decode( int * data
, const size_t len
, uint8_t * dataout
,  size_t dataoutlen
){ 
 101         int clock
, high
, low
, startindex
; 
 102         low 
= startindex 
= 0; 
 104         uint8_t * bitStream 
=  (uint8_t* ) malloc(sizeof(uint8_t) * dataoutlen
);         
 105         memset(bitStream
, 0x00, dataoutlen
);     
 107         /* Detect high and lows */ 
 108         DetectHighLowInGraph(&high
, &low
, TRUE
);  
 111         clock 
= GetClock("",0, 0);       
 113         startindex 
= DetectFirstTransition(data
, len
, high
); 
 117                 bitlength 
= ManchesterConvertFrom255(data
, len
, bitStream
, dataoutlen
, high
, low
, clock
, startindex
); 
 120                 bitlength 
= ManchesterConvertFrom1(data
, len
, bitStream
, dataoutlen
, clock
, startindex
); 
 122         memcpy(dataout
, bitStream
, bitlength
); 
 127  int DetectFirstTransition(const int * data
, const size_t len
, int threshold
){ 
 130         /* now look for the first threshold */ 
 131         for (; i 
< len
; ++i
) { 
 132                 if (data
[i
] == threshold
) { 
 139  int ManchesterConvertFrom255(const int * data
, const size_t len
, uint8_t * dataout
, int dataoutlen
, int high
, int low
, int clock
, int startIndex
){ 
 141         int i
, j
, z
, hithigh
, hitlow
, bitIndex
, startType
; 
 146         int damplimit 
= (int)((high 
/ 2) * 0.3); 
 147         int dampHi 
=  (high
/2)+damplimit
; 
 148         int dampLow 
= (high
/2)-damplimit
; 
 151         // i = clock frame of data 
 152         for (; i 
< (int)(len
/clock
); i
++) 
 157                 z 
= startIndex 
+ (i
*clock
); 
 160                 /* Find out if we hit both high and low peaks */ 
 161                 for (j 
= 0; j 
< clock
; j
++) 
 163                         if (data
[z
+j
] == high
){ 
 165                                 if ( startType 
== -1) 
 169                         if (data
[z
+j
] == low 
){ 
 171                                 if ( startType 
== -1) 
 175                         if (hithigh 
&& hitlow
) 
 179                 // No high value found, are we in a dampening field? 
 181                         //PrintAndLog(" # Entering damp test at index : %d (%d)", z+j, j); 
 182                         for (j 
= 0; j 
< clock
; j
++) { 
 184                                      (data
[z
+j
] <= dampHi 
&& data
[z
+j
] >= dampLow
) 
 191                 /*  Manchester Switching.. 
 196                         dataout
[bitIndex
++] = 1; 
 197                 else if (startType 
== 1)  
 198                         dataout
[bitIndex
++] = 0; 
 200                         dataout
[bitIndex
++] = 2; 
 202                 if ( isDamp 
> clock
/2 ) { 
 208                 if ( bitIndex 
>= dataoutlen
-1 ) 
 214  int ManchesterConvertFrom1(const int * data
, const size_t len
, uint8_t * dataout
,int dataoutlen
, int clock
, int startIndex
){ 
 216         PrintAndLog(" Path B"); 
 218         int i
,j
, bitindex
, lc
, tolerance
, warnings
; 
 220         int upperlimit 
= len
*2/clock
+8; 
 224         uint8_t decodedArr
[len
]; 
 226         /* Detect duration between 2 successive transitions */ 
 227         for (bitindex 
= 1; i 
< len
; i
++) { 
 229                 if (data
[i
-1] != data
[i
]) { 
 233                         // Error check: if bitindex becomes too large, we do not 
 234                         // have a Manchester encoded bitstream or the clock is really wrong! 
 235                         if (bitindex 
> upperlimit 
) { 
 236                                 PrintAndLog("Error: the clock you gave is probably wrong, aborting."); 
 239                         // Then switch depending on lc length: 
 240                         // Tolerance is 1/4 of clock rate (arbitrary) 
 241                         if (abs((lc
-clock
)/2) < tolerance
) { 
 242                                 // Short pulse : either "1" or "0" 
 243                                 decodedArr
[bitindex
++] = data
[i
-1]; 
 244                         } else if (abs(lc
-clock
) < tolerance
) { 
 245                                 // Long pulse: either "11" or "00" 
 246                                 decodedArr
[bitindex
++] = data
[i
-1]; 
 247                                 decodedArr
[bitindex
++] = data
[i
-1]; 
 250                                 PrintAndLog("Warning: Manchester decode error for pulse width detection."); 
 252                                         PrintAndLog("Error: too many detection errors, aborting."); 
 260         * We have a decodedArr of "01" ("1") or "10" ("0") 
 261         * parse it into final decoded dataout 
 263     for (i 
= 0; i 
< bitindex
; i 
+= 2) { 
 265             if ((decodedArr
[i
] == 0) && (decodedArr
[i
+1] == 1)) { 
 267                 } else if ((decodedArr
[i
] == 1) && (decodedArr
[i
+1] == 0)) { 
 272                         PrintAndLog("Unsynchronized, resync..."); 
 273                         PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); 
 276                                 PrintAndLog("Error: too many decode errors, aborting."); 
 282         PrintAndLog("%s", sprint_hex(dataout
, j
)); 
 286  void ManchesterDiffDecodedString(const uint8_t* bitstream
, size_t len
, uint8_t invert
){ 
 288         * We have a bitstream of "01" ("1") or "10" ("0") 
 289         * parse it into final decoded bitstream 
 292         uint8_t decodedArr
[(len
/2)+1]; 
 298     for (i 
= 0; i 
< len
; i 
+= 2) { 
 300                 uint8_t first 
= bitstream
[i
]; 
 301                 uint8_t second 
= bitstream
[i
+1]; 
 303                 if ( first 
== second 
) { 
 307                                 PrintAndLog("Error: too many decode errors, aborting."); 
 311                 else if ( lastbit 
!= first 
) { 
 312                         decodedArr
[j
++] = 0 ^ invert
; 
 315                         decodedArr
[j
++] = 1 ^ invert
; 
 320         PrintAndLog("%s", sprint_hex(decodedArr
, j
)); 
 323 void PrintPaddedManchester( uint8_t* bitStream
, size_t len
, size_t blocksize
){ 
 325         PrintAndLog(" Manchester decoded  : %d bits", len
); 
 327         uint8_t mod 
= len 
% blocksize
; 
 328         uint8_t div 
= len 
/ blocksize
; 
 331         // Now output the bitstream to the scrollback by line of 16 bits 
 332         for (i 
= 0; i 
< div
*blocksize
; i
+=blocksize
) { 
 333                 PrintAndLog(" %s", sprint_bin(bitStream
+i
,blocksize
) ); 
 337                 PrintAndLog(" %s", sprint_bin(bitStream
+i
, mod
) );       
 343 void iceFsk2(int * data
, const size_t len
){ 
 346         int * output 
=  (int* ) malloc(sizeof(int) * len
);       
 347         memset(output
, 0x00, len
); 
 349         // for (i=0; i<len-5; ++i){ 
 350                 // for ( j=1; j <=5; ++j) { 
 351                         // output[i] += data[i*j]; 
 357         for (i
=0; i
<len
; ++i
){ 
 361                         tmp 
=  (100 * (data
[i
]-rest
)) / rest
; 
 362                         output
[i
] = (tmp 
> 60)? 100:0; 
 366         for (j
=0; j
<len
; ++j
) 
 372 void iceFsk3(int * data
, const size_t len
){ 
 376         int * output 
=  (int* ) malloc(sizeof(int) * len
);       
 377         memset(output
, 0x00, len
); 
 378         float fc           
= 0.1125f
;          // center frequency 
 379         size_t adjustedLen 
= len
; 
 381     // create very simple low-pass filter to remove images (2nd-order Butterworth) 
 382     float complex iir_buf
[3] = {0,0,0}; 
 383     float b
[3] = {0.003621681514929,  0.007243363029857, 0.003621681514929}; 
 384     float a
[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023}; 
 386     float sample           
= 0;      // input sample read from file 
 387     float complex x_prime  
= 1.0f
;   // save sample for estimating frequency 
 390         for (i
=0; i
<adjustedLen
; ++i
) { 
 392                 sample 
= data
[i
]+128; 
 394         // remove DC offset and mix to complex baseband 
 395         x 
= (sample 
- 127.5f
) * cexpf( _Complex_I 
* 2 * M_PI 
* fc 
* i 
); 
 397         // apply low-pass filter, removing spectral image (IIR using direct-form II) 
 398         iir_buf
[2] = iir_buf
[1]; 
 399         iir_buf
[1] = iir_buf
[0]; 
 400         iir_buf
[0] = x 
- a
[1]*iir_buf
[1] - a
[2]*iir_buf
[2]; 
 401         x          
= b
[0]*iir_buf
[0] + 
 405         // compute instantaneous frequency by looking at phase difference 
 406         // between adjacent samples 
 407         float freq 
= cargf(x
*conjf(x_prime
)); 
 408         x_prime 
= x
;    // retain this sample for next iteration 
 410                 output
[i
] =(freq 
> 0)? 10 : -10; 
 414         for (j
=0; j
<adjustedLen
; ++j
) 
 421         for (j
=0; j
<adjustedLen
; ++j
){ 
 422                 if ( data
[j
] == 10) break; 
 426         for (;j
<adjustedLen
; ++j
){ 
 427                 if ( data
[j
] == -10 ) break; 
 431         int fieldlen 
= stopOne
-startOne
; 
 433         fieldlen 
= (fieldlen 
== 39 || fieldlen 
== 41)? 40 : fieldlen
; 
 434         fieldlen 
= (fieldlen 
== 59 || fieldlen 
== 51)? 50 : fieldlen
; 
 435         if ( fieldlen 
!= 40 && fieldlen 
!= 50){ 
 436                 printf("Detected field Length: %d \n", fieldlen
); 
 437                 printf("Can only handle 40 or 50.  Aborting...\n"); 
 441         // FSK sequence start == 000111 
 443         for (i 
=0; i
<adjustedLen
; ++i
){ 
 445                 for ( j 
= 0; j 
< 6*fieldlen
; ++j
){ 
 454         printf("000111 position: %d \n", startPos
); 
 456         startPos 
+= 6*fieldlen
+5; 
 461         for (i 
=startPos 
; i 
< adjustedLen
; i 
+= 40){ 
 462                 bit 
= data
[i
]>0 ? 1:0; 
 468         for (i 
=startPos 
; i 
< adjustedLen
; i 
+= 50){ 
 469                 bit 
= data
[i
]>0 ? 1:0; 
 470                 printf("%d", bit 
);     } 
 476 float complex cexpf (float complex Z
) 
 479   double rho 
= exp (__real__ Z
); 
 480   __real__ Res 
= rho 
* cosf(__imag__ Z
); 
 481   __imag__ Res 
= rho 
* sinf(__imag__ Z
);