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 //-----------------------------------------------------------------------------
16 #include <readline/readline.h>
21 double CursorScaleFactor
;
22 int PlotGridX
, PlotGridY
, PlotGridXdefault
= 64, PlotGridYdefault
= 64;
24 int flushAfterWrite
= 0; //buzzy
25 extern pthread_mutex_t print_lock
;
27 static char *logfilename
= "proxmark3.log";
29 void PrintAndLog(char *fmt
, ...)
33 va_list argptr
, argptr2
;
34 static FILE *logfile
= NULL
;
37 // lock this section to avoid interlacing prints from different threats
38 pthread_mutex_lock(&print_lock
);
40 if (logging
&& !logfile
) {
41 logfile
=fopen(logfilename
, "a");
43 fprintf(stderr
, "Can't open logfile, logging disabled!\n");
48 int need_hack
= (rl_readline_state
& RL_STATE_READCMD
) > 0;
51 saved_point
= rl_point
;
52 saved_line
= rl_copy_text(0, rl_end
);
54 rl_replace_line("", 0);
58 va_start(argptr
, fmt
);
59 va_copy(argptr2
, argptr
);
61 printf(" "); // cleaning prompt
67 rl_replace_line(saved_line
, 0);
68 rl_point
= saved_point
;
73 if (logging
&& logfile
) {
74 vfprintf(logfile
, fmt
, argptr2
);
75 fprintf(logfile
,"\n");
80 if (flushAfterWrite
== 1) //buzzy
85 pthread_mutex_unlock(&print_lock
);
89 void SetLogFilename(char *fn
)
95 int manchester_decode(const int * data
, const size_t len
, uint8_t * dataout
){
98 int i
, clock
, high
, low
, startindex
;
101 uint8_t bitStream
[len
];
103 memset(bitStream
, 0x00, len
);
105 /* Detect high and lows */
106 for (i
= 0; i
< len
; i
++) {
109 else if (data
[i
] < low
)
114 clock
= GetT55x7Clock( data
, len
, high
);
115 startindex
= DetectFirstTransition(data
, len
, high
, low
);
117 PrintAndLog(" Clock : %d", clock
);
118 PrintAndLog(" startindex : %d", startindex
);
121 bitlength
= ManchesterConvertFrom255(data
, len
, bitStream
, high
, low
, clock
, startindex
);
123 bitlength
= ManchesterConvertFrom1(data
, len
, bitStream
, clock
, startindex
);
125 if ( bitlength
> 0 ){
126 PrintPaddedManchester(bitStream
, bitlength
, clock
);
129 memcpy(dataout
, bitStream
, bitlength
);
135 int GetT55x7Clock( const int * data
, const size_t len
, int peak
){
137 int i
,lastpeak
,clock
;
141 /* Detect peak if we don't have one */
143 for (i
= 0; i
< len
; ++i
) {
144 if (data
[i
] > peak
) {
150 for (i
= 1; i
< len
; ++i
) {
151 /* if this is the beginning of a peak */
152 if ( data
[i
-1] != data
[i
] && data
[i
] == peak
) {
153 /* find lowest difference between peaks */
154 if (lastpeak
&& i
- lastpeak
< clock
)
155 clock
= i
- lastpeak
;
160 //defaults clock to precise values.
177 int DetectFirstTransition(const int * data
, const size_t len
, int high
, int low
){
182 Detect first transition Lo-Hi (arbitrary)
183 skip to the first high
185 for (i
= 0; i
< len
; ++i
)
189 /* now look for the first low */
190 for (; i
< len
; ++i
) {
191 if (data
[i
] == low
) {
199 int ManchesterConvertFrom255(const int * data
, const size_t len
, uint8_t * dataout
, int high
, int low
, int clock
, int startIndex
){
201 int i
, j
, hithigh
, hitlow
, first
, bit
, bitIndex
;
206 * We assume the 1st bit is zero, it may not be
207 * the case: this routine (I think) has an init problem.
212 for (; i
< (int)(len
/ clock
); i
++)
218 /* Find out if we hit both high and low peaks */
219 for (j
= 0; j
< clock
; j
++)
221 if (data
[(i
* clock
) + j
] == high
)
223 else if (data
[(i
* clock
) + j
] == low
)
226 /* it doesn't count if it's the first part of our read
227 because it's really just trailing from the last sequence */
228 if (first
&& (hithigh
|| hitlow
))
229 hithigh
= hitlow
= 0;
233 if (hithigh
&& hitlow
)
237 /* If we didn't hit both high and low peaks, we had a bit transition */
238 if (!hithigh
|| !hitlow
)
241 dataout
[bitIndex
++] = bit
;
246 int ManchesterConvertFrom1(const int * data
, const size_t len
, uint8_t * dataout
, int clock
, int startIndex
){
248 int i
,j
, bitindex
, lc
, tolerance
, warnings
;
250 int upperlimit
= len
*2/clock
+8;
254 uint8_t decodedArr
[len
];
256 /* Then detect duration between 2 successive transitions */
257 for (bitindex
= 1; i
< len
; i
++) {
259 if (data
[i
-1] != data
[i
]) {
263 // Error check: if bitindex becomes too large, we do not
264 // have a Manchester encoded bitstream or the clock is really wrong!
265 if (bitindex
> upperlimit
) {
266 PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
269 // Then switch depending on lc length:
270 // Tolerance is 1/4 of clock rate (arbitrary)
271 if (abs((lc
-clock
)/2) < tolerance
) {
272 // Short pulse : either "1" or "0"
273 decodedArr
[bitindex
++] = data
[i
-1];
274 } else if (abs(lc
-clock
) < tolerance
) {
275 // Long pulse: either "11" or "00"
276 decodedArr
[bitindex
++] = data
[i
-1];
277 decodedArr
[bitindex
++] = data
[i
-1];
280 PrintAndLog("Warning: Manchester decode error for pulse width detection.");
282 PrintAndLog("Error: too many detection errors, aborting.");
290 * We have a decodedArr of "01" ("1") or "10" ("0")
291 * parse it into final decoded dataout
293 for (i
= 0; i
< bitindex
; i
+= 2) {
295 if ((decodedArr
[i
] == 0) && (decodedArr
[i
+1] == 1)) {
297 } else if ((decodedArr
[i
] == 1) && (decodedArr
[i
+1] == 0)) {
302 PrintAndLog("Unsynchronized, resync...");
303 PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
306 PrintAndLog("Error: too many decode errors, aborting.");
312 PrintAndLog("%s", sprint_hex(dataout
, j
));
316 void ManchesterDiffDecodedString(const uint8_t* bitstream
, size_t len
, uint8_t invert
){
318 * We have a bitstream of "01" ("1") or "10" ("0")
319 * parse it into final decoded bitstream
322 uint8_t decodedArr
[(len
/2)+1];
328 for (i
= 0; i
< len
; i
+= 2) {
330 uint8_t first
= bitstream
[i
];
331 uint8_t second
= bitstream
[i
+1];
333 if ( first
== second
) {
337 PrintAndLog("Error: too many decode errors, aborting.");
341 else if ( lastbit
!= first
) {
342 decodedArr
[j
++] = 0 ^ invert
;
345 decodedArr
[j
++] = 1 ^ invert
;
350 PrintAndLog("%s", sprint_hex(decodedArr
, j
));
354 void PrintPaddedManchester( uint8_t* bitStream
, size_t len
, size_t blocksize
){
356 PrintAndLog(" Manchester decoded bitstream : %d bits", len
);
358 uint8_t mod
= len
% blocksize
;
359 uint8_t div
= len
/ blocksize
;
361 // Now output the bitstream to the scrollback by line of 16 bits
362 for (i
= 0; i
< div
*blocksize
; i
+=blocksize
) {
363 PrintAndLog(" %s", sprint_bin(bitStream
+i
,blocksize
) );
366 PrintAndLog(" %s", sprint_bin(bitStream
+i
, mod
) );