]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmddata.c
ADD: midnitesnakes desfire, ultralight changes from Unstable branch.
[proxmark3-svn] / client / cmddata.c
CommitLineData
a553f267 1//-----------------------------------------------------------------------------
2// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3//
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
6// the license.
7//-----------------------------------------------------------------------------
8// Data and Graph commands
9//-----------------------------------------------------------------------------
10
7fe9b0b7 11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <limits.h>
902cb3c0 15#include "proxmark3.h"
7fe9b0b7 16#include "data.h"
17#include "ui.h"
18#include "graph.h"
19#include "cmdparser.h"
d51b2eda 20#include "util.h"
7fe9b0b7 21#include "cmdmain.h"
22#include "cmddata.h"
6ff6ade2 23#include "lfdemod.h"
c15d2bdc 24
7fe9b0b7 25static int CmdHelp(const char *Cmd);
26
27int CmdAmp(const char *Cmd)
28{
29 int i, rising, falling;
30 int max = INT_MIN, min = INT_MAX;
31
32 for (i = 10; i < GraphTraceLen; ++i) {
33 if (GraphBuffer[i] > max)
34 max = GraphBuffer[i];
35 if (GraphBuffer[i] < min)
36 min = GraphBuffer[i];
37 }
38
39 if (max != min) {
40 rising = falling= 0;
41 for (i = 0; i < GraphTraceLen; ++i) {
42 if (GraphBuffer[i + 1] < GraphBuffer[i]) {
43 if (rising) {
44 GraphBuffer[i] = max;
45 rising = 0;
46 }
47 falling = 1;
48 }
49 if (GraphBuffer[i + 1] > GraphBuffer[i]) {
50 if (falling) {
51 GraphBuffer[i] = min;
52 falling = 0;
53 }
54 rising= 1;
55 }
56 }
57 }
58 RepaintGraphWindow();
59 return 0;
60}
61
62/*
63 * Generic command to demodulate ASK.
64 *
65 * Argument is convention: positive or negative (High mod means zero
66 * or high mod means one)
67 *
68 * Updates the Graph trace with 0/1 values
69 *
70 * Arguments:
71 * c : 0 or 1
72 */
1b492a97 73 //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock
7fe9b0b7 74int Cmdaskdemod(const char *Cmd)
75{
76 int i;
77 int c, high = 0, low = 0;
78
7fe9b0b7 79 sscanf(Cmd, "%i", &c);
80
6ff6ade2 81 /* Detect high and lows and clock */
82 // (AL - clock???)
7fe9b0b7 83 for (i = 0; i < GraphTraceLen; ++i)
84 {
85 if (GraphBuffer[i] > high)
86 high = GraphBuffer[i];
87 else if (GraphBuffer[i] < low)
88 low = GraphBuffer[i];
89 }
6ff6ade2 90 high=abs(high*.75);
91 low=abs(low*.75);
92 if (c != 0 && c != 1) {
93 PrintAndLog("Invalid argument: %s", Cmd);
94 return 0;
95 }
96 //prime loop
7fe9b0b7 97 if (GraphBuffer[0] > 0) {
98 GraphBuffer[0] = 1-c;
99 } else {
100 GraphBuffer[0] = c;
101 }
102 for (i = 1; i < GraphTraceLen; ++i) {
103 /* Transitions are detected at each peak
104 * Transitions are either:
105 * - we're low: transition if we hit a high
106 * - we're high: transition if we hit a low
107 * (we need to do it this way because some tags keep high or
108 * low for long periods, others just reach the peak and go
109 * down)
110 */
111 if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) {
112 GraphBuffer[i] = 1 - c;
113 } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){
114 GraphBuffer[i] = c;
115 } else {
116 /* No transition */
117 GraphBuffer[i] = GraphBuffer[i - 1];
118 }
119 }
120 RepaintGraphWindow();
121 return 0;
122}
123
6ff6ade2 124void printBitStream(uint8_t BitStream[], uint32_t bitLen){
1b492a97 125 uint32_t i = 0;
126 if (bitLen<16) {
127 PrintAndLog("Too few bits found: %d",bitLen);
128 return;
129 }
130 if (bitLen>512) bitLen=512;
6ff6ade2 131 for (i = 0; i <= (bitLen-16); i+=16) {
1b492a97 132 PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i",
133 BitStream[i],
134 BitStream[i+1],
135 BitStream[i+2],
136 BitStream[i+3],
137 BitStream[i+4],
138 BitStream[i+5],
139 BitStream[i+6],
140 BitStream[i+7],
141 BitStream[i+8],
142 BitStream[i+9],
143 BitStream[i+10],
144 BitStream[i+11],
145 BitStream[i+12],
146 BitStream[i+13],
147 BitStream[i+14],
148 BitStream[i+15]);
149 }
150 return;
151}
6ff6ade2 152void printEM410x(uint64_t id)
1b492a97 153{
6ff6ade2 154 if (id !=0){
1b492a97 155 uint64_t iii=1;
156 uint64_t id2lo=0; //id2hi=0,
6ff6ade2 157 uint32_t ii=0;
158 uint32_t i=0;
1b492a97 159 for (ii=5; ii>0;ii--){
160 for (i=0;i<8;i++){
6ff6ade2 161 id2lo=(id2lo<<1LL)|((id & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8)));
1b492a97 162 }
163 }
164 //output em id
6ff6ade2 165 PrintAndLog("EM TAG ID : %010llx", id);
1b492a97 166 PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
6ff6ade2 167 PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
168 PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
169 PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
170 PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
171 PrintAndLog("DEZ 14/IK2 : %014lld",id);
1b492a97 172 PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
6ff6ade2 173 PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
174 }
175 return;
1b492a97 176}
177
6ff6ade2 178int CmdEm410xDecode(const char *Cmd)
179{
180 uint64_t id=0;
181 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
182 uint32_t i=0;
183 i=getFromGraphBuf(BitStream);
184 id = Em410xDecode(BitStream,i);
185 printEM410x(id);
186 if (id>0) return 1;
187 return 0;
188}
1b492a97 189
190//by marshmellow
191//takes 2 arguments - clock and invert both as integers
6ff6ade2 192//attempts to demodulate ask while decoding manchester
1b492a97 193//prints binary found and saves in graphbuffer for further commands
194int Cmdaskmandemod(const char *Cmd)
195{
6ff6ade2 196 int invert=0;
197 int clk=0;
198 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
199 sscanf(Cmd, "%i %i", &clk, &invert);
1b492a97 200 if (invert != 0 && invert != 1) {
201 PrintAndLog("Invalid argument: %s", Cmd);
202 return 0;
203 }
6ff6ade2 204 uint32_t BitLen = getFromGraphBuf(BitStream);
205
206 int errCnt=0;
207 errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
208 if (errCnt<0){ //if fatal error (or -1)
209 // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
210 return 0;
211 }
212 if (BitLen<16) return 0;
213 PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
214
215 if (errCnt>0){
216 PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
1b492a97 217 }
6ff6ade2 218 PrintAndLog("ASK/Manchester decoded bitstream:");
219 // Now output the bitstream to the scrollback by line of 16 bits
220 printBitStream(BitStream,BitLen);
221 uint64_t lo =0;
222 lo = Em410xDecode(BitStream,BitLen);
223 if (lo>0){
224 //set GraphBuffer for clone or sim command
225 setGraphBuf(BitStream,BitLen);
226 PrintAndLog("EM410x pattern found: ");
227 printEM410x(lo);
228 }
229 if (BitLen>16) return 1;
230 return 0;
231}
232
233//by marshmellow
234//manchester decode
235//stricktly take 10 and 01 and convert to 0 and 1
236int Cmdmandecoderaw(const char *Cmd)
237{
238 int i =0;
239 int errCnt=0;
240 int bitnum=0;
241 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
242 int high = 0, low = 0;
243 for (;i<GraphTraceLen;++i){
244 if (GraphBuffer[i]>high) high=GraphBuffer[i];
245 else if(GraphBuffer[i]<low) low=GraphBuffer[i];
246 BitStream[i]=GraphBuffer[i];
247 }
248 if (high>1 || low <0 ){
249 PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode");
1b492a97 250 return 0;
251 }
6ff6ade2 252 bitnum=i;
253 errCnt=manrawdecode(BitStream,&bitnum);
254 if (errCnt>=20){
255 PrintAndLog("Too many errors: %d",errCnt);
256 return 0;
1b492a97 257 }
6ff6ade2 258 PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
259 printBitStream(BitStream,bitnum);
260 if (errCnt==0){
261 //put back in graphbuffer
1b492a97 262 ClearGraph(0);
263 for (i=0; i < bitnum; ++i){
264 GraphBuffer[i]=BitStream[i];
265 }
266 GraphTraceLen=bitnum;
267 RepaintGraphWindow();
6ff6ade2 268 uint64_t id = 0;
269 id = Em410xDecode(BitStream,i);
270 printEM410x(id);
271 }
272 return 1;
273}
274
275//by marshmellow
276//biphase decode
277//take 01 or 10 = 0 and 11 or 00 = 1
278//takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit
279// since it is not like manchester and doesn't have an incorrect bit pattern we
280// cannot determine if our decode is correct or if it should be shifted by one bit
281// the argument offset allows us to manually shift if the output is incorrect
282// (better would be to demod and decode at the same time so we can distinguish large
283// width waves vs small width waves to help the decode positioning) or askbiphdemod
284int CmdBiphaseDecodeRaw(const char *Cmd)
285{
286 int i = 0;
287 int errCnt=0;
288 int bitnum=0;
289 int offset=0;
290 int high=0, low=0;
291 sscanf(Cmd, "%i", &offset);
292 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
293 //get graphbuffer & high and low
294 for (;i<GraphTraceLen;++i){
295 if(GraphBuffer[i]>high)high=GraphBuffer[i];
296 else if(GraphBuffer[i]<low)low=GraphBuffer[i];
297 BitStream[i]=GraphBuffer[i];
298 }
299 if (high>1 || low <0){
300 PrintAndLog("Error: please raw demod the wave first then decode");
301 return 0;
302}
303 bitnum=i;
304 errCnt=BiphaseRawDecode(BitStream,&bitnum, offset);
305 if (errCnt>=20){
306 PrintAndLog("Too many errors attempting to decode: %d",errCnt);
307 return 0;
308 }
309 PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
310 printBitStream(BitStream,bitnum);
311 PrintAndLog("\nif bitstream does not look right try offset=1");
312 return 1;
313}
314
315
316//by marshmellow
317//takes 2 arguments - clock and invert both as integers
318//attempts to demodulate ask only
319//prints binary found and saves in graphbuffer for further commands
320int Cmdaskrawdemod(const char *Cmd)
321{
322 uint32_t i;
323 int invert=0;
324 int clk=0;
325 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
326 sscanf(Cmd, "%i %i", &clk, &invert);
327 if (invert != 0 && invert != 1) {
328 PrintAndLog("Invalid argument: %s", Cmd);
329 return 0;
330 }
331 int BitLen = getFromGraphBuf(BitStream);
332 int errCnt=0;
333 errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
334 if (errCnt==-1){ //throw away static - allow 1 and -1 (in case of threshold command first)
335 PrintAndLog("no data found");
336 return 0;
337 }
338 if (BitLen<16) return 0;
339 PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
340 //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
341 //move BitStream back to GraphBuffer
342
343 ClearGraph(0);
344 for (i=0; i < BitLen; ++i){
345 GraphBuffer[i]=BitStream[i];
346 }
347 GraphTraceLen=BitLen;
348 RepaintGraphWindow();
349
1b492a97 350 //output
351 if (errCnt>0){
352 PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
353 }
6ff6ade2 354 PrintAndLog("ASK demoded bitstream:");
1b492a97 355 // Now output the bitstream to the scrollback by line of 16 bits
6ff6ade2 356 printBitStream(BitStream,BitLen);
357
358 return 1;
1b492a97 359}
360
7fe9b0b7 361int CmdAutoCorr(const char *Cmd)
362{
363 static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
364
365 int window = atoi(Cmd);
366
367 if (window == 0) {
368 PrintAndLog("needs a window");
369 return 0;
370 }
371 if (window >= GraphTraceLen) {
372 PrintAndLog("window must be smaller than trace (%d samples)",
373 GraphTraceLen);
374 return 0;
375 }
376
377 PrintAndLog("performing %d correlations", GraphTraceLen - window);
378
379 for (int i = 0; i < GraphTraceLen - window; ++i) {
380 int sum = 0;
381 for (int j = 0; j < window; ++j) {
382 sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
383 }
384 CorrelBuffer[i] = sum;
385 }
386 GraphTraceLen = GraphTraceLen - window;
387 memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
388
389 RepaintGraphWindow();
390 return 0;
391}
392
393int CmdBitsamples(const char *Cmd)
394{
395 int cnt = 0;
90d74dc2 396 uint8_t got[12288];
397
398 GetFromBigBuf(got,sizeof(got),0);
399 WaitForResponse(CMD_ACK,NULL);
7fe9b0b7 400
90d74dc2 401 for (int j = 0; j < sizeof(got); j++) {
7fe9b0b7 402 for (int k = 0; k < 8; k++) {
90d74dc2 403 if(got[j] & (1 << (7 - k))) {
7fe9b0b7 404 GraphBuffer[cnt++] = 1;
405 } else {
406 GraphBuffer[cnt++] = 0;
407 }
408 }
7fe9b0b7 409 }
410 GraphTraceLen = cnt;
411 RepaintGraphWindow();
412 return 0;
413}
414
415/*
416 * Convert to a bitstream
417 */
418int CmdBitstream(const char *Cmd)
419{
420 int i, j;
421 int bit;
422 int gtl;
423 int clock;
424 int low = 0;
425 int high = 0;
426 int hithigh, hitlow, first;
427
428 /* Detect high and lows and clock */
429 for (i = 0; i < GraphTraceLen; ++i)
430 {
431 if (GraphBuffer[i] > high)
432 high = GraphBuffer[i];
433 else if (GraphBuffer[i] < low)
434 low = GraphBuffer[i];
435 }
436
437 /* Get our clock */
438 clock = GetClock(Cmd, high, 1);
439 gtl = ClearGraph(0);
440
441 bit = 0;
442 for (i = 0; i < (int)(gtl / clock); ++i)
443 {
444 hithigh = 0;
445 hitlow = 0;
446 first = 1;
447 /* Find out if we hit both high and low peaks */
448 for (j = 0; j < clock; ++j)
449 {
450 if (GraphBuffer[(i * clock) + j] == high)
451 hithigh = 1;
452 else if (GraphBuffer[(i * clock) + j] == low)
453 hitlow = 1;
454 /* it doesn't count if it's the first part of our read
455 because it's really just trailing from the last sequence */
456 if (first && (hithigh || hitlow))
457 hithigh = hitlow = 0;
458 else
459 first = 0;
460
461 if (hithigh && hitlow)
462 break;
463 }
464
465 /* If we didn't hit both high and low peaks, we had a bit transition */
466 if (!hithigh || !hitlow)
467 bit ^= 1;
468
469 AppendGraph(0, clock, bit);
470// for (j = 0; j < (int)(clock/2); j++)
471// GraphBuffer[(i * clock) + j] = bit ^ 1;
472// for (j = (int)(clock/2); j < clock; j++)
473// GraphBuffer[(i * clock) + j] = bit;
474 }
475
476 RepaintGraphWindow();
477 return 0;
478}
479
480int CmdBuffClear(const char *Cmd)
481{
482 UsbCommand c = {CMD_BUFF_CLEAR};
483 SendCommand(&c);
484 ClearGraph(true);
485 return 0;
486}
487
488int CmdDec(const char *Cmd)
489{
490 for (int i = 0; i < (GraphTraceLen / 2); ++i)
491 GraphBuffer[i] = GraphBuffer[i * 2];
492 GraphTraceLen /= 2;
493 PrintAndLog("decimated by 2");
494 RepaintGraphWindow();
495 return 0;
496}
497
498/* Print our clock rate */
6ff6ade2 499// uses data from graphbuffer
7fe9b0b7 500int CmdDetectClockRate(const char *Cmd)
501{
6ff6ade2 502 GetClock("",0,0);
7fe9b0b7 503 return 0;
504}
505
1b492a97 506//by marshmellow
6ff6ade2 507//fsk raw demod and print binary
508//takes 4 arguments - Clock, invert, rchigh, rclow
509//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
1b492a97 510int CmdFSKrawdemod(const char *Cmd)
511{
512 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
513 //set defaults
6ff6ade2 514 int rfLen = 50;
515 int invert=0;
516 int fchigh=10;
517 int fclow=8;
1b492a97 518 //set options from parameters entered with the command
6ff6ade2 519 sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
520
1b492a97 521 if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
6ff6ade2 522 //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
1b492a97 523 if (rfLen==1){
524 invert=1; //if invert option only is used
525 rfLen = 50;
526 } else if(rfLen==0) rfLen=50;
527 }
6ff6ade2 528 PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
529 uint32_t i=0;
530 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
531 uint32_t BitLen = getFromGraphBuf(BitStream);
532 int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
533 if (size>0){
534 PrintAndLog("FSK decoded bitstream:");
535 ClearGraph(0);
536 for (i=0;i<size;++i){
537 GraphBuffer[i]=BitStream[i];
1b492a97 538 }
6ff6ade2 539 GraphTraceLen=size;
540 RepaintGraphWindow();
1b492a97 541
1b492a97 542 // Now output the bitstream to the scrollback by line of 16 bits
6ff6ade2 543 if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
544 printBitStream(BitStream,size);
545 } else{
546 PrintAndLog("no FSK data found");
547 }
1b492a97 548 return 0;
549}
550
6ff6ade2 551//by marshmellow (based on existing demod + holiman's refactor)
552//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
553//print full HID Prox ID and some bit format details if found
1b492a97 554int CmdFSKdemodHID(const char *Cmd)
555{
556 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
1b492a97 557 uint32_t hi2=0, hi=0, lo=0;
558
6ff6ade2 559 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
560 uint32_t BitLen = getFromGraphBuf(BitStream);
1b492a97 561 //get binary from fsk wave
6ff6ade2 562 size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
563 if (size<0){
564 PrintAndLog("Error demoding fsk");
565 return 0;
1b492a97 566 }
6ff6ade2 567 if (hi2==0 && hi==0 && lo==0) return 0;
1b492a97 568 if (hi2 != 0){ //extra large HID tags
569 PrintAndLog("TAG ID: %x%08x%08x (%d)",
570 (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
6ff6ade2 571 setGraphBuf(BitStream,BitLen);
572 return 1;
1b492a97 573 }
574 else { //standard HID tags <38 bits
575 //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
6ff6ade2 576 uint8_t fmtLen = 0;
1b492a97 577 uint32_t fc = 0;
578 uint32_t cardnum = 0;
579 if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
580 uint32_t lo2=0;
581 lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
582 uint8_t idx3 = 1;
583 while(lo2>1){ //find last bit set to 1 (format len bit)
584 lo2=lo2>>1;
585 idx3++;
586 }
6ff6ade2 587 fmtLen =idx3+19;
1b492a97 588 fc =0;
589 cardnum=0;
6ff6ade2 590 if(fmtLen==26){
1b492a97 591 cardnum = (lo>>1)&0xFFFF;
592 fc = (lo>>17)&0xFF;
593 }
6ff6ade2 594 if(fmtLen==37){
1b492a97 595 cardnum = (lo>>1)&0x7FFFF;
596 fc = ((hi&0xF)<<12)|(lo>>20);
597 }
6ff6ade2 598 if(fmtLen==34){
1b492a97 599 cardnum = (lo>>1)&0xFFFF;
600 fc= ((hi&1)<<15)|(lo>>17);
601 }
6ff6ade2 602 if(fmtLen==35){
1b492a97 603 cardnum = (lo>>1)&0xFFFFF;
604 fc = ((hi&1)<<11)|(lo>>21);
605 }
606 }
607 else { //if bit 38 is not set then 37 bit format is used
6ff6ade2 608 fmtLen= 37;
1b492a97 609 fc =0;
610 cardnum=0;
6ff6ade2 611 if(fmtLen==37){
1b492a97 612 cardnum = (lo>>1)&0x7FFFF;
613 fc = ((hi&0xF)<<12)|(lo>>20);
614 }
615 }
1b492a97 616 PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
617 (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
6ff6ade2 618 (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
619 setGraphBuf(BitStream,BitLen);
620 return 1;
1b492a97 621 }
1b492a97 622 return 0;
623}
624
625//by marshmellow
6ff6ade2 626//IO-Prox demod - FSK RF/64 with preamble of 000000001
627//print ioprox ID and some format details
1b492a97 628int CmdFSKdemodIO(const char *Cmd)
629{
630 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
631 //set defaults
6ff6ade2 632 int idx=0;
633 //something in graphbuffer
634 if (GraphTraceLen < 65) return 0;
635 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
636 uint32_t BitLen = getFromGraphBuf(BitStream);
637 //get binary from fsk wave
638 idx = IOdemodFSK(BitStream,BitLen);
639 if (idx<0){
640 //PrintAndLog("Error demoding fsk");
641 return 0;
642 }
643 if (idx==0){
644 //PrintAndLog("IO Prox Data not found - FSK Data:");
645 //if (BitLen > 92) printBitStream(BitStream,92);
646 return 0;
1b492a97 647 }
1b492a97 648 //Index map
649 //0 10 20 30 40 50 60
650 //| | | | | | |
651 //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
652 //-----------------------------------------------------------------------------
653 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
654 //
655 //XSF(version)facility:codeone+codetwo (raw)
656 //Handle the data
6ff6ade2 657 if (idx+64>BitLen) return 0;
658 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]);
659 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]);
660 PrintAndLog("%d%d%d%d%d%d%d%d %d facility",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]);
661 PrintAndLog("%d%d%d%d%d%d%d%d %d version",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]);
662 PrintAndLog("%d%d%d%d%d%d%d%d %d code1",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]);
663 PrintAndLog("%d%d%d%d%d%d%d%d %d code2",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]);
664 PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",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]);
665
666 uint32_t code = bytebits_to_byte(BitStream+idx,32);
667 uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32);
668 uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
669 uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
670 uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
1b492a97 671
6ff6ade2 672 PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
673 setGraphBuf(BitStream,BitLen);
674 return 1;
1b492a97 675}
6ff6ade2 676
1b492a97 677int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
7fe9b0b7 678{
679 static const int LowTone[] = {
680 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
681 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
682 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
683 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
684 1, 1, 1, 1, 1, -1, -1, -1, -1, -1
685 };
686 static const int HighTone[] = {
687 1, 1, 1, 1, 1, -1, -1, -1, -1,
688 1, 1, 1, 1, -1, -1, -1, -1,
689 1, 1, 1, 1, -1, -1, -1, -1,
690 1, 1, 1, 1, -1, -1, -1, -1,
691 1, 1, 1, 1, -1, -1, -1, -1,
692 1, 1, 1, 1, -1, -1, -1, -1, -1,
693 };
694
695 int lowLen = sizeof (LowTone) / sizeof (int);
696 int highLen = sizeof (HighTone) / sizeof (int);
697 int convLen = (highLen > lowLen) ? highLen : lowLen;
698 uint32_t hi = 0, lo = 0;
699
700 int i, j;
701 int minMark = 0, maxMark = 0;
702
703 for (i = 0; i < GraphTraceLen - convLen; ++i) {
704 int lowSum = 0, highSum = 0;
705
706 for (j = 0; j < lowLen; ++j) {
707 lowSum += LowTone[j]*GraphBuffer[i+j];
708 }
709 for (j = 0; j < highLen; ++j) {
710 highSum += HighTone[j] * GraphBuffer[i + j];
711 }
712 lowSum = abs(100 * lowSum / lowLen);
713 highSum = abs(100 * highSum / highLen);
714 GraphBuffer[i] = (highSum << 16) | lowSum;
715 }
716
717 for(i = 0; i < GraphTraceLen - convLen - 16; ++i) {
718 int lowTot = 0, highTot = 0;
719 // 10 and 8 are f_s divided by f_l and f_h, rounded
720 for (j = 0; j < 10; ++j) {
721 lowTot += (GraphBuffer[i+j] & 0xffff);
722 }
723 for (j = 0; j < 8; j++) {
724 highTot += (GraphBuffer[i + j] >> 16);
725 }
726 GraphBuffer[i] = lowTot - highTot;
727 if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i];
728 if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i];
729 }
730
731 GraphTraceLen -= (convLen + 16);
732 RepaintGraphWindow();
733
1b492a97 734 // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
7fe9b0b7 735 int max = 0, maxPos = 0;
736 for (i = 0; i < 6000; ++i) {
737 int dec = 0;
738 for (j = 0; j < 3 * lowLen; ++j) {
739 dec -= GraphBuffer[i + j];
740 }
741 for (; j < 3 * (lowLen + highLen ); ++j) {
742 dec += GraphBuffer[i + j];
743 }
744 if (dec > max) {
745 max = dec;
746 maxPos = i;
747 }
748 }
749
750 // place start of bit sync marker in graph
751 GraphBuffer[maxPos] = maxMark;
752 GraphBuffer[maxPos + 1] = minMark;
753
754 maxPos += j;
755
756 // place end of bit sync marker in graph
757 GraphBuffer[maxPos] = maxMark;
758 GraphBuffer[maxPos+1] = minMark;
759
760 PrintAndLog("actual data bits start at sample %d", maxPos);
761 PrintAndLog("length %d/%d", highLen, lowLen);
762
763 uint8_t bits[46];
764 bits[sizeof(bits)-1] = '\0';
765
766 // find bit pairs and manchester decode them
767 for (i = 0; i < arraylen(bits) - 1; ++i) {
768 int dec = 0;
769 for (j = 0; j < lowLen; ++j) {
770 dec -= GraphBuffer[maxPos + j];
771 }
772 for (; j < lowLen + highLen; ++j) {
773 dec += GraphBuffer[maxPos + j];
774 }
775 maxPos += j;
776 // place inter bit marker in graph
777 GraphBuffer[maxPos] = maxMark;
778 GraphBuffer[maxPos + 1] = minMark;
779
780 // hi and lo form a 64 bit pair
781 hi = (hi << 1) | (lo >> 31);
782 lo = (lo << 1);
783 // store decoded bit as binary (in hi/lo) and text (in bits[])
784 if(dec < 0) {
785 bits[i] = '1';
786 lo |= 1;
787 } else {
788 bits[i] = '0';
789 }
790 }
791 PrintAndLog("bits: '%s'", bits);
792 PrintAndLog("hex: %08x %08x", hi, lo);
793 return 0;
794}
795
796int CmdGrid(const char *Cmd)
797{
798 sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
7ddb9900 799 PlotGridXdefault= PlotGridX;
800 PlotGridYdefault= PlotGridY;
7fe9b0b7 801 RepaintGraphWindow();
802 return 0;
803}
804
805int CmdHexsamples(const char *Cmd)
806{
4961e292 807 int i, j;
7fe9b0b7 808 int requested = 0;
809 int offset = 0;
4961e292 810 char string_buf[25];
811 char* string_ptr = string_buf;
90d74dc2 812 uint8_t got[40000];
4961e292 813
814 sscanf(Cmd, "%i %i", &requested, &offset);
90d74dc2 815
4961e292 816 /* if no args send something */
817 if (requested == 0) {
90d74dc2 818 requested = 8;
819 }
90d74dc2 820 if (offset + requested > sizeof(got)) {
821 PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
4961e292 822 return 0;
823 }
90d74dc2 824
4961e292 825 GetFromBigBuf(got,requested,offset);
90d74dc2 826 WaitForResponse(CMD_ACK,NULL);
827
4961e292 828 i = 0;
829 for (j = 0; j < requested; j++) {
830 i++;
831 string_ptr += sprintf(string_ptr, "%02x ", got[j]);
832 if (i == 8) {
833 *(string_ptr - 1) = '\0'; // remove the trailing space
834 PrintAndLog("%s", string_buf);
835 string_buf[0] = '\0';
836 string_ptr = string_buf;
837 i = 0;
838 }
839 if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
840 *(string_ptr - 1) = '\0';
841 PrintAndLog("%s", string_buf);
842 string_buf[0] = '\0';
843 }
7fe9b0b7 844 }
845 return 0;
846}
847
7fe9b0b7 848int CmdHide(const char *Cmd)
849{
850 HideGraphWindow();
851 return 0;
852}
853
854int CmdHpf(const char *Cmd)
855{
856 int i;
857 int accum = 0;
858
859 for (i = 10; i < GraphTraceLen; ++i)
860 accum += GraphBuffer[i];
861 accum /= (GraphTraceLen - 10);
862 for (i = 0; i < GraphTraceLen; ++i)
863 GraphBuffer[i] -= accum;
864
865 RepaintGraphWindow();
866 return 0;
867}
868
8d183c53 869int CmdSamples(const char *Cmd)
7fe9b0b7 870{
081151ea 871 uint8_t got[36440] = {0x00};
872
873 int n = strtol(Cmd, NULL, 0);
874 if (n == 0)
6ff6ade2 875 n = 20000;
081151ea 876 if (n > sizeof(got))
877 n = sizeof(got);
a2847518 878
081151ea 879 PrintAndLog("Reading %d samples from device memory\n", n);
880 GetFromBigBuf(got,n,3560);
881 WaitForResponse(CMD_ACK,NULL);
882 for (int j = 0; j < n; ++j) {
883 GraphBuffer[j] = ((int)got[j]) - 128;
884 }
885 GraphTraceLen = n;
886 RepaintGraphWindow();
887 return 0;
7fe9b0b7 888}
6ff6ade2 889
02306bac 890int CmdTuneSamples(const char *Cmd)
891{
d3499d36 892 int timeout = 0;
893 printf("\nMeasuring antenna characteristics, please wait...");
894
895 UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
896 SendCommand(&c);
897
898 UsbCommand resp;
899 while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
900 timeout++;
901 printf(".");
902 if (timeout > 7) {
903 PrintAndLog("\nNo response from Proxmark. Aborting...");
904 return 1;
905 }
906 }
02306bac 907
d3499d36 908 int peakv, peakf;
909 int vLf125, vLf134, vHf;
910 vLf125 = resp.arg[0] & 0xffff;
911 vLf134 = resp.arg[0] >> 16;
912 vHf = resp.arg[1] & 0xffff;;
913 peakf = resp.arg[2] & 0xffff;
914 peakv = resp.arg[2] >> 16;
915 PrintAndLog("");
916 PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);
917 PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);
918 PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
919 PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);
920 if (peakv<2000)
921 PrintAndLog("# Your LF antenna is unusable.");
922 else if (peakv<10000)
923 PrintAndLog("# Your LF antenna is marginal.");
924 if (vHf<2000)
925 PrintAndLog("# Your HF antenna is unusable.");
926 else if (vHf<5000)
927 PrintAndLog("# Your HF antenna is marginal.");
928
929 for (int i = 0; i < 256; i++) {
930 GraphBuffer[i] = resp.d.asBytes[i] - 128;
931 }
02306bac 932
d3499d36 933 PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
934 PrintAndLog("\n");
935 GraphTraceLen = 256;
936 ShowGraphWindow();
937
02306bac 938 return 0;
939}
940
7fe9b0b7 941int CmdLoad(const char *Cmd)
942{
463ca973 943 char filename[FILE_PATH_SIZE] = {0x00};
944 int len = 0;
945
946 len = strlen(Cmd);
947 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
948 memcpy(filename, Cmd, len);
949
950 FILE *f = fopen(filename, "r");
951 if (!f) {
952 PrintAndLog("couldn't open '%s'", filename);
953 return 0;
954 }
7fe9b0b7 955
956 GraphTraceLen = 0;
957 char line[80];
958 while (fgets(line, sizeof (line), f)) {
959 GraphBuffer[GraphTraceLen] = atoi(line);
960 GraphTraceLen++;
961 }
962 fclose(f);
963 PrintAndLog("loaded %d samples", GraphTraceLen);
964 RepaintGraphWindow();
965 return 0;
966}
967
968int CmdLtrim(const char *Cmd)
969{
970 int ds = atoi(Cmd);
971
972 for (int i = ds; i < GraphTraceLen; ++i)
973 GraphBuffer[i-ds] = GraphBuffer[i];
974 GraphTraceLen -= ds;
975
976 RepaintGraphWindow();
977 return 0;
978}
979
980/*
981 * Manchester demodulate a bitstream. The bitstream needs to be already in
982 * the GraphBuffer as 0 and 1 values
983 *
984 * Give the clock rate as argument in order to help the sync - the algorithm
985 * resyncs at each pulse anyway.
986 *
987 * Not optimized by any means, this is the 1st time I'm writing this type of
988 * routine, feel free to improve...
989 *
990 * 1st argument: clock rate (as number of samples per clock rate)
991 * Typical values can be 64, 32, 128...
992 */
993int CmdManchesterDemod(const char *Cmd)
994{
995 int i, j, invert= 0;
996 int bit;
997 int clock;
fddf220a 998 int lastval = 0;
7fe9b0b7 999 int low = 0;
1000 int high = 0;
1001 int hithigh, hitlow, first;
1002 int lc = 0;
1003 int bitidx = 0;
1004 int bit2idx = 0;
1005 int warnings = 0;
1006
1007 /* check if we're inverting output */
c6f1fb9d 1008 if (*Cmd == 'i')
7fe9b0b7 1009 {
1010 PrintAndLog("Inverting output");
1011 invert = 1;
fffad860 1012 ++Cmd;
7fe9b0b7 1013 do
1014 ++Cmd;
1015 while(*Cmd == ' '); // in case a 2nd argument was given
1016 }
1017
1018 /* Holds the decoded bitstream: each clock period contains 2 bits */
1019 /* later simplified to 1 bit after manchester decoding. */
1020 /* Add 10 bits to allow for noisy / uncertain traces without aborting */
1021 /* int BitStream[GraphTraceLen*2/clock+10]; */
1022
1023 /* But it does not work if compiling on WIndows: therefore we just allocate a */
1024 /* large array */
a61b4976 1025 uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00};
7fe9b0b7 1026
1027 /* Detect high and lows */
1028 for (i = 0; i < GraphTraceLen; i++)
1029 {
1030 if (GraphBuffer[i] > high)
1031 high = GraphBuffer[i];
1032 else if (GraphBuffer[i] < low)
1033 low = GraphBuffer[i];
1034 }
1035
1036 /* Get our clock */
a61b4976 1037 clock = GetClock(Cmd, high, 1);
7fe9b0b7 1038 int tolerance = clock/4;
1039
1040 /* Detect first transition */
1041 /* Lo-Hi (arbitrary) */
1042 /* skip to the first high */
1043 for (i= 0; i < GraphTraceLen; i++)
1044 if (GraphBuffer[i] == high)
1045 break;
1046 /* now look for the first low */
1047 for (; i < GraphTraceLen; i++)
1048 {
1049 if (GraphBuffer[i] == low)
1050 {
1051 lastval = i;
1052 break;
1053 }
1054 }
b44e5233 1055
7fe9b0b7 1056 /* If we're not working with 1/0s, demod based off clock */
1057 if (high != 1)
1058 {
1059 bit = 0; /* We assume the 1st bit is zero, it may not be
1060 * the case: this routine (I think) has an init problem.
1061 * Ed.
b44e5233 1062 */
7fe9b0b7 1063 for (; i < (int)(GraphTraceLen / clock); i++)
1064 {
1065 hithigh = 0;
1066 hitlow = 0;
1067 first = 1;
1068
1069 /* Find out if we hit both high and low peaks */
1070 for (j = 0; j < clock; j++)
1071 {
1072 if (GraphBuffer[(i * clock) + j] == high)
1073 hithigh = 1;
1074 else if (GraphBuffer[(i * clock) + j] == low)
1075 hitlow = 1;
1076
1077 /* it doesn't count if it's the first part of our read
1078 because it's really just trailing from the last sequence */
1079 if (first && (hithigh || hitlow))
1080 hithigh = hitlow = 0;
1081 else
1082 first = 0;
1083
1084 if (hithigh && hitlow)
1085 break;
1086 }
1087
1088 /* If we didn't hit both high and low peaks, we had a bit transition */
1089 if (!hithigh || !hitlow)
1090 bit ^= 1;
1091
1092 BitStream[bit2idx++] = bit ^ invert;
1093 }
1094 }
1095
1096 /* standard 1/0 bitstream */
1097 else
1098 {
1099
1100 /* Then detect duration between 2 successive transitions */
1101 for (bitidx = 1; i < GraphTraceLen; i++)
1102 {
1103 if (GraphBuffer[i-1] != GraphBuffer[i])
1104 {
1105 lc = i-lastval;
1106 lastval = i;
1107
1108 // Error check: if bitidx becomes too large, we do not
1109 // have a Manchester encoded bitstream or the clock is really
1110 // wrong!
1111 if (bitidx > (GraphTraceLen*2/clock+8) ) {
1112 PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
1113 return 0;
1114 }
1115 // Then switch depending on lc length:
1116 // Tolerance is 1/4 of clock rate (arbitrary)
1117 if (abs(lc-clock/2) < tolerance) {
1118 // Short pulse : either "1" or "0"
1119 BitStream[bitidx++]=GraphBuffer[i-1];
1120 } else if (abs(lc-clock) < tolerance) {
1121 // Long pulse: either "11" or "00"
1122 BitStream[bitidx++]=GraphBuffer[i-1];
1123 BitStream[bitidx++]=GraphBuffer[i-1];
1124 } else {
1125 // Error
1126 warnings++;
1127 PrintAndLog("Warning: Manchester decode error for pulse width detection.");
1128 PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");
1129
1130 if (warnings > 10)
1131 {
1132 PrintAndLog("Error: too many detection errors, aborting.");
1133 return 0;
1134 }
1135 }
1136 }
1137 }
1138
1139 // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
1140 // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
1141 // to stop output at the final bitidx2 value, not bitidx
c15d2bdc 1142
1143 //http://www.proxmark.org/forum/viewtopic.php?id=403
1144 for (i = 1; i < bitidx; i += 2) {
7fe9b0b7 1145 if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
1146 BitStream[bit2idx++] = 1 ^ invert;
1147 } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
1148 BitStream[bit2idx++] = 0 ^ invert;
1149 } else {
1150 // We cannot end up in this state, this means we are unsynchronized,
1151 // move up 1 bit:
1152 i++;
081151ea 1153 warnings++;
7fe9b0b7 1154 PrintAndLog("Unsynchronized, resync...");
1155 PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
1156
1157 if (warnings > 10)
1158 {
1159 PrintAndLog("Error: too many decode errors, aborting.");
1160 return 0;
1161 }
1162 }
1163 }
1164 }
1165
1166 PrintAndLog("Manchester decoded bitstream");
1167 // Now output the bitstream to the scrollback by line of 16 bits
1168 for (i = 0; i < (bit2idx-16); i+=16) {
1169 PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
1170 BitStream[i],
1171 BitStream[i+1],
1172 BitStream[i+2],
1173 BitStream[i+3],
1174 BitStream[i+4],
1175 BitStream[i+5],
1176 BitStream[i+6],
1177 BitStream[i+7],
1178 BitStream[i+8],
1179 BitStream[i+9],
1180 BitStream[i+10],
1181 BitStream[i+11],
1182 BitStream[i+12],
1183 BitStream[i+13],
1184 BitStream[i+14],
1185 BitStream[i+15]);
1186 }
c15d2bdc 1187 return bit2idx;
7fe9b0b7 1188}
1189
1190/* Modulate our data into manchester */
1191int CmdManchesterMod(const char *Cmd)
1192{
1193 int i, j;
7fe9b0b7 1194 int bit, lastbit, wave;
a61b4976 1195 int clock = GetClock(Cmd, 0, 1);
1196 int clock1 = GetT55x7Clock( GraphBuffer, GraphTraceLen, 0 );
1197 PrintAndLog("MAN MOD CLOCKS: %d ice %d", clock,clock1);
1198
1199 int half = (int)(clock/2);
1200
7fe9b0b7 1201 wave = 0;
1202 lastbit = 1;
1203 for (i = 0; i < (int)(GraphTraceLen / clock); i++)
1204 {
1205 bit = GraphBuffer[i * clock] ^ 1;
1206
a61b4976 1207 for (j = 0; j < half; ++j)
7fe9b0b7 1208 GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
a61b4976 1209 for (j = half; j < clock; ++j)
7fe9b0b7 1210 GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
1211
1212 /* Keep track of how we start our wave and if we changed or not this time */
1213 wave ^= bit ^ lastbit;
1214 lastbit = bit;
1215 }
1216
1217 RepaintGraphWindow();
1218 return 0;
1219}
1220
1221int CmdNorm(const char *Cmd)
1222{
1223 int i;
1224 int max = INT_MIN, min = INT_MAX;
1225
1226 for (i = 10; i < GraphTraceLen; ++i) {
1227 if (GraphBuffer[i] > max)
1228 max = GraphBuffer[i];
1229 if (GraphBuffer[i] < min)
1230 min = GraphBuffer[i];
1231 }
1232
1233 if (max != min) {
1234 for (i = 0; i < GraphTraceLen; ++i) {
1235 GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 1000 /
1236 (max - min);
1237 }
1238 }
1239 RepaintGraphWindow();
1240 return 0;
1241}
1242
1243int CmdPlot(const char *Cmd)
1244{
1245 ShowGraphWindow();
1246 return 0;
1247}
1248
1249int CmdSave(const char *Cmd)
1250{
463ca973 1251 char filename[FILE_PATH_SIZE] = {0x00};
1252 int len = 0;
1253
1254 len = strlen(Cmd);
1255 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
1256 memcpy(filename, Cmd, len);
1257
1258
1259 FILE *f = fopen(filename, "w");
7fe9b0b7 1260 if(!f) {
463ca973 1261 PrintAndLog("couldn't open '%s'", filename);
7fe9b0b7 1262 return 0;
1263 }
1264 int i;
1265 for (i = 0; i < GraphTraceLen; i++) {
1266 fprintf(f, "%d\n", GraphBuffer[i]);
1267 }
1268 fclose(f);
1269 PrintAndLog("saved to '%s'", Cmd);
1270 return 0;
1271}
1272
1273int CmdScale(const char *Cmd)
1274{
1275 CursorScaleFactor = atoi(Cmd);
1276 if (CursorScaleFactor == 0) {
1277 PrintAndLog("bad, can't have zero scale");
1278 CursorScaleFactor = 1;
1279 }
1280 RepaintGraphWindow();
1281 return 0;
1282}
1283
1284int CmdThreshold(const char *Cmd)
1285{
1286 int threshold = atoi(Cmd);
1287
1288 for (int i = 0; i < GraphTraceLen; ++i) {
1289 if (GraphBuffer[i] >= threshold)
1290 GraphBuffer[i] = 1;
1291 else
7bb9d33e 1292 GraphBuffer[i] = -1;
7fe9b0b7 1293 }
1294 RepaintGraphWindow();
1295 return 0;
1296}
1297
d51b2eda
MHS
1298int CmdDirectionalThreshold(const char *Cmd)
1299{
1300 int8_t upThres = param_get8(Cmd, 0);
1301 int8_t downThres = param_get8(Cmd, 1);
1302
1303 printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
1304
1305 int lastValue = GraphBuffer[0];
1306 GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
1307
1308 for (int i = 1; i < GraphTraceLen; ++i) {
1309 // Apply first threshold to samples heading up
1310 if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
1311 {
1312 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1313 GraphBuffer[i] = 1;
1314 }
1315 // Apply second threshold to samples heading down
1316 else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
1317 {
1318 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1319 GraphBuffer[i] = -1;
1320 }
1321 else
1322 {
1323 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1324 GraphBuffer[i] = GraphBuffer[i-1];
1325
1326 }
1327 }
1328 GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
1329 RepaintGraphWindow();
1330 return 0;
1331}
1332
7fe9b0b7 1333int CmdZerocrossings(const char *Cmd)
1334{
1335 // Zero-crossings aren't meaningful unless the signal is zero-mean.
1336 CmdHpf("");
1337
1338 int sign = 1;
1339 int zc = 0;
1340 int lastZc = 0;
1341
1342 for (int i = 0; i < GraphTraceLen; ++i) {
1343 if (GraphBuffer[i] * sign >= 0) {
1344 // No change in sign, reproduce the previous sample count.
1345 zc++;
1346 GraphBuffer[i] = lastZc;
1347 } else {
1348 // Change in sign, reset the sample count.
1349 sign = -sign;
1350 GraphBuffer[i] = lastZc;
1351 if (sign > 0) {
1352 lastZc = zc;
1353 zc = 0;
1354 }
1355 }
1356 }
1357
1358 RepaintGraphWindow();
1359 return 0;
1360}
1361
1362static command_t CommandTable[] =
1363{
1364 {"help", CmdHelp, 1, "This help"},
1365 {"amp", CmdAmp, 1, "Amplify peaks"},
6ff6ade2 1366 {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
1b492a97 1367 {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
6ff6ade2 1368 {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
7fe9b0b7 1369 {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
6ff6ade2 1370 {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
7fe9b0b7 1371 {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
1372 {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
1373 {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
1374 {"dec", CmdDec, 1, "Decimate samples"},
6ff6ade2 1375 {"detectaskclock",CmdDetectClockRate, 1, "Detect ASK clock rate"},
02306bac 1376 {"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
7fe9b0b7 1377 {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
1b492a97 1378 {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
1379 {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
1380 {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] Demodulate graph window from FSK to binary (clock = 64 or 50)(invert = 1 or 0)"},
7fe9b0b7 1381 {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
90d74dc2 1382 {"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
7fe9b0b7 1383 {"hide", CmdHide, 1, "Hide graph window"},
1384 {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
7fe9b0b7 1385 {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
1386 {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
1387 {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
6ff6ade2 1388 {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"},
7fe9b0b7 1389 {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
1390 {"norm", CmdNorm, 1, "Normalize max/min to +/-500"},
7ddb9900 1391 {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
90d74dc2 1392 {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
7fe9b0b7 1393 {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
1394 {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
dbf444a1 1395 {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
02306bac 1396 {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
7fe9b0b7 1397 {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
1398 {NULL, NULL, 0, NULL}
1399};
1400
1401int CmdData(const char *Cmd)
1402{
1403 CmdsParse(CommandTable, Cmd);
1404 return 0;
1405}
1406
1407int CmdHelp(const char *Cmd)
1408{
1409 CmdsHelp(CommandTable);
1410 return 0;
1411}
Impressum, Datenschutz