]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmddata.c
Merge pull request #1 from bforbort/master
[proxmark3-svn] / client / cmddata.c
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
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include "proxmark3.h"
16 #include "data.h"
17 #include "ui.h"
18 #include "graph.h"
19 #include "cmdparser.h"
20 #include "util.h"
21 #include "cmdmain.h"
22 #include "cmddata.h"
23 #include "lfdemod.h"
24
25 static int CmdHelp(const char *Cmd);
26
27 int 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 */
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
74 int Cmdaskdemod(const char *Cmd)
75 {
76 int i;
77 int c, high = 0, low = 0;
78
79 sscanf(Cmd, "%i", &c);
80
81 /* Detect high and lows and clock */
82 // (AL - clock???)
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 }
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
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
124 void printBitStream(uint8_t BitStream[], uint32_t bitLen){
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;
131 for (i = 0; i <= (bitLen-16); i+=16) {
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 }
152 void printEM410x(uint64_t id)
153 {
154 if (id !=0){
155 uint64_t iii=1;
156 uint64_t id2lo=0; //id2hi=0,
157 uint32_t ii=0;
158 uint32_t i=0;
159 for (ii=5; ii>0;ii--){
160 for (i=0;i<8;i++){
161 id2lo=(id2lo<<1LL)|((id & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8)));
162 }
163 }
164 //output em id
165 PrintAndLog("EM TAG ID : %010llx", id);
166 PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
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);
172 PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
173 PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
174 }
175 return;
176 }
177
178 int 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 }
189
190 //by marshmellow
191 //takes 2 arguments - clock and invert both as integers
192 //attempts to demodulate ask while decoding manchester
193 //prints binary found and saves in graphbuffer for further commands
194 int Cmdaskmandemod(const char *Cmd)
195 {
196 int invert=0;
197 int clk=0;
198 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
199 sscanf(Cmd, "%i %i", &clk, &invert);
200 if (invert != 0 && invert != 1) {
201 PrintAndLog("Invalid argument: %s", Cmd);
202 return 0;
203 }
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);
217 }
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
236 int 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");
250 return 0;
251 }
252 bitnum=i;
253 errCnt=manrawdecode(BitStream,&bitnum);
254 if (errCnt>=20){
255 PrintAndLog("Too many errors: %d",errCnt);
256 return 0;
257 }
258 PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
259 printBitStream(BitStream,bitnum);
260 if (errCnt==0){
261 //put back in graphbuffer
262 ClearGraph(0);
263 for (i=0; i < bitnum; ++i){
264 GraphBuffer[i]=BitStream[i];
265 }
266 GraphTraceLen=bitnum;
267 RepaintGraphWindow();
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
284 int 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
320 int 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
350 //output
351 if (errCnt>0){
352 PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
353 }
354 PrintAndLog("ASK demoded bitstream:");
355 // Now output the bitstream to the scrollback by line of 16 bits
356 printBitStream(BitStream,BitLen);
357
358 return 1;
359 }
360
361 int 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
393 int CmdBitsamples(const char *Cmd)
394 {
395 int cnt = 0;
396 uint8_t got[12288];
397
398 GetFromBigBuf(got,sizeof(got),0);
399 WaitForResponse(CMD_ACK,NULL);
400
401 for (int j = 0; j < sizeof(got); j++) {
402 for (int k = 0; k < 8; k++) {
403 if(got[j] & (1 << (7 - k))) {
404 GraphBuffer[cnt++] = 1;
405 } else {
406 GraphBuffer[cnt++] = 0;
407 }
408 }
409 }
410 GraphTraceLen = cnt;
411 RepaintGraphWindow();
412 return 0;
413 }
414
415 /*
416 * Convert to a bitstream
417 */
418 int 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
480 int CmdBuffClear(const char *Cmd)
481 {
482 UsbCommand c = {CMD_BUFF_CLEAR};
483 SendCommand(&c);
484 ClearGraph(true);
485 return 0;
486 }
487
488 int 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 */
499 // uses data from graphbuffer
500 int CmdDetectClockRate(const char *Cmd)
501 {
502 GetClock("",0,0);
503 return 0;
504 }
505
506 //by marshmellow
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))
510 int CmdFSKrawdemod(const char *Cmd)
511 {
512 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
513 //set defaults
514 int rfLen = 50;
515 int invert=0;
516 int fchigh=10;
517 int fclow=8;
518 //set options from parameters entered with the command
519 sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
520
521 if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
522 //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
523 if (rfLen==1){
524 invert=1; //if invert option only is used
525 rfLen = 50;
526 } else if(rfLen==0) rfLen=50;
527 }
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];
538 }
539 GraphTraceLen=size;
540 RepaintGraphWindow();
541
542 // Now output the bitstream to the scrollback by line of 16 bits
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 }
548 return 0;
549 }
550
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
554 int CmdFSKdemodHID(const char *Cmd)
555 {
556 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
557 uint32_t hi2=0, hi=0, lo=0;
558
559 uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
560 uint32_t BitLen = getFromGraphBuf(BitStream);
561 //get binary from fsk wave
562 size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
563 if (size<0){
564 PrintAndLog("Error demoding fsk");
565 return 0;
566 }
567 if (hi2==0 && hi==0 && lo==0) return 0;
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);
571 setGraphBuf(BitStream,BitLen);
572 return 1;
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
576 uint8_t fmtLen = 0;
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 }
587 fmtLen =idx3+19;
588 fc =0;
589 cardnum=0;
590 if(fmtLen==26){
591 cardnum = (lo>>1)&0xFFFF;
592 fc = (lo>>17)&0xFF;
593 }
594 if(fmtLen==37){
595 cardnum = (lo>>1)&0x7FFFF;
596 fc = ((hi&0xF)<<12)|(lo>>20);
597 }
598 if(fmtLen==34){
599 cardnum = (lo>>1)&0xFFFF;
600 fc= ((hi&1)<<15)|(lo>>17);
601 }
602 if(fmtLen==35){
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
608 fmtLen= 37;
609 fc =0;
610 cardnum=0;
611 if(fmtLen==37){
612 cardnum = (lo>>1)&0x7FFFF;
613 fc = ((hi&0xF)<<12)|(lo>>20);
614 }
615 }
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,
618 (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
619 setGraphBuf(BitStream,BitLen);
620 return 1;
621 }
622 return 0;
623 }
624
625 //by marshmellow
626 //IO-Prox demod - FSK RF/64 with preamble of 000000001
627 //print ioprox ID and some format details
628 int CmdFSKdemodIO(const char *Cmd)
629 {
630 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
631 //set defaults
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;
647 }
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
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
671
672 PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
673 setGraphBuf(BitStream,BitLen);
674 return 1;
675 }
676
677 int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
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
734 // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
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
796 int CmdGrid(const char *Cmd)
797 {
798 sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
799 PlotGridXdefault= PlotGridX;
800 PlotGridYdefault= PlotGridY;
801 RepaintGraphWindow();
802 return 0;
803 }
804
805 int CmdHexsamples(const char *Cmd)
806 {
807 int i, j;
808 int requested = 0;
809 int offset = 0;
810 char string_buf[25];
811 char* string_ptr = string_buf;
812 uint8_t got[40000];
813
814 sscanf(Cmd, "%i %i", &requested, &offset);
815
816 /* if no args send something */
817 if (requested == 0) {
818 requested = 8;
819 }
820 if (offset + requested > sizeof(got)) {
821 PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
822 return 0;
823 }
824
825 GetFromBigBuf(got,requested,offset);
826 WaitForResponse(CMD_ACK,NULL);
827
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 }
844 }
845 return 0;
846 }
847
848 int CmdHide(const char *Cmd)
849 {
850 HideGraphWindow();
851 return 0;
852 }
853
854 int 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
869 int CmdSamples(const char *Cmd)
870 {
871 uint8_t got[36440] = {0x00};
872
873 int n = strtol(Cmd, NULL, 0);
874 if (n == 0)
875 n = 20000;
876 if (n > sizeof(got))
877 n = sizeof(got);
878
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;
888 }
889
890 int CmdTuneSamples(const char *Cmd)
891 {
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 }
907
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 }
932
933 PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
934 PrintAndLog("\n");
935 GraphTraceLen = 256;
936 ShowGraphWindow();
937
938 return 0;
939 }
940
941 int CmdLoad(const char *Cmd)
942 {
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 }
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
968 int 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 int CmdRtrim(const char *Cmd)
980 {
981 int ds = atoi(Cmd);
982
983 GraphTraceLen = ds;
984
985 RepaintGraphWindow();
986 return 0;
987 }
988
989 /*
990 * Manchester demodulate a bitstream. The bitstream needs to be already in
991 * the GraphBuffer as 0 and 1 values
992 *
993 * Give the clock rate as argument in order to help the sync - the algorithm
994 * resyncs at each pulse anyway.
995 *
996 * Not optimized by any means, this is the 1st time I'm writing this type of
997 * routine, feel free to improve...
998 *
999 * 1st argument: clock rate (as number of samples per clock rate)
1000 * Typical values can be 64, 32, 128...
1001 */
1002 int CmdManchesterDemod(const char *Cmd)
1003 {
1004 int i, j, invert= 0;
1005 int bit;
1006 int clock;
1007 int lastval = 0;
1008 int low = 0;
1009 int high = 0;
1010 int hithigh, hitlow, first;
1011 int lc = 0;
1012 int bitidx = 0;
1013 int bit2idx = 0;
1014 int warnings = 0;
1015
1016 /* check if we're inverting output */
1017 if (*Cmd == 'i')
1018 {
1019 PrintAndLog("Inverting output");
1020 invert = 1;
1021 ++Cmd;
1022 do
1023 ++Cmd;
1024 while(*Cmd == ' '); // in case a 2nd argument was given
1025 }
1026
1027 /* Holds the decoded bitstream: each clock period contains 2 bits */
1028 /* later simplified to 1 bit after manchester decoding. */
1029 /* Add 10 bits to allow for noisy / uncertain traces without aborting */
1030 /* int BitStream[GraphTraceLen*2/clock+10]; */
1031
1032 /* But it does not work if compiling on WIndows: therefore we just allocate a */
1033 /* large array */
1034 uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00};
1035
1036 /* Detect high and lows */
1037 for (i = 0; i < GraphTraceLen; i++)
1038 {
1039 if (GraphBuffer[i] > high)
1040 high = GraphBuffer[i];
1041 else if (GraphBuffer[i] < low)
1042 low = GraphBuffer[i];
1043 }
1044
1045 /* Get our clock */
1046 clock = GetClock(Cmd, high, 1);
1047 int tolerance = clock/4;
1048
1049 /* Detect first transition */
1050 /* Lo-Hi (arbitrary) */
1051 /* skip to the first high */
1052 for (i= 0; i < GraphTraceLen; i++)
1053 if (GraphBuffer[i] == high)
1054 break;
1055 /* now look for the first low */
1056 for (; i < GraphTraceLen; i++)
1057 {
1058 if (GraphBuffer[i] == low)
1059 {
1060 lastval = i;
1061 break;
1062 }
1063 }
1064
1065 /* If we're not working with 1/0s, demod based off clock */
1066 if (high != 1)
1067 {
1068 bit = 0; /* We assume the 1st bit is zero, it may not be
1069 * the case: this routine (I think) has an init problem.
1070 * Ed.
1071 */
1072 for (; i < (int)(GraphTraceLen / clock); i++)
1073 {
1074 hithigh = 0;
1075 hitlow = 0;
1076 first = 1;
1077
1078 /* Find out if we hit both high and low peaks */
1079 for (j = 0; j < clock; j++)
1080 {
1081 if (GraphBuffer[(i * clock) + j] == high)
1082 hithigh = 1;
1083 else if (GraphBuffer[(i * clock) + j] == low)
1084 hitlow = 1;
1085
1086 /* it doesn't count if it's the first part of our read
1087 because it's really just trailing from the last sequence */
1088 if (first && (hithigh || hitlow))
1089 hithigh = hitlow = 0;
1090 else
1091 first = 0;
1092
1093 if (hithigh && hitlow)
1094 break;
1095 }
1096
1097 /* If we didn't hit both high and low peaks, we had a bit transition */
1098 if (!hithigh || !hitlow)
1099 bit ^= 1;
1100
1101 BitStream[bit2idx++] = bit ^ invert;
1102 }
1103 }
1104
1105 /* standard 1/0 bitstream */
1106 else
1107 {
1108
1109 /* Then detect duration between 2 successive transitions */
1110 for (bitidx = 1; i < GraphTraceLen; i++)
1111 {
1112 if (GraphBuffer[i-1] != GraphBuffer[i])
1113 {
1114 lc = i-lastval;
1115 lastval = i;
1116
1117 // Error check: if bitidx becomes too large, we do not
1118 // have a Manchester encoded bitstream or the clock is really
1119 // wrong!
1120 if (bitidx > (GraphTraceLen*2/clock+8) ) {
1121 PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
1122 return 0;
1123 }
1124 // Then switch depending on lc length:
1125 // Tolerance is 1/4 of clock rate (arbitrary)
1126 if (abs(lc-clock/2) < tolerance) {
1127 // Short pulse : either "1" or "0"
1128 BitStream[bitidx++]=GraphBuffer[i-1];
1129 } else if (abs(lc-clock) < tolerance) {
1130 // Long pulse: either "11" or "00"
1131 BitStream[bitidx++]=GraphBuffer[i-1];
1132 BitStream[bitidx++]=GraphBuffer[i-1];
1133 } else {
1134 // Error
1135 warnings++;
1136 PrintAndLog("Warning: Manchester decode error for pulse width detection.");
1137 PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");
1138
1139 if (warnings > 10)
1140 {
1141 PrintAndLog("Error: too many detection errors, aborting.");
1142 return 0;
1143 }
1144 }
1145 }
1146 }
1147
1148 // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
1149 // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
1150 // to stop output at the final bitidx2 value, not bitidx
1151
1152 //http://www.proxmark.org/forum/viewtopic.php?id=403
1153 for (i = 1; i < bitidx; i += 2) {
1154 if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
1155 BitStream[bit2idx++] = 1 ^ invert;
1156 } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
1157 BitStream[bit2idx++] = 0 ^ invert;
1158 } else {
1159 // We cannot end up in this state, this means we are unsynchronized,
1160 // move up 1 bit:
1161 i++;
1162 warnings++;
1163 PrintAndLog("Unsynchronized, resync...");
1164 PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
1165
1166 if (warnings > 10)
1167 {
1168 PrintAndLog("Error: too many decode errors, aborting.");
1169 return 0;
1170 }
1171 }
1172 }
1173 }
1174
1175 PrintAndLog("Manchester decoded bitstream");
1176 // Now output the bitstream to the scrollback by line of 16 bits
1177 for (i = 0; i < (bit2idx-16); i+=16) {
1178 PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
1179 BitStream[i],
1180 BitStream[i+1],
1181 BitStream[i+2],
1182 BitStream[i+3],
1183 BitStream[i+4],
1184 BitStream[i+5],
1185 BitStream[i+6],
1186 BitStream[i+7],
1187 BitStream[i+8],
1188 BitStream[i+9],
1189 BitStream[i+10],
1190 BitStream[i+11],
1191 BitStream[i+12],
1192 BitStream[i+13],
1193 BitStream[i+14],
1194 BitStream[i+15]);
1195 }
1196 return bit2idx;
1197 }
1198
1199 /* Modulate our data into manchester */
1200 int CmdManchesterMod(const char *Cmd)
1201 {
1202 int i, j;
1203 int bit, lastbit, wave;
1204 int clock = GetClock(Cmd, 0, 1);
1205 int clock1 = GetT55x7Clock( GraphBuffer, GraphTraceLen, 0 );
1206 PrintAndLog("MAN MOD CLOCKS: %d ice %d", clock,clock1);
1207
1208 int half = (int)(clock/2);
1209
1210 wave = 0;
1211 lastbit = 1;
1212 for (i = 0; i < (int)(GraphTraceLen / clock); i++)
1213 {
1214 bit = GraphBuffer[i * clock] ^ 1;
1215
1216 for (j = 0; j < half; ++j)
1217 GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
1218 for (j = half; j < clock; ++j)
1219 GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
1220
1221 /* Keep track of how we start our wave and if we changed or not this time */
1222 wave ^= bit ^ lastbit;
1223 lastbit = bit;
1224 }
1225
1226 RepaintGraphWindow();
1227 return 0;
1228 }
1229
1230 int CmdNorm(const char *Cmd)
1231 {
1232 int i;
1233 int max = INT_MIN, min = INT_MAX;
1234
1235 for (i = 10; i < GraphTraceLen; ++i) {
1236 if (GraphBuffer[i] > max)
1237 max = GraphBuffer[i];
1238 if (GraphBuffer[i] < min)
1239 min = GraphBuffer[i];
1240 }
1241
1242 if (max != min) {
1243 for (i = 0; i < GraphTraceLen; ++i) {
1244 GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 1000 /
1245 (max - min);
1246 }
1247 }
1248 RepaintGraphWindow();
1249 return 0;
1250 }
1251
1252 int CmdPlot(const char *Cmd)
1253 {
1254 ShowGraphWindow();
1255 return 0;
1256 }
1257
1258 int CmdSave(const char *Cmd)
1259 {
1260 char filename[FILE_PATH_SIZE] = {0x00};
1261 int len = 0;
1262
1263 len = strlen(Cmd);
1264 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
1265 memcpy(filename, Cmd, len);
1266
1267
1268 FILE *f = fopen(filename, "w");
1269 if(!f) {
1270 PrintAndLog("couldn't open '%s'", filename);
1271 return 0;
1272 }
1273 int i;
1274 for (i = 0; i < GraphTraceLen; i++) {
1275 fprintf(f, "%d\n", GraphBuffer[i]);
1276 }
1277 fclose(f);
1278 PrintAndLog("saved to '%s'", Cmd);
1279 return 0;
1280 }
1281
1282 int CmdScale(const char *Cmd)
1283 {
1284 CursorScaleFactor = atoi(Cmd);
1285 if (CursorScaleFactor == 0) {
1286 PrintAndLog("bad, can't have zero scale");
1287 CursorScaleFactor = 1;
1288 }
1289 RepaintGraphWindow();
1290 return 0;
1291 }
1292
1293 int CmdThreshold(const char *Cmd)
1294 {
1295 int threshold = atoi(Cmd);
1296
1297 for (int i = 0; i < GraphTraceLen; ++i) {
1298 if (GraphBuffer[i] >= threshold)
1299 GraphBuffer[i] = 1;
1300 else
1301 GraphBuffer[i] = -1;
1302 }
1303 RepaintGraphWindow();
1304 return 0;
1305 }
1306
1307 int CmdDirectionalThreshold(const char *Cmd)
1308 {
1309 int8_t upThres = param_get8(Cmd, 0);
1310 int8_t downThres = param_get8(Cmd, 1);
1311
1312 printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
1313
1314 int lastValue = GraphBuffer[0];
1315 GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
1316
1317 for (int i = 1; i < GraphTraceLen; ++i) {
1318 // Apply first threshold to samples heading up
1319 if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
1320 {
1321 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1322 GraphBuffer[i] = 1;
1323 }
1324 // Apply second threshold to samples heading down
1325 else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
1326 {
1327 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1328 GraphBuffer[i] = -1;
1329 }
1330 else
1331 {
1332 lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
1333 GraphBuffer[i] = GraphBuffer[i-1];
1334
1335 }
1336 }
1337 GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
1338 RepaintGraphWindow();
1339 return 0;
1340 }
1341
1342 int CmdZerocrossings(const char *Cmd)
1343 {
1344 // Zero-crossings aren't meaningful unless the signal is zero-mean.
1345 CmdHpf("");
1346
1347 int sign = 1;
1348 int zc = 0;
1349 int lastZc = 0;
1350
1351 for (int i = 0; i < GraphTraceLen; ++i) {
1352 if (GraphBuffer[i] * sign >= 0) {
1353 // No change in sign, reproduce the previous sample count.
1354 zc++;
1355 GraphBuffer[i] = lastZc;
1356 } else {
1357 // Change in sign, reset the sample count.
1358 sign = -sign;
1359 GraphBuffer[i] = lastZc;
1360 if (sign > 0) {
1361 lastZc = zc;
1362 zc = 0;
1363 }
1364 }
1365 }
1366
1367 RepaintGraphWindow();
1368 return 0;
1369 }
1370
1371 static command_t CommandTable[] =
1372 {
1373 {"help", CmdHelp, 1, "This help"},
1374 {"amp", CmdAmp, 1, "Amplify peaks"},
1375 {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
1376 {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
1377 {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
1378 {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
1379 {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
1380 {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
1381 {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
1382 {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
1383 {"dec", CmdDec, 1, "Decimate samples"},
1384 {"detectaskclock",CmdDetectClockRate, 1, "Detect ASK clock rate"},
1385 {"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
1386 {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
1387 {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
1388 {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
1389 {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"},
1390 {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
1391 {"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
1392 {"hide", CmdHide, 1, "Hide graph window"},
1393 {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
1394 {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
1395 {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
1396 {"rtrim", CmdRtrim, 1, "<location to end trace> -- Trim samples from right of trace"},
1397 {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
1398 {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"},
1399 {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
1400 {"norm", CmdNorm, 1, "Normalize max/min to +/-500"},
1401 {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
1402 {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
1403 {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
1404 {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
1405 {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
1406 {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
1407 {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
1408 {NULL, NULL, 0, NULL}
1409 };
1410
1411 int CmdData(const char *Cmd)
1412 {
1413 CmdsParse(CommandTable, Cmd);
1414 return 0;
1415 }
1416
1417 int CmdHelp(const char *Cmd)
1418 {
1419 CmdsHelp(CommandTable);
1420 return 0;
1421 }
Impressum, Datenschutz