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 uint8_t manchester_decode(const uint8_t * data
, const size_t len
, uint8_t * dataout
){
97 size_t bytelength
= len
;
99 uint8_t bitStream
[bytelength
];
100 memset(bitStream
, 0x00, bytelength
);
102 int clock
,high
, low
, bit
, hithigh
, hitlow
, first
, bit2idx
, lastpeak
;
103 int i
,invert
, lastval
;
108 low
= bit
= bit2idx
= lastpeak
= invert
= lastval
= hithigh
= hitlow
= first
= 0;
111 /* Detect high and lows */
112 for (i
= 0; i
< bytelength
; i
++) {
115 else if (data
[i
] < low
)
121 for (i
= 1; i
< bytelength
; i
++) {
122 /* if this is the beginning of a peak */
124 if ( data
[j
] != data
[i
] &&
127 /* find lowest difference between peaks */
128 if (lastpeak
&& i
- lastpeak
< clock
)
129 clock
= i
- lastpeak
;
134 int tolerance
= clock
/4;
135 PrintAndLog(" Detected clock: %d",clock
);
137 /* Detect first transition */
138 /* Lo-Hi (arbitrary) */
139 /* skip to the first high */
140 for (i
= 0; i
< bytelength
; i
++)
144 /* now look for the first low */
145 for (; i
< bytelength
; i
++) {
146 if (data
[i
] == low
) {
152 /* If we're not working with 1/0s, demod based off clock */
155 bit
= 0; /* We assume the 1st bit is zero, it may not be
156 * the case: this routine (I think) has an init problem.
159 for (; i
< (int)(bytelength
/ clock
); i
++)
165 /* Find out if we hit both high and low peaks */
166 for (j
= 0; j
< clock
; j
++)
168 if (data
[(i
* clock
) + j
] == high
)
170 else if (data
[(i
* clock
) + j
] == low
)
173 /* it doesn't count if it's the first part of our read
174 because it's really just trailing from the last sequence */
175 if (first
&& (hithigh
|| hitlow
))
176 hithigh
= hitlow
= 0;
180 if (hithigh
&& hitlow
)
184 /* If we didn't hit both high and low peaks, we had a bit transition */
185 if (!hithigh
|| !hitlow
)
188 bitStream
[bit2idx
++] = bit
^ invert
;
191 /* standard 1/0 bitstream */
193 /* Then detect duration between 2 successive transitions */
194 for (bitidx
= 1; i
< bytelength
; i
++) {
196 if (data
[i
-1] != data
[i
]) {
200 // Error check: if bitidx becomes too large, we do not
201 // have a Manchester encoded bitstream or the clock is really
203 if (bitidx
> (bytelength
*2/clock
+8) ) {
204 PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
207 // Then switch depending on lc length:
208 // Tolerance is 1/4 of clock rate (arbitrary)
209 if (abs(lc
-clock
/2) < tolerance
) {
210 // Short pulse : either "1" or "0"
211 bitStream
[bitidx
++] = data
[i
-1];
212 } else if (abs(lc
-clock
) < tolerance
) {
213 // Long pulse: either "11" or "00"
214 bitStream
[bitidx
++] = data
[i
-1];
215 bitStream
[bitidx
++] = data
[i
-1];
219 PrintAndLog("Warning: Manchester decode error for pulse width detection.");
221 PrintAndLog("Error: too many detection errors, aborting.");
228 // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
229 // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
230 // to stop output at the final bitidx2 value, not bitidx
231 for (i
= 0; i
< bitidx
; i
+= 2) {
232 if ((bitStream
[i
] == 0) && (bitStream
[i
+1] == 1)) {
233 bitStream
[bit2idx
++] = 1 ^ invert
;
235 else if ((bitStream
[i
] == 1) && (bitStream
[i
+1] == 0)) {
236 bitStream
[bit2idx
++] = 0 ^ invert
;
239 // We cannot end up in this state, this means we are unsynchronized,
243 PrintAndLog("Unsynchronized, resync...");
245 PrintAndLog("Error: too many decode errors, aborting.");
251 // PrintAndLog(" Manchester decoded bitstream : %d bits", (bit2idx-16));
252 // uint8_t mod = (bit2idx-16) % blocksize;
253 // uint8_t div = (bit2idx-16) / blocksize;
255 // // Now output the bitstream to the scrollback by line of 16 bits
256 // for (i = 0; i < div*blocksize; i+=blocksize) {
257 // PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) );
260 // PrintAndLog(" %s", sprint_bin(bitStream+i, mod) );
264 memcpy(dataout
, bitStream
, bit2idx
);
270 void PrintPaddedManchester( uint8_t* bitStream
, size_t len
, size_t blocksize
){
272 PrintAndLog(" Manchester decoded bitstream : %d bits", len
);
274 uint8_t mod
= len
% blocksize
;
275 uint8_t div
= len
/ blocksize
;
277 // Now output the bitstream to the scrollback by line of 16 bits
278 for (i
= 0; i
< div
*blocksize
; i
+=blocksize
) {
279 PrintAndLog(" %s", sprint_bin(bitStream
+i
,blocksize
) );
282 PrintAndLog(" %s", sprint_bin(bitStream
+i
, mod
) );