]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmddata.c
674a1bb5e05e4be5a490b56bed91b0b7383d4717
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 //-----------------------------------------------------------------------------
14 //#include <inttypes.h>
16 #include "proxmark3.h"
20 #include "cmdparser.h"
26 static int CmdHelp ( const char * Cmd
);
28 int CmdAmp ( const char * Cmd
)
30 int i
, rising
, falling
;
31 int max
= INT_MIN
, min
= INT_MAX
;
33 for ( i
= 10 ; i
< GraphTraceLen
; ++ i
) {
34 if ( GraphBuffer
[ i
] > max
)
36 if ( GraphBuffer
[ i
] < min
)
42 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
) {
43 if ( GraphBuffer
[ i
+ 1 ] < GraphBuffer
[ i
]) {
50 if ( GraphBuffer
[ i
+ 1 ] > GraphBuffer
[ i
]) {
64 * Generic command to demodulate ASK.
66 * Argument is convention: positive or negative (High mod means zero
67 * or high mod means one)
69 * Updates the Graph trace with 0/1 values
74 //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock
75 int Cmdaskdemod ( const char * Cmd
)
78 int c
, high
= 0 , low
= 0 ;
80 // TODO: complain if we do not give 2 arguments here !
81 // (AL - this doesn't make sense! we're only using one argument!!!)
82 sscanf ( Cmd
, "%i" , & c
);
84 /* Detect high and lows and clock */
86 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
)
88 if ( GraphBuffer
[ i
] > high
)
89 high
= GraphBuffer
[ i
];
90 else if ( GraphBuffer
[ i
] < low
)
95 if ( c
!= 0 && c
!= 1 ) {
96 PrintAndLog ( "Invalid argument: %s" , Cmd
);
100 if ( GraphBuffer
[ 0 ] > 0 ) {
101 GraphBuffer
[ 0 ] = 1 - c
;
105 for ( i
= 1 ; i
< GraphTraceLen
; ++ i
) {
106 /* Transitions are detected at each peak
107 * Transitions are either:
108 * - we're low: transition if we hit a high
109 * - we're high: transition if we hit a low
110 * (we need to do it this way because some tags keep high or
111 * low for long periods, others just reach the peak and go
114 //[marhsmellow] change == to >= for high and <= for low for fuzz
115 if (( GraphBuffer
[ i
] == high
) && ( GraphBuffer
[ i
- 1 ] == c
)) {
116 GraphBuffer
[ i
] = 1 - c
;
117 } else if (( GraphBuffer
[ i
] == low
) && ( GraphBuffer
[ i
- 1 ] == ( 1 - c
))){
121 GraphBuffer
[ i
] = GraphBuffer
[ i
- 1 ];
124 RepaintGraphWindow ();
128 void printBitStream ( uint8_t BitStream
[], uint32_t bitLen
){
131 PrintAndLog ( "Too few bits found: %d" , bitLen
);
134 if ( bitLen
> 512 ) bitLen
= 512 ;
135 for ( i
= 0 ; i
< ( bitLen
- 16 ); i
+= 16 ) {
136 PrintAndLog ( "%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i" ,
156 void printEM410x ( uint64_t id
)
160 uint64_t id2lo
= 0 ; //id2hi=0,
163 for ( ii
= 5 ; ii
> 0 ; ii
--){
165 id2lo
=( id2lo
<< 1LL )|(( id
& ( iii
<<( i
+(( ii
- 1 )* 8 ))))>>( i
+(( ii
- 1 )* 8 )));
169 PrintAndLog ( "EM TAG ID : %010llx" , id
);
170 PrintAndLog ( "Unique TAG ID: %010llx" , id2lo
); //id2hi,
171 PrintAndLog ( "DEZ 8 : %08lld" , id
& 0xFFFFFF );
172 PrintAndLog ( "DEZ 10 : %010lld" , id
& 0xFFFFFF );
173 PrintAndLog ( "DEZ 5.5 : %05lld.%05lld" ,( id
>> 16LL ) & 0xFFFF ,( id
& 0xFFFF ));
174 PrintAndLog ( "DEZ 3.5A : %03lld.%05lld" ,( id
>> 32ll ),( id
& 0xFFFF ));
175 PrintAndLog ( "DEZ 14/IK2 : %014lld" , id
);
176 PrintAndLog ( "DEZ 15/IK3 : %015lld" , id2lo
);
177 PrintAndLog ( "Other : %05lld_%03lld_%08lld" ,( id
& 0xFFFF ),(( id
>> 16LL ) & 0xFF ),( id
& 0xFFFFFF ));
182 int CmdEm410xDecode ( const char * Cmd
)
185 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
187 for ( i
= 0 ; i
< GraphTraceLen
;++ i
){
188 BitStream
[ i
]=( uint8_t )( GraphBuffer
[ i
]+ 128 );
190 id
= Em410xDecode ( BitStream
, i
);
195 int getFromGraphBuf ( uint8_t * buff
)
198 for ( i
= 0 ; i
< GraphTraceLen
;++ i
)
199 buff
[ i
]=( uint8_t )( GraphBuffer
[ i
]+ 128 );
204 //takes 2 arguments - clock and invert both as integers
205 //attempts to demodulate ask while decoding manchester
206 //prints binary found and saves in graphbuffer for further commands
207 int Cmdaskmandemod ( const char * Cmd
)
211 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
212 sscanf ( Cmd
, "%i %i" , & clk
, & invert
);
213 if ( invert
!= 0 && invert
!= 1 ) {
214 PrintAndLog ( "Invalid argument: %s" , Cmd
);
217 uint32_t BitLen
= getFromGraphBuf ( BitStream
);
220 errCnt
= askmandemod ( BitStream
, & BitLen
,& clk
,& invert
);
221 if ( errCnt
==- 1 ){ //if fatal error (or -1)
222 PrintAndLog ( "no data found" );
225 PrintAndLog ( "Using Clock: %d and invert=%d" , clk
, invert
);
226 //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
227 //move BitStream back to GraphBuffer
230 for (i=0; i < bitnum; ++i){
231 GraphBuffer[i]=BitStream[i];
233 GraphTraceLen=bitnum;
234 RepaintGraphWindow();
238 PrintAndLog ( "# Errors during Demoding (shown as 77 in bit stream): %d" , errCnt
);
240 PrintAndLog ( "ASK/Manchester decoded bitstream:" );
241 // Now output the bitstream to the scrollback by line of 16 bits
242 printBitStream ( BitStream
, BitLen
);
244 lo
= Em410xDecode ( BitStream
, BitLen
);
251 //biphase demod = 10 (or 01)=1 / 00 (or 11)=0
256 //stricktly take 10 and 01 and convert to 0 and 1
257 int Cmdmandecoderaw ( const char * Cmd
)
262 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
264 for (; i
< GraphTraceLen
;++ i
){
265 if ( GraphBuffer
[ i
]> high
) high
= GraphBuffer
[ i
];
266 else if ( GraphBuffer
[ i
]< low
) low
= GraphBuffer
[ i
];
267 BitStream
[ i
]= GraphBuffer
[ i
];
269 if ( high
> 1 || low
< 0 ){
270 PrintAndLog ( "Error: please raw demod the wave first then mancheseter raw decode" );
274 errCnt
= manrawdemod ( BitStream
,& bitnum
);
275 PrintAndLog ( "Manchester Decoded - # errors:%d - data:" , errCnt
);
276 printBitStream ( BitStream
, bitnum
);
278 //put back in graphbuffer
280 for ( i
= 0 ; i
< bitnum
;++ i
){
281 GraphBuffer
[ i
]= BitStream
[ i
];
283 GraphTraceLen
= bitnum
;
284 RepaintGraphWindow ();
286 id
= Em410xDecode ( BitStream
, i
);
293 //takes 2 arguments - clock and invert both as integers
294 //attempts to demodulate ask only
295 //prints binary found and saves in graphbuffer for further commands
296 int Cmdaskrawdemod ( const char * Cmd
)
301 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
302 sscanf ( Cmd
, "%i %i" , & clk
, & invert
);
303 if ( invert
!= 0 && invert
!= 1 ) {
304 PrintAndLog ( "Invalid argument: %s" , Cmd
);
307 int BitLen
= getFromGraphBuf ( BitStream
);
309 errCnt
= askrawdemod ( BitStream
, & BitLen
,& clk
,& invert
);
310 if ( errCnt
==- 1 ){ //throw away static - allow 1 and -1 (in case of threshold command first)
311 PrintAndLog ( "no data found" );
314 PrintAndLog ( "Using Clock: %d and invert=%d" , clk
, invert
);
315 //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
316 //move BitStream back to GraphBuffer
319 for ( i
= 0 ; i
< BitLen
; ++ i
){
320 GraphBuffer
[ i
]= BitStream
[ i
];
322 GraphTraceLen
= BitLen
;
323 RepaintGraphWindow ();
327 PrintAndLog ( "# Errors during Demoding (shown as 77 in bit stream): %d" , errCnt
);
329 PrintAndLog ( "ASK demoded bitstream:" );
330 // Now output the bitstream to the scrollback by line of 16 bits
331 printBitStream ( BitStream
, BitLen
);
336 int CmdAutoCorr ( const char * Cmd
)
338 static int CorrelBuffer
[ MAX_GRAPH_TRACE_LEN
];
340 int window
= atoi ( Cmd
);
343 PrintAndLog ( "needs a window" );
346 if ( window
>= GraphTraceLen
) {
347 PrintAndLog ( "window must be smaller than trace (%d samples)" ,
352 PrintAndLog ( "performing %d correlations" , GraphTraceLen
- window
);
354 for ( int i
= 0 ; i
< GraphTraceLen
- window
; ++ i
) {
356 for ( int j
= 0 ; j
< window
; ++ j
) {
357 sum
+= ( GraphBuffer
[ j
]* GraphBuffer
[ i
+ j
]) / 256 ;
359 CorrelBuffer
[ i
] = sum
;
361 GraphTraceLen
= GraphTraceLen
- window
;
362 memcpy ( GraphBuffer
, CorrelBuffer
, GraphTraceLen
* sizeof ( int ));
364 RepaintGraphWindow ();
368 int CmdBitsamples ( const char * Cmd
)
373 GetFromBigBuf ( got
, sizeof ( got
), 0 );
374 WaitForResponse ( CMD_ACK
, NULL
);
376 for ( int j
= 0 ; j
< sizeof ( got
); j
++) {
377 for ( int k
= 0 ; k
< 8 ; k
++) {
378 if ( got
[ j
] & ( 1 << ( 7 - k
))) {
379 GraphBuffer
[ cnt
++] = 1 ;
381 GraphBuffer
[ cnt
++] = 0 ;
386 RepaintGraphWindow ();
391 * Convert to a bitstream
393 int CmdBitstream ( const char * Cmd
)
401 int hithigh
, hitlow
, first
;
403 /* Detect high and lows and clock */
404 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
)
406 if ( GraphBuffer
[ i
] > high
)
407 high
= GraphBuffer
[ i
];
408 else if ( GraphBuffer
[ i
] < low
)
409 low
= GraphBuffer
[ i
];
413 clock
= GetClock ( Cmd
, high
, 1 );
417 for ( i
= 0 ; i
< ( int )( gtl
/ clock
); ++ i
)
422 /* Find out if we hit both high and low peaks */
423 for ( j
= 0 ; j
< clock
; ++ j
)
425 if ( GraphBuffer
[( i
* clock
) + j
] == high
)
427 else if ( GraphBuffer
[( i
* clock
) + j
] == low
)
429 /* it doesn't count if it's the first part of our read
430 because it's really just trailing from the last sequence */
431 if ( first
&& ( hithigh
|| hitlow
))
432 hithigh
= hitlow
= 0 ;
436 if ( hithigh
&& hitlow
)
440 /* If we didn't hit both high and low peaks, we had a bit transition */
441 if (! hithigh
|| ! hitlow
)
444 AppendGraph ( 0 , clock
, bit
);
445 // for (j = 0; j < (int)(clock/2); j++)
446 // GraphBuffer[(i * clock) + j] = bit ^ 1;
447 // for (j = (int)(clock/2); j < clock; j++)
448 // GraphBuffer[(i * clock) + j] = bit;
451 RepaintGraphWindow ();
455 int CmdBuffClear ( const char * Cmd
)
457 UsbCommand c
= { CMD_BUFF_CLEAR
};
463 int CmdDec ( const char * Cmd
)
465 for ( int i
= 0 ; i
< ( GraphTraceLen
/ 2 ); ++ i
)
466 GraphBuffer
[ i
] = GraphBuffer
[ i
* 2 ];
468 PrintAndLog ( "decimated by 2" );
469 RepaintGraphWindow ();
473 /* Print our clock rate */
474 int CmdDetectClockRate ( const char * Cmd
)
476 int clock
= DetectClock ( 0 );
477 PrintAndLog ( "Auto-detected clock rate: %d" , clock
);
481 uint32_t bytebits_to_byte(uint8_t *src, int numbits)
484 for(int i = 0 ; i < numbits ; i++)
486 num = (num << 1) | (*src);
493 //fsk raw demod and print binary
494 //takes 2 arguments - Clock and invert
495 //defaults: clock = 50, invert=0
496 int CmdFSKrawdemod ( const char * Cmd
)
498 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
502 //set options from parameters entered with the command
503 if ( strlen ( Cmd
)> 0 && strlen ( Cmd
)<= 2 ) {
504 rfLen
= param_get8 ( Cmd
, 0 ); //if rfLen option only is used
506 invert
= 1 ; //if invert option only is used
508 } else if ( rfLen
== 0 ) rfLen
= 50 ;
511 rfLen
= param_get8 ( Cmd
, 0 ); //if both options are used
512 invert
= param_get8 ( Cmd
, 1 );
514 PrintAndLog ( "Args invert: %d \n Clock:%d" , invert
, rfLen
);
516 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
517 uint32_t BitLen
= getFromGraphBuf ( BitStream
);
518 int size
= fskdemod ( BitStream
, BitLen
, rfLen
, invert
);
520 PrintAndLog ( "FSK decoded bitstream:" );
522 for ( i
= 0 ; i
< size
;++ i
){
523 GraphBuffer
[ i
]= BitStream
[ i
];
526 RepaintGraphWindow ();
528 // Now output the bitstream to the scrollback by line of 16 bits
529 if ( size
> ( 7 * 32 )+ 2 ) size
= ( 7 * 32 )+ 2 ; //only output a max of 7 blocks of 32 bits most tags will have full bit stream inside that sample size
530 printBitStream ( BitStream
, size
);
534 //by marshmellow (based on existing demod + holiman's refactor)
535 //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
536 //print full HID Prox ID and some bit format details if found
537 int CmdFSKdemodHID ( const char * Cmd
)
539 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
540 uint32_t hi2
= 0 , hi
= 0 , lo
= 0 ;
542 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
543 uint32_t BitLen
= getFromGraphBuf ( BitStream
);
544 //get binary from fsk wave
545 size_t size
= HIDdemodFSK ( BitStream
, BitLen
,& hi2
,& hi
,& lo
);
547 PrintAndLog ( "Error demoding fsk" );
550 if ( hi2
!= 0 ){ //extra large HID tags
551 PrintAndLog ( "TAG ID: %x%08x%08x (%d)" ,
552 ( unsigned int ) hi2
, ( unsigned int ) hi
, ( unsigned int ) lo
, ( unsigned int ) ( lo
>> 1 ) & 0xFFFF );
554 else { //standard HID tags <38 bits
555 //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
558 uint32_t cardnum
= 0 ;
559 if ((( hi
>> 5 )& 1 )== 1 ){ //if bit 38 is set then < 37 bit format is used
561 lo2
=((( hi
& 15 ) << 12 ) | ( lo
>> 20 )); //get bits 21-37 to check for format len bit
563 while ( lo2
> 1 ){ //find last bit set to 1 (format len bit)
571 cardnum
= ( lo
>> 1 )& 0xFFFF ;
575 cardnum
= ( lo
>> 1 )& 0x7FFFF ;
576 fc
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );
579 cardnum
= ( lo
>> 1 )& 0xFFFF ;
580 fc
= (( hi
& 1 )<< 15 )|( lo
>> 17 );
583 cardnum
= ( lo
>> 1 )& 0xFFFFF ;
584 fc
= (( hi
& 1 )<< 11 )|( lo
>> 21 );
587 else { //if bit 38 is not set then 37 bit format is used
592 cardnum
= ( lo
>> 1 )& 0x7FFFF ;
593 fc
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );
596 PrintAndLog ( "TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d" ,
597 ( unsigned int ) hi
, ( unsigned int ) lo
, ( unsigned int ) ( lo
>> 1 ) & 0xFFFF ,
598 ( unsigned int ) bitlen
, ( unsigned int ) fc
, ( unsigned int ) cardnum
);
605 //IO-Prox demod - FSK RF/64 with preamble of 000000001
606 //print ioprox ID and some format details
607 int CmdFSKdemodIO ( const char * Cmd
)
609 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
612 //test samples are not just noise
613 if ( GraphTraceLen
< 64 ) return 0 ;
614 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
]={ 0 };
615 uint32_t BitLen
= getFromGraphBuf ( BitStream
);
616 //get binary from fsk wave
617 idx
= IOdemodFSK ( BitStream
, BitLen
);
619 PrintAndLog ( "Error demoding fsk" );
623 PrintAndLog ( "IO Prox Data not found - FSK Data:" );
624 printBitStream ( BitStream
, 92 );
627 //0 10 20 30 40 50 60
629 //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
630 //-----------------------------------------------------------------------------
631 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
633 //XSF(version)facility:codeone+codetwo (raw)
636 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 ]);
637 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 ]);
638 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , 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 ]);
639 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , 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 ]);
640 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , 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 ]);
641 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , 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 ]);
642 PrintAndLog ( "%d%d%d%d%d%d%d%d %d%d" , 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 ]);
644 uint32_t code
= bytebits_to_byte ( BitStream
+ idx
, 32 );
645 uint32_t code2
= bytebits_to_byte ( BitStream
+ idx
+ 32 , 32 );
646 short version
= bytebits_to_byte ( BitStream
+ idx
+ 27 , 8 ); //14,4
647 uint8_t facilitycode
= bytebits_to_byte ( BitStream
+ idx
+ 19 , 8 ) ;
648 uint16_t number
= ( bytebits_to_byte ( BitStream
+ idx
+ 36 , 8 )<< 8 )|( bytebits_to_byte ( BitStream
+ idx
+ 45 , 8 )); //36,9
650 PrintAndLog ( "XSF(%02d)%02x:%d (%08x%08x)" , version
, facilitycode
, number
, code
, code2
);
653 int CmdFSKdemod ( const char * Cmd
) //old CmdFSKdemod needs updating
655 static const int LowTone
[] = {
656 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
657 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
658 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
659 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
660 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1
662 static const int HighTone
[] = {
663 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
664 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
665 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
666 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
667 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
668 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
671 int lowLen
= sizeof ( LowTone
) / sizeof ( int );
672 int highLen
= sizeof ( HighTone
) / sizeof ( int );
673 int convLen
= ( highLen
> lowLen
) ? highLen
: lowLen
; //if highlen > lowLen then highlen else lowlen
674 uint32_t hi
= 0 , lo
= 0 ;
677 int minMark
= 0 , maxMark
= 0 ;
679 for ( i
= 0 ; i
< GraphTraceLen
- convLen
; ++ i
) {
680 int lowSum
= 0 , highSum
= 0 ;
682 for ( j
= 0 ; j
< lowLen
; ++ j
) {
683 lowSum
+= LowTone
[ j
]* GraphBuffer
[ i
+ j
];
685 for ( j
= 0 ; j
< highLen
; ++ j
) {
686 highSum
+= HighTone
[ j
] * GraphBuffer
[ i
+ j
];
688 lowSum
= abs ( 100 * lowSum
/ lowLen
);
689 highSum
= abs ( 100 * highSum
/ highLen
);
690 GraphBuffer
[ i
] = ( highSum
<< 16 ) | lowSum
;
693 for ( i
= 0 ; i
< GraphTraceLen
- convLen
- 16 ; ++ i
) {
694 int lowTot
= 0 , highTot
= 0 ;
695 // 10 and 8 are f_s divided by f_l and f_h, rounded
696 for ( j
= 0 ; j
< 10 ; ++ j
) {
697 lowTot
+= ( GraphBuffer
[ i
+ j
] & 0xffff );
699 for ( j
= 0 ; j
< 8 ; j
++) {
700 highTot
+= ( GraphBuffer
[ i
+ j
] >> 16 );
702 GraphBuffer
[ i
] = lowTot
- highTot
;
703 if ( GraphBuffer
[ i
] > maxMark
) maxMark
= GraphBuffer
[ i
];
704 if ( GraphBuffer
[ i
] < minMark
) minMark
= GraphBuffer
[ i
];
707 GraphTraceLen
-= ( convLen
+ 16 );
708 RepaintGraphWindow ();
710 // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
711 int max
= 0 , maxPos
= 0 ;
712 for ( i
= 0 ; i
< 6000 ; ++ i
) {
714 for ( j
= 0 ; j
< 3 * lowLen
; ++ j
) {
715 dec
-= GraphBuffer
[ i
+ j
];
717 for (; j
< 3 * ( lowLen
+ highLen
); ++ j
) {
718 dec
+= GraphBuffer
[ i
+ j
];
726 // place start of bit sync marker in graph
727 GraphBuffer
[ maxPos
] = maxMark
;
728 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
732 // place end of bit sync marker in graph
733 GraphBuffer
[ maxPos
] = maxMark
;
734 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
736 PrintAndLog ( "actual data bits start at sample %d" , maxPos
);
737 PrintAndLog ( "length %d/%d" , highLen
, lowLen
);
740 bits
[ sizeof ( bits
)- 1 ] = '\0' ;
742 // find bit pairs and manchester decode them
743 for ( i
= 0 ; i
< arraylen ( bits
) - 1 ; ++ i
) {
745 for ( j
= 0 ; j
< lowLen
; ++ j
) {
746 dec
-= GraphBuffer
[ maxPos
+ j
];
748 for (; j
< lowLen
+ highLen
; ++ j
) {
749 dec
+= GraphBuffer
[ maxPos
+ j
];
752 // place inter bit marker in graph
753 GraphBuffer
[ maxPos
] = maxMark
;
754 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
756 // hi and lo form a 64 bit pair
757 hi
= ( hi
<< 1 ) | ( lo
>> 31 );
759 // store decoded bit as binary (in hi/lo) and text (in bits[])
767 PrintAndLog ( "bits: '%s'" , bits
);
768 PrintAndLog ( "hex: %08x %08x" , hi
, lo
);
772 int CmdGrid ( const char * Cmd
)
774 sscanf ( Cmd
, "%i %i" , & PlotGridX
, & PlotGridY
);
775 PlotGridXdefault
= PlotGridX
;
776 PlotGridYdefault
= PlotGridY
;
777 RepaintGraphWindow ();
781 int CmdHexsamples ( const char * Cmd
)
787 char * string_ptr
= string_buf
;
790 sscanf ( Cmd
, "%i %i" , & requested
, & offset
);
792 /* if no args send something */
793 if ( requested
== 0 ) {
796 if ( offset
+ requested
> sizeof ( got
)) {
797 PrintAndLog ( "Tried to read past end of buffer, <bytes> + <offset> > 40000" );
801 GetFromBigBuf ( got
, requested
, offset
);
802 WaitForResponse ( CMD_ACK
, NULL
);
805 for ( j
= 0 ; j
< requested
; j
++) {
807 string_ptr
+= sprintf ( string_ptr
, "%02x " , got
[ j
]);
809 *( string_ptr
- 1 ) = '\0' ; // remove the trailing space
810 PrintAndLog ( "%s" , string_buf
);
811 string_buf
[ 0 ] = '\0' ;
812 string_ptr
= string_buf
;
815 if ( j
== requested
- 1 && string_buf
[ 0 ] != '\0' ) { // print any remaining bytes
816 *( string_ptr
- 1 ) = '\0' ;
817 PrintAndLog ( "%s" , string_buf
);
818 string_buf
[ 0 ] = '\0' ;
824 int CmdHide ( const char * Cmd
)
830 int CmdHpf ( const char * Cmd
)
835 for ( i
= 10 ; i
< GraphTraceLen
; ++ i
)
836 accum
+= GraphBuffer
[ i
];
837 accum
/= ( GraphTraceLen
- 10 );
838 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
)
839 GraphBuffer
[ i
] -= accum
;
841 RepaintGraphWindow ();
845 int CmdSamples ( const char * Cmd
)
851 n
= strtol ( Cmd
, NULL
, 0 );
852 if ( n
== 0 ) n
= 6000 ;
853 if ( n
> sizeof ( got
)) n
= sizeof ( got
);
855 PrintAndLog ( "Reading %d samples \n " , n
);
856 GetFromBigBuf ( got
, n
, 0 );
857 WaitForResponse ( CMD_ACK
, NULL
);
858 for ( int j
= 0 ; j
< n
; j
++) {
859 GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) - 128 ;
862 PrintAndLog ( "Done! \n " );
864 RepaintGraphWindow ();
868 int CmdTuneSamples ( const char * Cmd
)
874 PrintAndLog ( "Reading %d samples \n " , n
);
875 GetFromBigBuf ( got
, n
, 7256 ); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256
876 WaitForResponse ( CMD_ACK
, NULL
);
877 for ( int j
= 0 ; j
< n
; j
++) {
878 GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) - 128 ;
881 PrintAndLog ( "Done! Divisor 89 is 134khz, 95 is 125khz. \n " );
884 RepaintGraphWindow ();
888 int CmdLoad ( const char * Cmd
)
890 FILE * f
= fopen ( Cmd
, "r" );
892 PrintAndLog ( "couldn't open '%s'" , Cmd
);
898 while ( fgets ( line
, sizeof ( line
), f
)) {
899 GraphBuffer
[ GraphTraceLen
] = atoi ( line
);
903 PrintAndLog ( "loaded %d samples" , GraphTraceLen
);
904 RepaintGraphWindow ();
908 int CmdLtrim ( const char * Cmd
)
912 for ( int i
= ds
; i
< GraphTraceLen
; ++ i
)
913 GraphBuffer
[ i
- ds
] = GraphBuffer
[ i
];
916 RepaintGraphWindow ();
921 * Manchester demodulate a bitstream. The bitstream needs to be already in
922 * the GraphBuffer as 0 and 1 values
924 * Give the clock rate as argument in order to help the sync - the algorithm
925 * resyncs at each pulse anyway.
927 * Not optimized by any means, this is the 1st time I'm writing this type of
928 * routine, feel free to improve...
930 * 1st argument: clock rate (as number of samples per clock rate)
931 * Typical values can be 64, 32, 128...
933 int CmdManchesterDemod ( const char * Cmd
)
941 int hithigh
, hitlow
, first
;
947 /* check if we're inverting output */
950 PrintAndLog ( "Inverting output" );
955 while (* Cmd
== ' ' ); // in case a 2nd argument was given
958 /* Holds the decoded bitstream: each clock period contains 2 bits */
959 /* later simplified to 1 bit after manchester decoding. */
960 /* Add 10 bits to allow for noisy / uncertain traces without aborting */
961 /* int BitStream[GraphTraceLen*2/clock+10]; */
963 /* But it does not work if compiling on WIndows: therefore we just allocate a */
965 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
] = { 0 };
967 /* Detect high and lows */
968 for ( i
= 0 ; i
< GraphTraceLen
; i
++)
970 if ( GraphBuffer
[ i
] > high
)
971 high
= GraphBuffer
[ i
];
972 else if ( GraphBuffer
[ i
] < low
)
973 low
= GraphBuffer
[ i
];
977 clock
= GetClock ( Cmd
, high
, 1 );
979 int tolerance
= clock
/ 4 ;
981 /* Detect first transition */
982 /* Lo-Hi (arbitrary) */
983 /* skip to the first high */
984 for ( i
= 0 ; i
< GraphTraceLen
; i
++)
985 if ( GraphBuffer
[ i
] == high
)
987 /* now look for the first low */
988 for (; i
< GraphTraceLen
; i
++)
990 if ( GraphBuffer
[ i
] == low
)
997 /* If we're not working with 1/0s, demod based off clock */
1000 bit
= 0 ; /* We assume the 1st bit is zero, it may not be
1001 * the case: this routine (I think) has an init problem.
1004 for (; i
< ( int )( GraphTraceLen
/ clock
); i
++)
1010 /* Find out if we hit both high and low peaks */
1011 for ( j
= 0 ; j
< clock
; j
++)
1013 if ( GraphBuffer
[( i
* clock
) + j
] == high
)
1015 else if ( GraphBuffer
[( i
* clock
) + j
] == low
)
1018 /* it doesn't count if it's the first part of our read
1019 because it's really just trailing from the last sequence */
1020 if ( first
&& ( hithigh
|| hitlow
))
1021 hithigh
= hitlow
= 0 ;
1025 if ( hithigh
&& hitlow
)
1029 /* If we didn't hit both high and low peaks, we had a bit transition */
1030 if (! hithigh
|| ! hitlow
)
1033 BitStream
[ bit2idx
++] = bit
^ invert
;
1037 /* standard 1/0 bitstream */
1041 /* Then detect duration between 2 successive transitions */
1042 for ( bitidx
= 1 ; i
< GraphTraceLen
; i
++)
1044 if ( GraphBuffer
[ i
- 1 ] != GraphBuffer
[ i
])
1049 // Error check: if bitidx becomes too large, we do not
1050 // have a Manchester encoded bitstream or the clock is really
1052 if ( bitidx
> ( GraphTraceLen
* 2 / clock
+ 8 ) ) {
1053 PrintAndLog ( "Error: the clock you gave is probably wrong, aborting." );
1056 // Then switch depending on lc length:
1057 // Tolerance is 1/4 of clock rate (arbitrary)
1058 if ( abs ( lc
- clock
/ 2 ) < tolerance
) {
1059 // Short pulse : either "1" or "0"
1060 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1061 } else if ( abs ( lc
- clock
) < tolerance
) {
1062 // Long pulse: either "11" or "00"
1063 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1064 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1068 PrintAndLog ( "Warning: Manchester decode error for pulse width detection." );
1069 PrintAndLog ( "(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)" );
1073 PrintAndLog ( "Error: too many detection errors, aborting." );
1080 // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
1081 // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
1082 // to stop output at the final bitidx2 value, not bitidx
1083 for ( i
= 0 ; i
< bitidx
; i
+= 2 ) {
1084 if (( BitStream
[ i
] == 0 ) && ( BitStream
[ i
+ 1 ] == 1 )) {
1085 BitStream
[ bit2idx
++] = 1 ^ invert
;
1086 } else if (( BitStream
[ i
] == 1 ) && ( BitStream
[ i
+ 1 ] == 0 )) {
1087 BitStream
[ bit2idx
++] = 0 ^ invert
;
1089 // We cannot end up in this state, this means we are unsynchronized,
1093 PrintAndLog ( "Unsynchronized, resync..." );
1094 PrintAndLog ( "(too many of those messages mean the stream is not Manchester encoded)" );
1098 PrintAndLog ( "Error: too many decode errors, aborting." );
1105 PrintAndLog ( "Manchester decoded bitstream" );
1106 // Now output the bitstream to the scrollback by line of 16 bits
1107 for ( i
= 0 ; i
< ( bit2idx
- 16 ); i
+= 16 ) {
1108 PrintAndLog ( "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i" ,
1129 /* Modulate our data into manchester */
1130 int CmdManchesterMod ( const char * Cmd
)
1134 int bit
, lastbit
, wave
;
1137 clock
= GetClock ( Cmd
, 0 , 1 );
1141 for ( i
= 0 ; i
< ( int )( GraphTraceLen
/ clock
); i
++)
1143 bit
= GraphBuffer
[ i
* clock
] ^ 1 ;
1145 for ( j
= 0 ; j
< ( int )( clock
/ 2 ); j
++)
1146 GraphBuffer
[( i
* clock
) + j
] = bit
^ lastbit
^ wave
;
1147 for ( j
= ( int )( clock
/ 2 ); j
< clock
; j
++)
1148 GraphBuffer
[( i
* clock
) + j
] = bit
^ lastbit
^ wave
^ 1 ;
1150 /* Keep track of how we start our wave and if we changed or not this time */
1151 wave
^= bit
^ lastbit
;
1155 RepaintGraphWindow ();
1159 int CmdNorm ( const char * Cmd
)
1162 int max
= INT_MIN
, min
= INT_MAX
;
1164 for ( i
= 10 ; i
< GraphTraceLen
; ++ i
) {
1165 if ( GraphBuffer
[ i
] > max
)
1166 max
= GraphBuffer
[ i
];
1167 if ( GraphBuffer
[ i
] < min
)
1168 min
= GraphBuffer
[ i
];
1172 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1173 GraphBuffer
[ i
] = ( GraphBuffer
[ i
] - (( max
+ min
) / 2 )) * 1000 /
1177 RepaintGraphWindow ();
1181 int CmdPlot ( const char * Cmd
)
1187 int CmdSave ( const char * Cmd
)
1189 FILE * f
= fopen ( Cmd
, "w" );
1191 PrintAndLog ( "couldn't open '%s'" , Cmd
);
1195 for ( i
= 0 ; i
< GraphTraceLen
; i
++) {
1196 fprintf ( f
, "%d \n " , GraphBuffer
[ i
]);
1199 PrintAndLog ( "saved to '%s'" , Cmd
);
1203 int CmdScale ( const char * Cmd
)
1205 CursorScaleFactor
= atoi ( Cmd
);
1206 if ( CursorScaleFactor
== 0 ) {
1207 PrintAndLog ( "bad, can't have zero scale" );
1208 CursorScaleFactor
= 1 ;
1210 RepaintGraphWindow ();
1214 int CmdThreshold ( const char * Cmd
)
1216 int threshold
= atoi ( Cmd
);
1218 for ( int i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1219 if ( GraphBuffer
[ i
] >= threshold
)
1222 GraphBuffer
[ i
] = - 1 ;
1224 RepaintGraphWindow ();
1228 int CmdDirectionalThreshold ( const char * Cmd
)
1230 int8_t upThres
= param_get8 ( Cmd
, 0 );
1231 int8_t downThres
= param_get8 ( Cmd
, 1 );
1233 printf ( "Applying Up Threshold: %d, Down Threshold: %d \n " , upThres
, downThres
);
1235 int lastValue
= GraphBuffer
[ 0 ];
1236 GraphBuffer
[ 0 ] = 0 ; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
1238 for ( int i
= 1 ; i
< GraphTraceLen
; ++ i
) {
1239 // Apply first threshold to samples heading up
1240 if ( GraphBuffer
[ i
] >= upThres
&& GraphBuffer
[ i
] > lastValue
)
1242 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1245 // Apply second threshold to samples heading down
1246 else if ( GraphBuffer
[ i
] <= downThres
&& GraphBuffer
[ i
] < lastValue
)
1248 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1249 GraphBuffer
[ i
] = - 1 ;
1253 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1254 GraphBuffer
[ i
] = GraphBuffer
[ i
- 1 ];
1258 GraphBuffer
[ 0 ] = GraphBuffer
[ 1 ]; // Aline with first edited sample.
1259 RepaintGraphWindow ();
1263 int CmdZerocrossings ( const char * Cmd
)
1265 // Zero-crossings aren't meaningful unless the signal is zero-mean.
1272 for ( int i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1273 if ( GraphBuffer
[ i
] * sign
>= 0 ) {
1274 // No change in sign, reproduce the previous sample count.
1276 GraphBuffer
[ i
] = lastZc
;
1278 // Change in sign, reset the sample count.
1280 GraphBuffer
[ i
] = lastZc
;
1288 RepaintGraphWindow ();
1292 static command_t CommandTable
[] =
1294 { "help" , CmdHelp
, 1 , "This help" },
1295 { "amp" , CmdAmp
, 1 , "Amplify peaks" },
1296 { "askdemod" , Cmdaskdemod
, 1 , "<0 or 1> -- Attempt to demodulate simple ASK tags" },
1297 { "askmandemod" , Cmdaskmandemod
, 1 , "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])" },
1298 { "askrawdemod" , Cmdaskrawdemod
, 1 , "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])" },
1299 { "autocorr" , CmdAutoCorr
, 1 , "<window length> -- Autocorrelation over window" },
1300 { "bitsamples" , CmdBitsamples
, 0 , "Get raw samples as bitstring" },
1301 { "bitstream" , CmdBitstream
, 1 , "[clock rate] -- Convert waveform into a bitstream" },
1302 { "buffclear" , CmdBuffClear
, 1 , "Clear sample buffer and graph window" },
1303 { "dec" , CmdDec
, 1 , "Decimate samples" },
1304 { "detectclock" , CmdDetectClockRate
, 1 , "Detect clock rate" },
1305 { "fskdemod" , CmdFSKdemod
, 1 , "Demodulate graph window as a HID FSK" },
1306 { "fskhiddemod" , CmdFSKdemodHID
, 1 , "Demodulate graph window as a HID FSK using raw" },
1307 { "fskiodemod" , CmdFSKdemodIO
, 1 , "Demodulate graph window as an IO Prox FSK using raw" },
1308 { "fskrawdemod" , CmdFSKrawdemod
, 1 , "[clock rate] [invert] Demodulate graph window from FSK to binary (clock = 64 or 50)(invert = 1 or 0)" },
1309 { "grid" , CmdGrid
, 1 , "<x> <y> -- overlay grid on graph window, use zero value to turn off either" },
1310 { "hexsamples" , CmdHexsamples
, 0 , "<bytes> [<offset>] -- Dump big buffer as hex bytes" },
1311 { "hide" , CmdHide
, 1 , "Hide graph window" },
1312 { "hpf" , CmdHpf
, 1 , "Remove DC offset from trace" },
1313 { "load" , CmdLoad
, 1 , "<filename> -- Load trace (to graph window" },
1314 { "ltrim" , CmdLtrim
, 1 , "<samples> -- Trim samples from left of trace" },
1315 { "mandemod" , CmdManchesterDemod
, 1 , "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)" },
1316 { "manrawdecode" , Cmdmandecoderaw
, 1 , "Manchester decode binary stream already in graph buffer" },
1317 { "manmod" , CmdManchesterMod
, 1 , "[clock rate] -- Manchester modulate a binary stream" },
1318 { "norm" , CmdNorm
, 1 , "Normalize max/min to +/-500" },
1319 { "plot" , CmdPlot
, 1 , "Show graph window (hit 'h' in window for keystroke help)" },
1320 { "samples" , CmdSamples
, 0 , "[512 - 40000] -- Get raw samples for graph window" },
1321 { "tune" , CmdTuneSamples
, 0 , "Get hw tune samples for graph window" },
1322 { "save" , CmdSave
, 1 , "<filename> -- Save trace (from graph window)" },
1323 { "scale" , CmdScale
, 1 , "<int> -- Set cursor display scale" },
1324 { "threshold" , CmdThreshold
, 1 , "<threshold> -- Maximize/minimize every value in the graph window depending on threshold" },
1325 { "zerocrossings" , CmdZerocrossings
, 1 , "Count time between zero-crossings" },
1326 { "dirthreshold" , CmdDirectionalThreshold
, 1 , "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev." },
1327 { NULL
, NULL
, 0 , NULL
}
1330 int CmdData ( const char * Cmd
)
1332 CmdsParse ( CommandTable
, Cmd
);
1336 int CmdHelp ( const char * Cmd
)
1338 CmdsHelp ( CommandTable
);