]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmddata.c
be6e35d58f49b0afdc4408835df6ebc22afe3c05
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 //-----------------------------------------------------------------------------
17 #include "proxmark3.h"
21 #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
)
93 if ( c
!= 0 && c
!= 1 ) {
94 PrintAndLog ( "Invalid argument: %s" , Cmd
);
98 if ( GraphBuffer
[ 0 ] > 0 ) {
103 for ( i
= 1 ; i
< GraphTraceLen
; ++ i
) {
104 /* Transitions are detected at each peak
105 * Transitions are either:
106 * - we're low: transition if we hit a high
107 * - we're high: transition if we hit a low
108 * (we need to do it this way because some tags keep high or
109 * low for long periods, others just reach the peak and go
112 //[marhsmellow] change == to >= for high and <= for low for fuzz
113 if (( GraphBuffer
[ i
] == high
) && ( GraphBuffer
[ i
- 1 ] == c
)) {
114 GraphBuffer
[ i
] = 1 - c
;
115 } else if (( GraphBuffer
[ i
] == low
) && ( GraphBuffer
[ i
- 1 ] == ( 1 - c
))){
119 GraphBuffer
[ i
] = GraphBuffer
[ i
- 1 ];
122 RepaintGraphWindow ();
126 void printBitStream ( int BitStream
[], uint32_t bitLen
){
128 if ( bitLen
< 16 ) return ;
129 if ( bitLen
> 512 ) bitLen
= 512 ;
130 for ( i
= 0 ; i
< ( bitLen
- 16 ); i
+= 16 ) {
131 PrintAndLog ( "%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i" ,
151 void printBitStream2 ( uint8_t BitStream
[], uint32_t bitLen
){
154 PrintAndLog ( "Too few bits found: %d" , bitLen
);
157 if ( bitLen
> 512 ) bitLen
= 512 ;
158 for ( i
= 0 ; i
< ( bitLen
- 16 ); i
+= 16 ) {
159 PrintAndLog ( "%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i" ,
181 //takes 1s and 0s and searches for EM410x format - output EM ID
182 int Em410xDecode ( const char * Cmd
)
184 //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
185 // otherwise could be a void with no arguments
188 uint64_t lo
= 0 ; //hi=0,
191 uint32_t initLoopMax
= 1000 ;
192 if ( initLoopMax
> GraphTraceLen
) initLoopMax
= GraphTraceLen
;
194 for (; i
< initLoopMax
; ++ i
) //1000 samples should be plenty to find high and low values
196 if ( GraphBuffer
[ i
] > high
)
197 high
= GraphBuffer
[ i
];
198 else if ( GraphBuffer
[ i
] < low
)
199 low
= GraphBuffer
[ i
];
201 if ((( high
!= 1 )||( low
!= 0 ))){ //allow only 1s and 0s
202 PrintAndLog ( "no data found" );
205 uint8_t parityTest
= 0 ;
206 // 111111111 bit pattern represent start of frame
207 int frame_marker_mask
[] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 };
210 uint8_t resetCnt
= 0 ;
211 while ( ( idx
+ 64 ) < GraphTraceLen
) {
213 // search for a start of frame marker
214 if ( memcmp ( GraphBuffer
+ idx
, frame_marker_mask
, sizeof ( frame_marker_mask
)) == 0 )
215 { // frame marker found
216 idx
+= 9 ; //sizeof(frame_marker_mask);
218 for ( ii
= 0 ; ii
< 5 ; ++ ii
){
219 parityTest
+= GraphBuffer
[( i
* 5 )+ ii
+ idx
];
221 if ( parityTest
== (( parityTest
>> 1 )<< 1 )){
223 for ( ii
= 0 ; ii
< 4 ;++ ii
){
224 //hi = (hi<<1)|(lo>>31);
225 lo
=( lo
<< 1LL )|( GraphBuffer
[( i
* 5 )+ ii
+ idx
]);
227 //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[idx+ii+(i*5)-1],lo);
228 } else { //parity failed
229 //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[idx+ii+(i*5)-1]);
232 if ( resetCnt
> 5 ) return 0 ;
234 goto restart
; //continue;
237 //skip last 5 bit parity test for simplicity.
241 uint64_t id2lo
= 0 ; //id2hi=0,
242 //for (i=0;i<8;i++){ //for uint32 instead of uint64
243 // id2hi=(id2hi<<1)|((hi & (iii<<(i)))>>i);
245 for ( ii
= 5 ; ii
> 0 ; ii
--){
247 id2lo
=( id2lo
<< 1LL )|(( lo
& ( iii
<<( i
+(( ii
- 1 )* 8 ))))>>( i
+(( ii
- 1 )* 8 )));
251 PrintAndLog ( "EM TAG ID : %010llx" , lo
);
252 PrintAndLog ( "Unique TAG ID: %010llx" , id2lo
); //id2hi,
253 PrintAndLog ( "DEZ 8 : %08lld" , lo
& 0xFFFFFF );
254 PrintAndLog ( "DEZ 10 : %010lld" , lo
& 0xFFFFFF );
255 PrintAndLog ( "DEZ 5.5 : %05lld.%05lld" ,( lo
>> 16LL ) & 0xFFFF ,( lo
& 0xFFFF ));
256 PrintAndLog ( "DEZ 3.5A : %03lld.%05lld" ,( lo
>> 32ll ),( lo
& 0xFFFF ));
257 PrintAndLog ( "DEZ 14/IK2 : %014lld" , lo
);
258 PrintAndLog ( "DEZ 15/IK3 : %015lld" , id2lo
);
259 PrintAndLog ( "Other : %05lld_%03lld_%08lld" ,( lo
& 0xFFFF ),(( lo
>> 16LL ) & 0xFF ),( lo
& 0xFFFFFF ));
270 //takes 2 arguments - clock and invert both as integers
271 //prints binary found and saves in graphbuffer for further commands
272 int Cmdaskmandemod ( const char * Cmd
)
275 int invert
= 0 ; //invert default
276 int high
= 0 , low
= 0 ;
277 int clk
= DetectClock ( 0 ); //clock default
278 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
] = { 0 };
280 sscanf ( Cmd
, "%i %i" , & clk
, & invert
);
283 if ( invert
!= 0 && invert
!= 1 ) {
284 PrintAndLog ( "Invalid argument: %s" , Cmd
);
287 uint32_t initLoopMax
= 1000 ;
288 if ( initLoopMax
> GraphTraceLen
) initLoopMax
= GraphTraceLen
;
289 // Detect high and lows
290 PrintAndLog ( "Using Clock: %d and invert=%d" , clk
, invert
);
291 for ( i
= 0 ; i
< initLoopMax
; ++ i
) //1000 samples should be plenty to find high and low values
293 if ( GraphBuffer
[ i
] > high
)
294 high
= GraphBuffer
[ i
];
295 else if ( GraphBuffer
[ i
] < low
)
296 low
= GraphBuffer
[ i
];
298 if (( high
< 30 ) && (( high
!= 1 )||( low
!=- 1 ))){ //throw away static - allow 1 and -1 (in case of threshold command first)
299 PrintAndLog ( "no data found" );
302 //13% fuzz in case highs and lows aren't clipped [marshmellow]
303 high
=( int )( 0.75 * high
);
306 //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
307 int lastBit
= 0 ; //set first clock check
308 uint32_t bitnum
= 0 ; //output counter
309 uint8_t tol
= 0 ; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
310 if ( clk
== 32 ) tol
= 1 ; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
312 uint32_t gLen
= GraphTraceLen
;
313 if ( gLen
> 500 ) gLen
= 500 ;
315 uint32_t bestStart
= GraphTraceLen
;
316 uint32_t bestErrCnt
= ( GraphTraceLen
/ 1000 );
317 //PrintAndLog("DEBUG - lastbit - %d",lastBit);
318 //loop to find first wave that works
319 for ( iii
= 0 ; iii
< gLen
; ++ iii
){
320 if (( GraphBuffer
[ iii
]>= high
)||( GraphBuffer
[ iii
]<= low
)){
322 //loop through to see if this start location works
323 for ( i
= iii
; i
< GraphTraceLen
; ++ i
) {
324 if (( GraphBuffer
[ i
] >= high
) && (( i
- lastBit
)>( clk
- tol
))){
326 BitStream
[ bitnum
] = invert
;
328 } else if (( GraphBuffer
[ i
] <= low
) && (( i
- lastBit
)>( clk
- tol
))){
329 //low found and we are expecting a bar
331 BitStream
[ bitnum
] = 1 - invert
;
334 //mid value found or no bar supposed to be here
335 if (( i
- lastBit
)>( clk
+ tol
)){
336 //should have hit a high or low based on clock!!
340 //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
342 BitStream
[ bitnum
]= 77 ;
348 lastBit
+= clk
; //skip over until hit too many errors
349 if ( errCnt
>(( GraphTraceLen
/ 1000 ))){ //allow 1 error for every 1000 samples else start over
351 bitnum
= 0 ; //start over
357 //we got more than 64 good bits and not all errors
358 if (( bitnum
> ( 64 + errCnt
)) && ( errCnt
<( GraphTraceLen
/ 1000 ))) {
360 if ( errCnt
== 0 ) break ; //great read - finish
361 if ( bestStart
== iii
) break ; //if current run == bestErrCnt run (after exhausted testing) then finish
362 if ( errCnt
< bestErrCnt
){ //set this as new best run
368 if ( iii
>= gLen
){ //exhausted test
369 //if there was a ok test go back to that one and re-run the best run (then dump after that run)
370 if ( bestErrCnt
< ( GraphTraceLen
/ 1000 )) iii
= bestStart
;
375 PrintAndLog ( "Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d" , iii
, lastBit
, i
, bitnum
);
376 //move BitStream back to GraphBuffer
378 for ( i
= 0 ; i
< bitnum
; ++ i
){
379 GraphBuffer
[ i
]= BitStream
[ i
];
381 GraphTraceLen
= bitnum
;
382 RepaintGraphWindow ();
385 PrintAndLog ( "# Errors during Demoding (shown as 77 in bit stream): %d" , errCnt
);
387 PrintAndLog ( "ASK decoded bitstream:" );
388 // Now output the bitstream to the scrollback by line of 16 bits
389 printBitStream2 ( BitStream
, bitnum
);
395 int CmdAutoCorr ( const char * Cmd
)
397 static int CorrelBuffer
[ MAX_GRAPH_TRACE_LEN
];
399 int window
= atoi ( Cmd
);
402 PrintAndLog ( "needs a window" );
405 if ( window
>= GraphTraceLen
) {
406 PrintAndLog ( "window must be smaller than trace (%d samples)" ,
411 PrintAndLog ( "performing %d correlations" , GraphTraceLen
- window
);
413 for ( int i
= 0 ; i
< GraphTraceLen
- window
; ++ i
) {
415 for ( int j
= 0 ; j
< window
; ++ j
) {
416 sum
+= ( GraphBuffer
[ j
]* GraphBuffer
[ i
+ j
]) / 256 ;
418 CorrelBuffer
[ i
] = sum
;
420 GraphTraceLen
= GraphTraceLen
- window
;
421 memcpy ( GraphBuffer
, CorrelBuffer
, GraphTraceLen
* sizeof ( int ));
423 RepaintGraphWindow ();
427 int CmdBitsamples ( const char * Cmd
)
432 GetFromBigBuf ( got
, sizeof ( got
), 0 );
433 WaitForResponse ( CMD_ACK
, NULL
);
435 for ( int j
= 0 ; j
< sizeof ( got
); j
++) {
436 for ( int k
= 0 ; k
< 8 ; k
++) {
437 if ( got
[ j
] & ( 1 << ( 7 - k
))) {
438 GraphBuffer
[ cnt
++] = 1 ;
440 GraphBuffer
[ cnt
++] = 0 ;
445 RepaintGraphWindow ();
450 * Convert to a bitstream
452 int CmdBitstream ( const char * Cmd
)
460 int hithigh
, hitlow
, first
;
462 /* Detect high and lows and clock */
463 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
)
465 if ( GraphBuffer
[ i
] > high
)
466 high
= GraphBuffer
[ i
];
467 else if ( GraphBuffer
[ i
] < low
)
468 low
= GraphBuffer
[ i
];
472 clock
= GetClock ( Cmd
, high
, 1 );
476 for ( i
= 0 ; i
< ( int )( gtl
/ clock
); ++ i
)
481 /* Find out if we hit both high and low peaks */
482 for ( j
= 0 ; j
< clock
; ++ j
)
484 if ( GraphBuffer
[( i
* clock
) + j
] == high
)
486 else if ( GraphBuffer
[( i
* clock
) + j
] == low
)
488 /* it doesn't count if it's the first part of our read
489 because it's really just trailing from the last sequence */
490 if ( first
&& ( hithigh
|| hitlow
))
491 hithigh
= hitlow
= 0 ;
495 if ( hithigh
&& hitlow
)
499 /* If we didn't hit both high and low peaks, we had a bit transition */
500 if (! hithigh
|| ! hitlow
)
503 AppendGraph ( 0 , clock
, bit
);
504 // for (j = 0; j < (int)(clock/2); j++)
505 // GraphBuffer[(i * clock) + j] = bit ^ 1;
506 // for (j = (int)(clock/2); j < clock; j++)
507 // GraphBuffer[(i * clock) + j] = bit;
510 RepaintGraphWindow ();
514 int CmdBuffClear ( const char * Cmd
)
516 UsbCommand c
= { CMD_BUFF_CLEAR
};
522 int CmdDec ( const char * Cmd
)
524 for ( int i
= 0 ; i
< ( GraphTraceLen
/ 2 ); ++ i
)
525 GraphBuffer
[ i
] = GraphBuffer
[ i
* 2 ];
527 PrintAndLog ( "decimated by 2" );
528 RepaintGraphWindow ();
532 /* Print our clock rate */
533 int CmdDetectClockRate ( const char * Cmd
)
535 int clock
= DetectClock ( 0 );
536 PrintAndLog ( "Auto-detected clock rate: %d" , clock
);
541 //demod GraphBuffer wave to 0s and 1s for each wave - 0s for short waves 1s for long waves
542 size_t fsk_wave_demod ( int size
)
544 uint32_t last_transition
= 0 ;
547 // we don't care about actual value, only if it's more or less than a
548 // threshold essentially we capture zero crossings for later analysis
549 for ( idx
= 1 ; idx
< size
; idx
++){
550 if ( maxVal
< GraphBuffer
[ idx
]) maxVal
= GraphBuffer
[ idx
];
552 // set close to the top of the wave threshold with 13% margin for error
553 // less likely to get a false transition up there.
554 // (but have to be careful not to go too high and miss some short waves)
555 uint32_t threshold_value
= ( uint32_t )( maxVal
* .87 );
557 // int threshold_value = 100;
559 // sync to first lo-hi transition, and threshold
560 // PrintAndLog("FSK init complete size: %d",size);//debug
561 // Need to threshold first sample
562 if ( GraphBuffer
[ 0 ] < threshold_value
) GraphBuffer
[ 0 ] = 0 ;
563 else GraphBuffer
[ 0 ] = 1 ;
565 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
566 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
567 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
568 for ( idx
= 1 ; idx
< size
; idx
++) {
569 // threshold current value
570 if ( GraphBuffer
[ idx
] < threshold_value
) GraphBuffer
[ idx
] = 0 ;
571 else GraphBuffer
[ idx
] = 1 ;
572 // Check for 0->1 transition
573 if ( GraphBuffer
[ idx
- 1 ] < GraphBuffer
[ idx
]) { // 0 -> 1 transition
574 if ( idx
- last_transition
< 6 ){
575 // do nothing with extra garbage (shouldn't be any) noise tolerance?
576 } else if ( idx
- last_transition
< 9 ) {
577 GraphBuffer
[ numBits
]= 1 ;
578 // Other fsk demods reverse this making the short waves 1 and long waves 0
579 // this is really backwards... smaller waves will typically be 0 and larger 1 [marshmellow]
580 // but will leave as is and invert when needed later
582 GraphBuffer
[ numBits
]= 0 ;
584 last_transition
= idx
;
586 // PrintAndLog("numbits %d",numBits);
589 return numBits
; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0
591 uint32_t myround ( float f
)
593 if ( f
>= UINT_MAX
) return UINT_MAX
;
594 return ( uint32_t ) ( f
+ ( float ) 0.5 );
597 //by marshmellow (from holiman's base)
598 //translate 11111100000 to 10
599 size_t aggregate_bits ( int size
, uint8_t rfLen
, uint8_t maxConsequtiveBits
, uint8_t invert
) //,uint8_t l2h_crossing_value
601 int lastval
= GraphBuffer
[ 0 ];
606 for ( idx
= 1 ; idx
< size
; idx
++) {
608 if ( GraphBuffer
[ idx
]== lastval
) {
612 // if lastval was 1, we have a 1->0 crossing
613 if ( GraphBuffer
[ idx
- 1 ]== 1 ) {
614 n
= myround (( float )( n
+ 1 )/(( float )( rfLen
)/( float ) 8 )); //-2 noise tolerance
616 // n=(n+1) / h2l_crossing_value;
617 //truncating could get us into trouble
618 //now we will try with actual clock (RF/64 or RF/50) variable instead
619 //then devide with float casting then truncate after more acurate division
620 //and round to nearest int
621 //like n = (((float)n)/(float)rfLen/(float)10);
622 } else { // 0->1 crossing
623 n
= myround (( float )( n
+ 1 )/(( float )( rfLen
- 2 )/( float ) 10 )); // as int 120/6 = 20 as float 120/(64/10) = 18 (18.75)
624 //n=(n+1) / l2h_crossing_value;
626 if ( n
== 0 ) n
= 1 ; //this should never happen... should we error if it does?
628 if ( n
< maxConsequtiveBits
) // Consecutive //when the consecutive bits are low - the noise tolerance can be high
629 //if it is high then we must be careful how much noise tolerance we allow
631 if ( invert
== 0 ){ // do not invert bits
632 for ( n2
= 0 ; n2
< n
; n2
++){
633 GraphBuffer
[ numBits
+ n2
]= GraphBuffer
[ idx
- 1 ];
635 //memset(GraphBuffer+numBits, GraphBuffer[idx-1] , n);
636 } else { // invert bits
637 for ( n2
= 0 ; n2
< n
; n2
++){
638 GraphBuffer
[ numBits
+ n2
]= GraphBuffer
[ idx
- 1 ]^ 1 ;
640 //memset(GraphBuffer+numBits, GraphBuffer[idx-1]^1 , n);
645 lastval
= GraphBuffer
[ idx
];
650 //by marshmellow (from holiman's base)
651 // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod)
652 size_t fskdemod ( uint8_t rfLen
, uint8_t invert
)
654 //uint8_t h2l_crossing_value = 6;
655 //uint8_t l2h_crossing_value = 5;
657 // if (rfLen==64) //currently only know settings for RF/64 change from default if option entered
659 // h2l_crossing_value=8; //or 8 as 64/8 = 8
660 // l2h_crossing_value=6; //or 6.4 as 64/10 = 6.4
662 size_t size
= GraphTraceLen
;
664 size
= fsk_wave_demod ( size
);
665 size
= aggregate_bits ( size
, rfLen
, 192 , invert
);
666 // size = aggregate_bits(size, h2l_crossing_value, l2h_crossing_value,192, invert); //192=no limit to same values
667 //done messing with GraphBuffer - repaint
668 RepaintGraphWindow ();
671 uint32_t bytebits_to_byte ( int * src
, int numbits
)
674 for ( int i
= 0 ; i
< numbits
; i
++)
676 num
= ( num
<< 1 ) | (* src
);
683 //fsk demod and print binary
684 int CmdFSKrawdemod ( const char * Cmd
)
686 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
690 //set options from parameters entered with the command
691 if ( strlen ( Cmd
)> 0 && strlen ( Cmd
)<= 2 ) {
692 rfLen
= param_get8 ( Cmd
, 0 ); //if rfLen option only is used
694 invert
= 1 ; //if invert option only is used
696 } else if ( rfLen
== 0 ) rfLen
= 50 ;
699 rfLen
= param_get8 ( Cmd
, 0 ); //if both options are used
700 invert
= param_get8 ( Cmd
, 1 );
702 PrintAndLog ( "Args invert: %d \n Clock:%d" , invert
, rfLen
);
704 size_t size
= fskdemod ( rfLen
, invert
);
706 PrintAndLog ( "FSK decoded bitstream:" );
707 // Now output the bitstream to the scrollback by line of 16 bits
708 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
709 printBitStream ( GraphBuffer
, size
);
716 int CmdFSKdemodHID ( const char * Cmd
)
718 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
721 uint8_t invert
= 0 ; //param_get8(Cmd, 0);
723 uint32_t hi2
= 0 , hi
= 0 , lo
= 0 ;
725 //get binary from fsk wave
726 size_t size
= fskdemod ( rfLen
, invert
);
728 // final loop, go over previously decoded fsk data and now manchester decode into usable tag ID
729 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
730 int frame_marker_mask
[] = { 1 , 1 , 1 , 0 , 0 , 0 };
733 while ( idx
+ 6 < size
) {
734 // search for a start of frame marker
736 if ( memcmp ( GraphBuffer
+ idx
, frame_marker_mask
, sizeof ( frame_marker_mask
)) == 0 )
737 { // frame marker found
738 idx
+= 6 ; //sizeof(frame_marker_mask); //size of int is >6
739 while ( GraphBuffer
[ idx
] != GraphBuffer
[ idx
+ 1 ] && idx
< size
- 2 )
741 // Keep going until next frame marker (or error)
742 // Shift in a bit. Start by shifting high registers
743 hi2
= ( hi2
<< 1 )|( hi
>> 31 );
744 hi
= ( hi
<< 1 )|( lo
>> 31 );
745 //Then, shift in a 0 or one into low
746 if ( GraphBuffer
[ idx
] && ! GraphBuffer
[ idx
+ 1 ]) // 1 0
754 //PrintAndLog("Num shifts: %d ", numshifts);
755 // Hopefully, we read a tag and hit upon the next frame marker
758 if ( memcmp ( GraphBuffer
+( idx
), frame_marker_mask
, sizeof ( frame_marker_mask
)) == 0 )
760 if ( hi2
!= 0 ){ //extra large HID tags
761 PrintAndLog ( "TAG ID: %x%08x%08x (%d)" ,
762 ( unsigned int ) hi2
, ( unsigned int ) hi
, ( unsigned int ) lo
, ( unsigned int ) ( lo
>> 1 ) & 0xFFFF );
764 else { //standard HID tags <38 bits
765 //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
768 uint32_t cardnum
= 0 ;
769 if ((( hi
>> 5 )& 1 )== 1 ){ //if bit 38 is set then < 37 bit format is used
771 lo2
=((( hi
& 15 ) << 12 ) | ( lo
>> 20 )); //get bits 21-37 to check for format len bit
773 while ( lo2
> 1 ){ //find last bit set to 1 (format len bit)
781 cardnum
= ( lo
>> 1 )& 0xFFFF ;
785 cardnum
= ( lo
>> 1 )& 0x7FFFF ;
786 fc
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );
789 cardnum
= ( lo
>> 1 )& 0xFFFF ;
790 fc
= (( hi
& 1 )<< 15 )|( lo
>> 17 );
793 cardnum
= ( lo
>> 1 )& 0xFFFFF ;
794 fc
= (( hi
& 1 )<< 11 )|( lo
>> 21 );
797 else { //if bit 38 is not set then 37 bit format is used
802 cardnum
= ( lo
>> 1 )& 0x7FFFF ;
803 fc
= (( hi
& 0xF )<< 12 )|( lo
>> 20 );
807 PrintAndLog ( "TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d" ,
808 ( unsigned int ) hi
, ( unsigned int ) lo
, ( unsigned int ) ( lo
>> 1 ) & 0xFFFF ,
809 ( unsigned int ) bitlen
, ( unsigned int ) fc
, ( unsigned int ) cardnum
);
823 if ( idx
+ sizeof ( frame_marker_mask
) >= size
){
824 PrintAndLog ( "start bits for hid not found" );
825 PrintAndLog ( "FSK decoded bitstream:" );
826 // Now output the bitstream to the scrollback by line of 16 bits
827 printBitStream ( GraphBuffer
, size
);
835 int CmdFSKdemodIO ( const char * Cmd
)
837 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
843 //test samples are not just noise
844 if ( GraphTraceLen
< 64 ) return 0 ;
845 for ( idx
= 0 ; idx
< 64 ; idx
++){
846 if ( testMax
< GraphBuffer
[ idx
]) testMax
= GraphBuffer
[ idx
];
849 //get full binary from fsk wave
850 size_t size
= fskdemod ( rfLen
, invert
);
853 //PrintAndLog("testMax %d",testMax);
856 //0 10 20 30 40 50 60
858 //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
859 //-----------------------------------------------------------------------------
860 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
862 //XSF(version)facility:codeone+codetwo (raw)
864 int mask
[] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 };
865 for ( idx
= 0 ; idx
< ( size
- 74 ); idx
++) {
866 if ( memcmp ( GraphBuffer
+ idx
, mask
, sizeof ( mask
))== 0 ) {
868 if ( GraphBuffer
[ idx
+ 17 ]== 1 && GraphBuffer
[ idx
+ 26 ]== 1 && GraphBuffer
[ idx
+ 35 ]== 1 && GraphBuffer
[ idx
+ 44 ]== 1 && GraphBuffer
[ idx
+ 53 ]== 1 ){
869 //confirmed proper separator bits found
871 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
], GraphBuffer
[ idx
+ 1 ], GraphBuffer
[ idx
+ 2 ], GraphBuffer
[ idx
+ 3 ], GraphBuffer
[ idx
+ 4 ], GraphBuffer
[ idx
+ 5 ], GraphBuffer
[ idx
+ 6 ], GraphBuffer
[ idx
+ 7 ], GraphBuffer
[ idx
+ 8 ]);
872 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
+ 9 ], GraphBuffer
[ idx
+ 10 ], GraphBuffer
[ idx
+ 11 ], GraphBuffer
[ idx
+ 12 ], GraphBuffer
[ idx
+ 13 ], GraphBuffer
[ idx
+ 14 ], GraphBuffer
[ idx
+ 15 ], GraphBuffer
[ idx
+ 16 ], GraphBuffer
[ idx
+ 17 ]);
873 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
+ 18 ], GraphBuffer
[ idx
+ 19 ], GraphBuffer
[ idx
+ 20 ], GraphBuffer
[ idx
+ 21 ], GraphBuffer
[ idx
+ 22 ], GraphBuffer
[ idx
+ 23 ], GraphBuffer
[ idx
+ 24 ], GraphBuffer
[ idx
+ 25 ], GraphBuffer
[ idx
+ 26 ]);
874 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
+ 27 ], GraphBuffer
[ idx
+ 28 ], GraphBuffer
[ idx
+ 29 ], GraphBuffer
[ idx
+ 30 ], GraphBuffer
[ idx
+ 31 ], GraphBuffer
[ idx
+ 32 ], GraphBuffer
[ idx
+ 33 ], GraphBuffer
[ idx
+ 34 ], GraphBuffer
[ idx
+ 35 ]);
875 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
+ 36 ], GraphBuffer
[ idx
+ 37 ], GraphBuffer
[ idx
+ 38 ], GraphBuffer
[ idx
+ 39 ], GraphBuffer
[ idx
+ 40 ], GraphBuffer
[ idx
+ 41 ], GraphBuffer
[ idx
+ 42 ], GraphBuffer
[ idx
+ 43 ], GraphBuffer
[ idx
+ 44 ]);
876 PrintAndLog ( "%d%d%d%d%d%d%d%d %d" , GraphBuffer
[ idx
+ 45 ], GraphBuffer
[ idx
+ 46 ], GraphBuffer
[ idx
+ 47 ], GraphBuffer
[ idx
+ 48 ], GraphBuffer
[ idx
+ 49 ], GraphBuffer
[ idx
+ 50 ], GraphBuffer
[ idx
+ 51 ], GraphBuffer
[ idx
+ 52 ], GraphBuffer
[ idx
+ 53 ]);
877 PrintAndLog ( "%d%d%d%d%d%d%d%d %d%d" , GraphBuffer
[ idx
+ 54 ], GraphBuffer
[ idx
+ 55 ], GraphBuffer
[ idx
+ 56 ], GraphBuffer
[ idx
+ 57 ], GraphBuffer
[ idx
+ 58 ], GraphBuffer
[ idx
+ 59 ], GraphBuffer
[ idx
+ 60 ], GraphBuffer
[ idx
+ 61 ], GraphBuffer
[ idx
+ 62 ], GraphBuffer
[ idx
+ 63 ]);
879 uint32_t code
= bytebits_to_byte ( GraphBuffer
+ idx
, 32 );
880 uint32_t code2
= bytebits_to_byte ( GraphBuffer
+ idx
+ 32 , 32 );
881 short version
= bytebits_to_byte ( GraphBuffer
+ idx
+ 27 , 8 ); //14,4
882 uint8_t facilitycode
= bytebits_to_byte ( GraphBuffer
+ idx
+ 19 , 8 ) ;
883 uint16_t number
= ( bytebits_to_byte ( GraphBuffer
+ idx
+ 36 , 8 )<< 8 )|( bytebits_to_byte ( GraphBuffer
+ idx
+ 45 , 8 )); //36,9
885 PrintAndLog ( "XSF(%02d)%02x:%d (%08x%08x)" , version
, facilitycode
, number
, code
, code2
);
889 PrintAndLog ( "thought we had a valid tag but did not match format" );
893 if ( idx
>= ( size
- 74 )){
894 PrintAndLog ( "start bits for io prox not found" );
895 PrintAndLog ( "FSK decoded bitstream:" );
896 // Now output the bitstream to the scrollback by line of 16 bits
897 printBitStream ( GraphBuffer
, size
);
903 int CmdFSKdemod ( const char * Cmd
) //old CmdFSKdemod needs updating
905 static const int LowTone
[] = {
906 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
907 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
908 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
909 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
910 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1
912 static const int HighTone
[] = {
913 1 , 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
914 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
915 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
916 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
917 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 ,
918 1 , 1 , 1 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
921 int lowLen
= sizeof ( LowTone
) / sizeof ( int );
922 int highLen
= sizeof ( HighTone
) / sizeof ( int );
923 int convLen
= ( highLen
> lowLen
) ? highLen
: lowLen
; //if highlen > lowLen then highlen else lowlen
924 uint32_t hi
= 0 , lo
= 0 ;
927 int minMark
= 0 , maxMark
= 0 ;
929 for ( i
= 0 ; i
< GraphTraceLen
- convLen
; ++ i
) {
930 int lowSum
= 0 , highSum
= 0 ;
932 for ( j
= 0 ; j
< lowLen
; ++ j
) {
933 lowSum
+= LowTone
[ j
]* GraphBuffer
[ i
+ j
];
935 for ( j
= 0 ; j
< highLen
; ++ j
) {
936 highSum
+= HighTone
[ j
] * GraphBuffer
[ i
+ j
];
938 lowSum
= abs ( 100 * lowSum
/ lowLen
);
939 highSum
= abs ( 100 * highSum
/ highLen
);
940 GraphBuffer
[ i
] = ( highSum
<< 16 ) | lowSum
;
943 for ( i
= 0 ; i
< GraphTraceLen
- convLen
- 16 ; ++ i
) {
944 int lowTot
= 0 , highTot
= 0 ;
945 // 10 and 8 are f_s divided by f_l and f_h, rounded
946 for ( j
= 0 ; j
< 10 ; ++ j
) {
947 lowTot
+= ( GraphBuffer
[ i
+ j
] & 0xffff );
949 for ( j
= 0 ; j
< 8 ; j
++) {
950 highTot
+= ( GraphBuffer
[ i
+ j
] >> 16 );
952 GraphBuffer
[ i
] = lowTot
- highTot
;
953 if ( GraphBuffer
[ i
] > maxMark
) maxMark
= GraphBuffer
[ i
];
954 if ( GraphBuffer
[ i
] < minMark
) minMark
= GraphBuffer
[ i
];
957 GraphTraceLen
-= ( convLen
+ 16 );
958 RepaintGraphWindow ();
960 // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
961 int max
= 0 , maxPos
= 0 ;
962 for ( i
= 0 ; i
< 6000 ; ++ i
) {
964 for ( j
= 0 ; j
< 3 * lowLen
; ++ j
) {
965 dec
-= GraphBuffer
[ i
+ j
];
967 for (; j
< 3 * ( lowLen
+ highLen
); ++ j
) {
968 dec
+= GraphBuffer
[ i
+ j
];
976 // place start of bit sync marker in graph
977 GraphBuffer
[ maxPos
] = maxMark
;
978 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
982 // place end of bit sync marker in graph
983 GraphBuffer
[ maxPos
] = maxMark
;
984 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
986 PrintAndLog ( "actual data bits start at sample %d" , maxPos
);
987 PrintAndLog ( "length %d/%d" , highLen
, lowLen
);
990 bits
[ sizeof ( bits
)- 1 ] = '\0' ;
992 // find bit pairs and manchester decode them
993 for ( i
= 0 ; i
< arraylen ( bits
) - 1 ; ++ i
) {
995 for ( j
= 0 ; j
< lowLen
; ++ j
) {
996 dec
-= GraphBuffer
[ maxPos
+ j
];
998 for (; j
< lowLen
+ highLen
; ++ j
) {
999 dec
+= GraphBuffer
[ maxPos
+ j
];
1002 // place inter bit marker in graph
1003 GraphBuffer
[ maxPos
] = maxMark
;
1004 GraphBuffer
[ maxPos
+ 1 ] = minMark
;
1006 // hi and lo form a 64 bit pair
1007 hi
= ( hi
<< 1 ) | ( lo
>> 31 );
1009 // store decoded bit as binary (in hi/lo) and text (in bits[])
1017 PrintAndLog ( "bits: '%s'" , bits
);
1018 PrintAndLog ( "hex: %08x %08x" , hi
, lo
);
1022 int CmdGrid ( const char * Cmd
)
1024 sscanf ( Cmd
, "%i %i" , & PlotGridX
, & PlotGridY
);
1025 PlotGridXdefault
= PlotGridX
;
1026 PlotGridYdefault
= PlotGridY
;
1027 RepaintGraphWindow ();
1031 int CmdHexsamples ( const char * Cmd
)
1036 char string_buf
[ 25 ];
1037 char * string_ptr
= string_buf
;
1040 sscanf ( Cmd
, "%i %i" , & requested
, & offset
);
1042 /* if no args send something */
1043 if ( requested
== 0 ) {
1046 if ( offset
+ requested
> sizeof ( got
)) {
1047 PrintAndLog ( "Tried to read past end of buffer, <bytes> + <offset> > 40000" );
1051 GetFromBigBuf ( got
, requested
, offset
);
1052 WaitForResponse ( CMD_ACK
, NULL
);
1055 for ( j
= 0 ; j
< requested
; j
++) {
1057 string_ptr
+= sprintf ( string_ptr
, "%02x " , got
[ j
]);
1059 *( string_ptr
- 1 ) = '\0' ; // remove the trailing space
1060 PrintAndLog ( "%s" , string_buf
);
1061 string_buf
[ 0 ] = '\0' ;
1062 string_ptr
= string_buf
;
1065 if ( j
== requested
- 1 && string_buf
[ 0 ] != '\0' ) { // print any remaining bytes
1066 *( string_ptr
- 1 ) = '\0' ;
1067 PrintAndLog ( "%s" , string_buf
);
1068 string_buf
[ 0 ] = '\0' ;
1074 int CmdHide ( const char * Cmd
)
1080 int CmdHpf ( const char * Cmd
)
1085 for ( i
= 10 ; i
< GraphTraceLen
; ++ i
)
1086 accum
+= GraphBuffer
[ i
];
1087 accum
/= ( GraphTraceLen
- 10 );
1088 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
)
1089 GraphBuffer
[ i
] -= accum
;
1091 RepaintGraphWindow ();
1095 int CmdSamples ( const char * Cmd
)
1101 n
= strtol ( Cmd
, NULL
, 0 );
1102 if ( n
== 0 ) n
= 6000 ;
1103 if ( n
> sizeof ( got
)) n
= sizeof ( got
);
1105 PrintAndLog ( "Reading %d samples \n " , n
);
1106 GetFromBigBuf ( got
, n
, 0 );
1107 WaitForResponse ( CMD_ACK
, NULL
);
1108 for ( int j
= 0 ; j
< n
; j
++) {
1109 GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) - 128 ;
1112 PrintAndLog ( "Done! \n " );
1114 RepaintGraphWindow ();
1118 int CmdTuneSamples ( const char * Cmd
)
1124 PrintAndLog ( "Reading %d samples \n " , n
);
1125 GetFromBigBuf ( got
, n
, 7256 ); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256
1126 WaitForResponse ( CMD_ACK
, NULL
);
1127 for ( int j
= 0 ; j
< n
; j
++) {
1128 GraphBuffer
[ cnt
++] = (( int ) got
[ j
]) - 128 ;
1131 PrintAndLog ( "Done! Divisor 89 is 134khz, 95 is 125khz. \n " );
1134 RepaintGraphWindow ();
1138 int CmdLoad ( const char * Cmd
)
1140 FILE * f
= fopen ( Cmd
, "r" );
1142 PrintAndLog ( "couldn't open '%s'" , Cmd
);
1148 while ( fgets ( line
, sizeof ( line
), f
)) {
1149 GraphBuffer
[ GraphTraceLen
] = atoi ( line
);
1153 PrintAndLog ( "loaded %d samples" , GraphTraceLen
);
1154 RepaintGraphWindow ();
1158 int CmdLtrim ( const char * Cmd
)
1162 for ( int i
= ds
; i
< GraphTraceLen
; ++ i
)
1163 GraphBuffer
[ i
- ds
] = GraphBuffer
[ i
];
1164 GraphTraceLen
-= ds
;
1166 RepaintGraphWindow ();
1171 * Manchester demodulate a bitstream. The bitstream needs to be already in
1172 * the GraphBuffer as 0 and 1 values
1174 * Give the clock rate as argument in order to help the sync - the algorithm
1175 * resyncs at each pulse anyway.
1177 * Not optimized by any means, this is the 1st time I'm writing this type of
1178 * routine, feel free to improve...
1180 * 1st argument: clock rate (as number of samples per clock rate)
1181 * Typical values can be 64, 32, 128...
1183 int CmdManchesterDemod ( const char * Cmd
)
1185 int i
, j
, invert
= 0 ;
1191 int hithigh
, hitlow
, first
;
1197 /* check if we're inverting output */
1200 PrintAndLog ( "Inverting output" );
1205 while (* Cmd
== ' ' ); // in case a 2nd argument was given
1208 /* Holds the decoded bitstream: each clock period contains 2 bits */
1209 /* later simplified to 1 bit after manchester decoding. */
1210 /* Add 10 bits to allow for noisy / uncertain traces without aborting */
1211 /* int BitStream[GraphTraceLen*2/clock+10]; */
1213 /* But it does not work if compiling on WIndows: therefore we just allocate a */
1215 uint8_t BitStream
[ MAX_GRAPH_TRACE_LEN
] = { 0 };
1217 /* Detect high and lows */
1218 for ( i
= 0 ; i
< GraphTraceLen
; i
++)
1220 if ( GraphBuffer
[ i
] > high
)
1221 high
= GraphBuffer
[ i
];
1222 else if ( GraphBuffer
[ i
] < low
)
1223 low
= GraphBuffer
[ i
];
1227 clock
= GetClock ( Cmd
, high
, 1 );
1229 int tolerance
= clock
/ 4 ;
1231 /* Detect first transition */
1232 /* Lo-Hi (arbitrary) */
1233 /* skip to the first high */
1234 for ( i
= 0 ; i
< GraphTraceLen
; i
++)
1235 if ( GraphBuffer
[ i
] == high
)
1237 /* now look for the first low */
1238 for (; i
< GraphTraceLen
; i
++)
1240 if ( GraphBuffer
[ i
] == low
)
1247 /* If we're not working with 1/0s, demod based off clock */
1250 bit
= 0 ; /* We assume the 1st bit is zero, it may not be
1251 * the case: this routine (I think) has an init problem.
1254 for (; i
< ( int )( GraphTraceLen
/ clock
); i
++)
1260 /* Find out if we hit both high and low peaks */
1261 for ( j
= 0 ; j
< clock
; j
++)
1263 if ( GraphBuffer
[( i
* clock
) + j
] == high
)
1265 else if ( GraphBuffer
[( i
* clock
) + j
] == low
)
1268 /* it doesn't count if it's the first part of our read
1269 because it's really just trailing from the last sequence */
1270 if ( first
&& ( hithigh
|| hitlow
))
1271 hithigh
= hitlow
= 0 ;
1275 if ( hithigh
&& hitlow
)
1279 /* If we didn't hit both high and low peaks, we had a bit transition */
1280 if (! hithigh
|| ! hitlow
)
1283 BitStream
[ bit2idx
++] = bit
^ invert
;
1287 /* standard 1/0 bitstream */
1291 /* Then detect duration between 2 successive transitions */
1292 for ( bitidx
= 1 ; i
< GraphTraceLen
; i
++)
1294 if ( GraphBuffer
[ i
- 1 ] != GraphBuffer
[ i
])
1299 // Error check: if bitidx becomes too large, we do not
1300 // have a Manchester encoded bitstream or the clock is really
1302 if ( bitidx
> ( GraphTraceLen
* 2 / clock
+ 8 ) ) {
1303 PrintAndLog ( "Error: the clock you gave is probably wrong, aborting." );
1306 // Then switch depending on lc length:
1307 // Tolerance is 1/4 of clock rate (arbitrary)
1308 if ( abs ( lc
- clock
/ 2 ) < tolerance
) {
1309 // Short pulse : either "1" or "0"
1310 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1311 } else if ( abs ( lc
- clock
) < tolerance
) {
1312 // Long pulse: either "11" or "00"
1313 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1314 BitStream
[ bitidx
++]= GraphBuffer
[ i
- 1 ];
1318 PrintAndLog ( "Warning: Manchester decode error for pulse width detection." );
1319 PrintAndLog ( "(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)" );
1323 PrintAndLog ( "Error: too many detection errors, aborting." );
1330 // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
1331 // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
1332 // to stop output at the final bitidx2 value, not bitidx
1333 for ( i
= 0 ; i
< bitidx
; i
+= 2 ) {
1334 if (( BitStream
[ i
] == 0 ) && ( BitStream
[ i
+ 1 ] == 1 )) {
1335 BitStream
[ bit2idx
++] = 1 ^ invert
;
1336 } else if (( BitStream
[ i
] == 1 ) && ( BitStream
[ i
+ 1 ] == 0 )) {
1337 BitStream
[ bit2idx
++] = 0 ^ invert
;
1339 // We cannot end up in this state, this means we are unsynchronized,
1343 PrintAndLog ( "Unsynchronized, resync..." );
1344 PrintAndLog ( "(too many of those messages mean the stream is not Manchester encoded)" );
1348 PrintAndLog ( "Error: too many decode errors, aborting." );
1355 PrintAndLog ( "Manchester decoded bitstream" );
1356 // Now output the bitstream to the scrollback by line of 16 bits
1357 for ( i
= 0 ; i
< ( bit2idx
- 16 ); i
+= 16 ) {
1358 PrintAndLog ( "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i" ,
1379 /* Modulate our data into manchester */
1380 int CmdManchesterMod ( const char * Cmd
)
1384 int bit
, lastbit
, wave
;
1387 clock
= GetClock ( Cmd
, 0 , 1 );
1391 for ( i
= 0 ; i
< ( int )( GraphTraceLen
/ clock
); i
++)
1393 bit
= GraphBuffer
[ i
* clock
] ^ 1 ;
1395 for ( j
= 0 ; j
< ( int )( clock
/ 2 ); j
++)
1396 GraphBuffer
[( i
* clock
) + j
] = bit
^ lastbit
^ wave
;
1397 for ( j
= ( int )( clock
/ 2 ); j
< clock
; j
++)
1398 GraphBuffer
[( i
* clock
) + j
] = bit
^ lastbit
^ wave
^ 1 ;
1400 /* Keep track of how we start our wave and if we changed or not this time */
1401 wave
^= bit
^ lastbit
;
1405 RepaintGraphWindow ();
1409 int CmdNorm ( const char * Cmd
)
1412 int max
= INT_MIN
, min
= INT_MAX
;
1414 for ( i
= 10 ; i
< GraphTraceLen
; ++ i
) {
1415 if ( GraphBuffer
[ i
] > max
)
1416 max
= GraphBuffer
[ i
];
1417 if ( GraphBuffer
[ i
] < min
)
1418 min
= GraphBuffer
[ i
];
1422 for ( i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1423 GraphBuffer
[ i
] = ( GraphBuffer
[ i
] - (( max
+ min
) / 2 )) * 1000 /
1427 RepaintGraphWindow ();
1431 int CmdPlot ( const char * Cmd
)
1437 int CmdSave ( const char * Cmd
)
1439 FILE * f
= fopen ( Cmd
, "w" );
1441 PrintAndLog ( "couldn't open '%s'" , Cmd
);
1445 for ( i
= 0 ; i
< GraphTraceLen
; i
++) {
1446 fprintf ( f
, "%d \n " , GraphBuffer
[ i
]);
1449 PrintAndLog ( "saved to '%s'" , Cmd
);
1453 int CmdScale ( const char * Cmd
)
1455 CursorScaleFactor
= atoi ( Cmd
);
1456 if ( CursorScaleFactor
== 0 ) {
1457 PrintAndLog ( "bad, can't have zero scale" );
1458 CursorScaleFactor
= 1 ;
1460 RepaintGraphWindow ();
1464 int CmdThreshold ( const char * Cmd
)
1466 int threshold
= atoi ( Cmd
);
1468 for ( int i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1469 if ( GraphBuffer
[ i
] >= threshold
)
1472 GraphBuffer
[ i
] = - 1 ;
1474 RepaintGraphWindow ();
1478 int CmdDirectionalThreshold ( const char * Cmd
)
1480 int8_t upThres
= param_get8 ( Cmd
, 0 );
1481 int8_t downThres
= param_get8 ( Cmd
, 1 );
1483 printf ( "Applying Up Threshold: %d, Down Threshold: %d \n " , upThres
, downThres
);
1485 int lastValue
= GraphBuffer
[ 0 ];
1486 GraphBuffer
[ 0 ] = 0 ; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
1488 for ( int i
= 1 ; i
< GraphTraceLen
; ++ i
) {
1489 // Apply first threshold to samples heading up
1490 if ( GraphBuffer
[ i
] >= upThres
&& GraphBuffer
[ i
] > lastValue
)
1492 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1495 // Apply second threshold to samples heading down
1496 else if ( GraphBuffer
[ i
] <= downThres
&& GraphBuffer
[ i
] < lastValue
)
1498 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1499 GraphBuffer
[ i
] = - 1 ;
1503 lastValue
= GraphBuffer
[ i
]; // Buffer last value as we overwrite it.
1504 GraphBuffer
[ i
] = GraphBuffer
[ i
- 1 ];
1508 GraphBuffer
[ 0 ] = GraphBuffer
[ 1 ]; // Aline with first edited sample.
1509 RepaintGraphWindow ();
1513 int CmdZerocrossings ( const char * Cmd
)
1515 // Zero-crossings aren't meaningful unless the signal is zero-mean.
1522 for ( int i
= 0 ; i
< GraphTraceLen
; ++ i
) {
1523 if ( GraphBuffer
[ i
] * sign
>= 0 ) {
1524 // No change in sign, reproduce the previous sample count.
1526 GraphBuffer
[ i
] = lastZc
;
1528 // Change in sign, reset the sample count.
1530 GraphBuffer
[ i
] = lastZc
;
1538 RepaintGraphWindow ();
1542 static command_t CommandTable
[] =
1544 { "help" , CmdHelp
, 1 , "This help" },
1545 { "amp" , CmdAmp
, 1 , "Amplify peaks" },
1546 { "askdemod" , Cmdaskdemod
, 1 , "<0 or 1> -- Attempt to demodulate simple ASK tags" },
1547 { "askmandemod" , Cmdaskmandemod
, 1 , "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])" },
1548 { "autocorr" , CmdAutoCorr
, 1 , "<window length> -- Autocorrelation over window" },
1549 { "bitsamples" , CmdBitsamples
, 0 , "Get raw samples as bitstring" },
1550 { "bitstream" , CmdBitstream
, 1 , "[clock rate] -- Convert waveform into a bitstream" },
1551 { "buffclear" , CmdBuffClear
, 1 , "Clear sample buffer and graph window" },
1552 { "dec" , CmdDec
, 1 , "Decimate samples" },
1553 { "detectclock" , CmdDetectClockRate
, 1 , "Detect clock rate" },
1554 { "fskdemod" , CmdFSKdemod
, 1 , "Demodulate graph window as a HID FSK" },
1555 { "fskhiddemod" , CmdFSKdemodHID
, 1 , "Demodulate graph window as a HID FSK using raw" },
1556 { "fskiodemod" , CmdFSKdemodIO
, 1 , "Demodulate graph window as an IO Prox FSK using raw" },
1557 { "fskrawdemod" , CmdFSKrawdemod
, 1 , "[clock rate] [invert] Demodulate graph window from FSK to binary (clock = 64 or 50)(invert = 1 or 0)" },
1558 { "grid" , CmdGrid
, 1 , "<x> <y> -- overlay grid on graph window, use zero value to turn off either" },
1559 { "hexsamples" , CmdHexsamples
, 0 , "<bytes> [<offset>] -- Dump big buffer as hex bytes" },
1560 { "hide" , CmdHide
, 1 , "Hide graph window" },
1561 { "hpf" , CmdHpf
, 1 , "Remove DC offset from trace" },
1562 { "load" , CmdLoad
, 1 , "<filename> -- Load trace (to graph window" },
1563 { "ltrim" , CmdLtrim
, 1 , "<samples> -- Trim samples from left of trace" },
1564 { "mandemod" , CmdManchesterDemod
, 1 , "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)" },
1565 { "manmod" , CmdManchesterMod
, 1 , "[clock rate] -- Manchester modulate a binary stream" },
1566 { "norm" , CmdNorm
, 1 , "Normalize max/min to +/-500" },
1567 { "plot" , CmdPlot
, 1 , "Show graph window (hit 'h' in window for keystroke help)" },
1568 { "samples" , CmdSamples
, 0 , "[512 - 40000] -- Get raw samples for graph window" },
1569 { "tune" , CmdTuneSamples
, 0 , "Get hw tune samples for graph window" },
1570 { "save" , CmdSave
, 1 , "<filename> -- Save trace (from graph window)" },
1571 { "scale" , CmdScale
, 1 , "<int> -- Set cursor display scale" },
1572 { "threshold" , CmdThreshold
, 1 , "<threshold> -- Maximize/minimize every value in the graph window depending on threshold" },
1573 { "zerocrossings" , CmdZerocrossings
, 1 , "Count time between zero-crossings" },
1574 { "dirthreshold" , CmdDirectionalThreshold
, 1 , "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev." },
1575 { NULL
, NULL
, 0 , NULL
}
1578 int CmdData ( const char * Cmd
)
1580 CmdsParse ( CommandTable
, Cmd
);
1584 int CmdHelp ( const char * Cmd
)
1586 CmdsHelp ( CommandTable
);