]> git.zerfleddert.de Git - proxmark3-svn/blame - common/lfdemod.c
FIX: a shot at fixing the "_" underscore problem in fileutils.c. This one uses _ifde...
[proxmark3-svn] / common / lfdemod.c
CommitLineData
6ff6ade2 1//-----------------------------------------------------------------------------
2// Copyright (C) 2014
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// Low frequency commands
9//-----------------------------------------------------------------------------
10
8d0a3e87 11#include <stdio.h>
6ff6ade2 12#include <stdlib.h>
13#include <string.h>
14#include "lfdemod.h"
15
16//by marshmellow
17//takes 1s and 0s and searches for EM410x format - output EM ID
8d0a3e87 18uint64_t Em410xDecode(uint8_t *BitStream, uint32_t BitLen)
6ff6ade2 19{
8d0a3e87 20 //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
21 // otherwise could be a void with no arguments
22 //set defaults
23 int high = 0, low = 128;
24 uint64_t lo = 0;
25 uint32_t i = 0;
26 uint32_t initLoopMax = 65;
27
28 if (initLoopMax > BitLen)
29 initLoopMax = BitLen;
30
31 for (; i < initLoopMax; ++i) //65 samples should be plenty to find high and low values
32 {
33 if (BitStream[i] > high)
34 high = BitStream[i];
35 else if (BitStream[i] < low)
36 low = BitStream[i];
37 }
6ff6ade2 38
8d0a3e87 39 if (((high !=1)||(low !=0))){ //allow only 1s and 0s
40 return 0;
41 }
42
43 uint8_t parityTest = 0;
44 // 111111111 bit pattern represent start of frame
45 uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1};
46 uint32_t idx = 0;
47 uint32_t j = 0;
48 uint8_t resetCnt = 0;
49 while( (idx + 64) < BitLen) {
50
51 restart:
6ff6ade2 52
6ff6ade2 53 // search for a start of frame marker
8d0a3e87 54 if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) {
55 // frame marker found
56 idx += 9;//sizeof(frame_marker_mask);
57 for ( i = 0; i < 10; ++i){
58 for( j = 0; j < 5; ++j){
59 parityTest += BitStream[(i*5) + j + idx];
60 }
61 if (parityTest == ( (parityTest >> 1) << 1)){
62 parityTest = 0;
63 for (j = 0; j < 4; ++j){
64 lo = ( lo << 1LL)|( BitStream[( i * 5 ) + j + idx]);
65 }
66 } else {
67 //parity failed
68 parityTest = 0;
69 idx -= 8;
70 if (resetCnt > 5) return 0;
71 resetCnt++;
72 goto restart;//continue;
73 }
74 }
75 //skip last 5 bit parity test for simplicity.
76 return lo;
77 } else {
78 idx++;
79 }
80 }
81 return 0;
6ff6ade2 82}
83
84//by marshmellow
85//takes 2 arguments - clock and invert both as integers
86//attempts to demodulate ask while decoding manchester
87//prints binary found and saves in graphbuffer for further commands
8d0a3e87 88int askmandemod(uint8_t *BinStream, uint32_t *BitLen, int *clk, int *invert)
6ff6ade2 89{
8d0a3e87 90 int i;
91 int high = 0, low = 128;
92 *clk = DetectASKClock(BinStream, (size_t)*BitLen, *clk); //clock default
93
94 if (*clk < 8 ) *clk = 64;
95 if (*clk < 32 ) *clk = 32;
96 if (*invert != 1) *invert = 0;
97
98 uint32_t initLoopMax = 200;
99 if (initLoopMax > *BitLen)
100 initLoopMax = *BitLen;
6ff6ade2 101
8d0a3e87 102 // Detect high and lows
103 // 200 samples should be enough to find high and low values
104 for (i = 0; i < initLoopMax; ++i) {
105 if (BinStream[i] > high)
106 high = BinStream[i];
107 else if (BinStream[i] < low)
108 low = BinStream[i];
109 }
6ff6ade2 110
8d0a3e87 111 //throw away static
112 if ((high < 158) )
113 return -2;
114
115 //25% fuzz in case highs and lows aren't clipped [marshmellow]
116 high = (int)(high * .75);
117 low = (int)(low+128 * .25);
6ff6ade2 118
8d0a3e87 119 int lastBit = 0; // set first clock check
120 uint32_t bitnum = 0; // output counter
121
122 // clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
123 //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
124 int tol = ( *clk == 32 ) ? 1 : 0;
125
126 int j = 0;
127 uint32_t gLen = *BitLen;
128
129 if (gLen > 3000) gLen = 3000;
130
131 uint8_t errCnt = 0;
132 uint32_t bestStart = *BitLen;
133 uint32_t bestErrCnt = (*BitLen/1000);
134 uint32_t maxErr = bestErrCnt;
6ff6ade2 135
136 //loop to find first wave that works
8d0a3e87 137 for (j=0; j < gLen; ++j){
138
139 if ((BinStream[j] >= high)||(BinStream[j] <= low)){
140 lastBit = j - *clk;
141 errCnt = 0;
142
6ff6ade2 143 //loop through to see if this start location works
8d0a3e87 144 for (i = j; i < *BitLen; ++i) {
6ff6ade2 145 if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
8d0a3e87 146 lastBit += *clk;
6ff6ade2 147 } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
148 //low found and we are expecting a bar
8d0a3e87 149 lastBit += *clk;
6ff6ade2 150 } else {
151 //mid value found or no bar supposed to be here
8d0a3e87 152 if ((i-lastBit) > (*clk + tol)){
6ff6ade2 153 //should have hit a high or low based on clock!!
154
155 errCnt++;
8d0a3e87 156 lastBit += *clk;//skip over until hit too many errors
157 if (errCnt > maxErr) break; //allow 1 error for every 1000 samples else start over
6ff6ade2 158 }
159 }
8d0a3e87 160 if ((i-j) >(400 * *clk)) break; //got plenty of bits
6ff6ade2 161 }
162 //we got more than 64 good bits and not all errors
8d0a3e87 163 if ((((i-j)/ *clk) > (64 + errCnt)) && (errCnt < maxErr)) {
6ff6ade2 164 //possible good read
8d0a3e87 165 if (errCnt == 0){
166 bestStart = j;
167 bestErrCnt = errCnt;
6ff6ade2 168 break; //great read - finish
169 }
8d0a3e87 170 if (errCnt < bestErrCnt){ //set this as new best run
171 bestErrCnt = errCnt;
172 bestStart = j;
6ff6ade2 173 }
174 }
175 }
176 }
8d0a3e87 177 if (bestErrCnt < maxErr){
6ff6ade2 178 //best run is good enough set to best run and set overwrite BinStream
8d0a3e87 179 j = bestStart;
180 lastBit = bestStart - *clk;
181 bitnum = 0;
182 for (i = j; i < *BitLen; ++i) {
183 if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
184 lastBit += *clk;
185 BinStream[bitnum] = *invert;
186 bitnum++;
187 } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
188 //low found and we are expecting a bar
189 lastBit += *clk;
190 BinStream[bitnum] = 1 - *invert;
191 bitnum++;
192 } else {
193 //mid value found or no bar supposed to be here
194 if ((i-lastBit) > (*clk+tol)){
195 //should have hit a high or low based on clock!!
196 if (bitnum > 0){
197 BinStream[bitnum] = 77;
198 bitnum++;
199 }
200 lastBit += *clk;//skip over error
201 }
202 }
203 if (bitnum >= 400) break;
204 }
205 *BitLen = bitnum;
206 } else {
207 *invert = bestStart;
208 *clk = j;
209 return -1;
210 }
6ff6ade2 211 return bestErrCnt;
212}
213
214//by marshmellow
215//take 10 and 01 and manchester decode
216//run through 2 times and take least errCnt
8d0a3e87 217int manrawdecode(uint8_t * bits, int *bitlen)
6ff6ade2 218{
8d0a3e87 219 int bitnum = 0;
220 int errCnt = 0;
6ff6ade2 221 int bestErr = 1000;
222 int bestRun = 0;
8d0a3e87 223 int i = 1;
224 int j = 1;
225
226 for (; j < 3; ++j){
227 i = 1;
228 for ( i = i + j; i < *bitlen-2; i += 2){
229 if ( bits[i]==1 && (bits[i+1]==0)){
230 } else if ((bits[i]==0)&& bits[i+1]==1){
231 } else {
232 errCnt++;
233 }
234 if(bitnum > 300) break;
6ff6ade2 235 }
8d0a3e87 236 if (bestErr > errCnt){
237 bestErr = errCnt;
238 bestRun = j;
6ff6ade2 239 }
8d0a3e87 240 errCnt = 0;
241 }
242 errCnt = bestErr;
243 if (errCnt < 20){
244 j = bestRun;
245 i = 1;
246 for ( i = i+j; i < *bitlen-2; i += 2){
247 if ( bits[i] == 1 && bits[i + 1] == 0 ){
248 bits[bitnum++] = 0;
249 } else if ( bits[i] == 0 && bits[i + 1] == 1 ){
250 bits[bitnum++] = 1;
251 } else {
252 bits[bitnum++] = 77;
253 }
254 if ( bitnum > 300 ) break;
6ff6ade2 255 }
8d0a3e87 256 *bitlen = bitnum;
6ff6ade2 257 }
8d0a3e87 258 return errCnt;
6ff6ade2 259}
260
261
262//by marshmellow
263//take 01 or 10 = 0 and 11 or 00 = 1
8d0a3e87 264int BiphaseRawDecode(uint8_t * bits, int *bitlen, int offset)
6ff6ade2 265{
8d0a3e87 266 uint8_t bitnum = 0;
267 uint32_t errCnt = 0;
268 uint32_t i = offset;
269
270 for (; i < *bitlen-2; i += 2 ){
271 if ( (bits[i]==1 && bits[i+1]==0)||
272 (bits[i]==0 && bits[i+1]==1)){
273 bits[bitnum++] = 1;
274 } else if ( (bits[i]==0 && bits[i+1]==0)||
275 (bits[i]==1 && bits[i+1]==1)){
276 bits[bitnum++] = 0;
277 } else {
278 bits[bitnum++] = 77;
279 errCnt++;
280 }
281 if ( bitnum > 250) break;
6ff6ade2 282 }
8d0a3e87 283 *bitlen = bitnum;
284 return errCnt;
6ff6ade2 285}
286
287//by marshmellow
288//takes 2 arguments - clock and invert both as integers
289//attempts to demodulate ask only
290//prints binary found and saves in graphbuffer for further commands
8d0a3e87 291int askrawdemod(uint8_t *BinStream, int *bitLen, int *clk, int *invert)
6ff6ade2 292{
293 uint32_t i;
8d0a3e87 294 uint32_t initLoopMax = 200;
6ff6ade2 295 int high = 0, low = 128;
8d0a3e87 296 uint8_t BitStream[502] = {0x00};
297
298 *clk = DetectASKClock(BinStream, *bitLen, *clk); //clock default
299
300 if (*clk < 8) *clk = 64;
301 if (*clk < 32) *clk = 32;
6ff6ade2 302 if (*invert != 1) *invert = 0;
8d0a3e87 303
304 if (initLoopMax > *bitLen)
305 initLoopMax = *bitLen;
6ff6ade2 306
6ff6ade2 307 // Detect high and lows
308 for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values
309 {
310 if (BinStream[i] > high)
8d0a3e87 311 high = BinStream[i];
6ff6ade2 312 else if (BinStream[i] < low)
8d0a3e87 313 low = BinStream[i];
6ff6ade2 314 }
8d0a3e87 315
316 //throw away static
317 if ((high < 158)){
318 return -2;
319 }
320
321 //25% fuzz in case highs and lows aren't clipped [marshmellow]
322 high = (int)(high * .75);
323 low = (int)(low+128 * .25);
324
325 int lastBit = 0; //set first clock check
326 uint32_t bitnum = 0; //output counter
327
328 uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
329 if (*clk==32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
330
6ff6ade2 331 uint32_t gLen = *bitLen;
8d0a3e87 332 if (gLen > 500) gLen = 500;
6ff6ade2 333
8d0a3e87 334 uint32_t j = 0;
335 uint8_t errCnt = 0;
336 uint32_t bestStart = *bitLen;
337 uint32_t bestErrCnt = (*bitLen / 1000);
338 uint32_t errCntLimit = bestErrCnt;
339 uint8_t midBit = 0;
340
6ff6ade2 341 //loop to find first wave that works
8d0a3e87 342 for (j = 0; j < gLen; ++j){
343
344 if ((BinStream[j] >= high)||(BinStream[j] <= low)){
345 lastBit = j - *clk;
6ff6ade2 346 //loop through to see if this start location works
8d0a3e87 347 for (i = j; i < *bitLen; ++i) {
6ff6ade2 348 if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
8d0a3e87 349 lastBit += *clk;
6ff6ade2 350 BitStream[bitnum] = *invert;
351 bitnum++;
8d0a3e87 352 midBit = 0;
6ff6ade2 353 } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
354 //low found and we are expecting a bar
8d0a3e87 355 lastBit += *clk;
6ff6ade2 356 BitStream[bitnum] = 1-*invert;
357 bitnum++;
358 midBit=0;
359 } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
360 //mid bar?
8d0a3e87 361 midBit = 1;
362 BitStream[bitnum] = 1 - *invert;
6ff6ade2 363 bitnum++;
364 } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
365 //mid bar?
8d0a3e87 366 midBit = 1;
367 BitStream[bitnum] = *invert;
6ff6ade2 368 bitnum++;
369 } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){
370 //no mid bar found
8d0a3e87 371 midBit = 1;
372 BitStream[bitnum] = BitStream[bitnum-1];
6ff6ade2 373 bitnum++;
374 } else {
375 //mid value found or no bar supposed to be here
376
8d0a3e87 377 if (( i - lastBit) > ( *clk + tol)){
6ff6ade2 378 //should have hit a high or low based on clock!!
379
380 if (bitnum > 0){
8d0a3e87 381 BitStream[bitnum] = 77;
6ff6ade2 382 bitnum++;
383 }
384
385 errCnt++;
8d0a3e87 386 lastBit += *clk;//skip over until hit too many errors
387 if (errCnt > errCntLimit){ //allow 1 error for every 1000 samples else start over
388 errCnt = 0;
389 bitnum = 0;//start over
6ff6ade2 390 break;
391 }
392 }
393 }
8d0a3e87 394 if (bitnum > 500) break;
6ff6ade2 395 }
396 //we got more than 64 good bits and not all errors
8d0a3e87 397 //possible good read
398 if ((bitnum > (64 + errCnt)) && (errCnt < errCntLimit)) {
399
400 //great read - finish
401 if (errCnt == 0) break;
402
403 //if current run == bestErrCnt run (after exhausted testing) then finish
404 if (bestStart == j) break;
405
406 //set this as new best run
407 if (errCnt < bestErrCnt){
408 bestErrCnt = errCnt;
409 bestStart = j;
6ff6ade2 410 }
411 }
412 }
8d0a3e87 413 if (j >= gLen){ //exhausted test
6ff6ade2 414 //if there was a ok test go back to that one and re-run the best run (then dump after that run)
8d0a3e87 415 if (bestErrCnt < errCntLimit)
416 j = bestStart;
6ff6ade2 417 }
418 }
8d0a3e87 419 if (bitnum > 16){
6ff6ade2 420
8d0a3e87 421 for (i = 0; i < bitnum; ++i){
422 BinStream[i] = BitStream[i];
6ff6ade2 423 }
424 *bitLen = bitnum;
425 } else {
426 return -1;
427 }
428 return errCnt;
429}
430//translate wave to 11111100000 (1 for each short wave 0 for each long wave)
431size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow)
432{
433 uint32_t last_transition = 0;
434 uint32_t idx = 1;
8d0a3e87 435 uint32_t maxVal = 0;
436
437 if (fchigh == 0) fchigh = 10;
438 if (fclow == 0) fclow = 8;
439
6ff6ade2 440 // we do care about the actual theshold value as sometimes near the center of the
441 // wave we may get static that changes direction of wave for one value
442 // if our value is too low it might affect the read. and if our tag or
443 // antenna is weak a setting too high might not see anything. [marshmellow]
8d0a3e87 444 if ( size < 100)
445 return 0;
446
447 // Find high from first 100 samples
448 for ( idx = 1; idx < 100; idx++ ){
449 if ( maxVal < dest[idx])
450 maxVal = dest[idx];
451 }
452
6ff6ade2 453 // set close to the top of the wave threshold with 25% margin for error
454 // less likely to get a false transition up there.
455 // (but have to be careful not to go too high and miss some short waves)
8d0a3e87 456 uint8_t threshold_value = (uint8_t)(maxVal * .75);
6ff6ade2 457
458 // sync to first lo-hi transition, and threshold
459 // Need to threshold first sample
460
8d0a3e87 461 dest[0] = (dest[0] < threshold_value) ? 0 : 1;
6ff6ade2 462
463 size_t numBits = 0;
8d0a3e87 464
6ff6ade2 465 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
466 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
467 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
468 for(idx = 1; idx < size; idx++) {
6ff6ade2 469
8d0a3e87 470 // threshold current value
471 dest[idx] = (dest[idx] < threshold_value) ? 0 : 1;
6ff6ade2 472
473 // Check for 0->1 transition
474 if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
8d0a3e87 475 if ( ( idx - last_transition ) <( fclow - 2 ) ) { //0-5 = garbage noise
6ff6ade2 476 //do nothing with extra garbage
8d0a3e87 477 } else if ((idx - last_transition) < ( fchigh - 1 )) { //6-8 = 8 waves
6ff6ade2 478 dest[numBits]=1;
479 } else { //9+ = 10 waves
480 dest[numBits]=0;
481 }
482 last_transition = idx;
483 numBits++;
484 }
485 }
8d0a3e87 486 //it returns the number of bytes, but each byte represents a bit: 1 or 0
487 return numBits;
6ff6ade2 488}
489
490uint32_t myround2(float f)
491{
492 if (f >= 2000) return 2000;//something bad happened
493 return (uint32_t) (f + (float)0.5);
494}
495
496//translate 11111100000 to 10
8d0a3e87 497size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert, uint8_t fchigh, uint8_t fclow )
6ff6ade2 498{
8d0a3e87 499 uint8_t lastval = dest[0];
500 uint32_t idx = 0;
501 uint32_t n = 1;
502 size_t numBits = 0;
6ff6ade2 503
8d0a3e87 504 for( idx = 1; idx < size; idx++) {
6ff6ade2 505
8d0a3e87 506 if (dest[idx] == lastval) {
6ff6ade2 507 n++;
508 continue;
509 }
510 //if lastval was 1, we have a 1->0 crossing
8d0a3e87 511 if ( dest[idx-1] == 1 ) {
512 n = myround2( (float)( n + 1 ) / ((float)(rfLen)/(float)fclow));
513 } else { // 0->1 crossing
514 n = myround2( (float)( n + 1 ) / ((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor
6ff6ade2 515 }
516 if (n == 0) n = 1;
517
518 if(n < maxConsequtiveBits) //Consecutive
519 {
8d0a3e87 520 if(invert == 0){ //invert bits
6ff6ade2 521 memset(dest+numBits, dest[idx-1] , n);
522 }else{
523 memset(dest+numBits, dest[idx-1]^1 , n);
524 }
525 numBits += n;
526 }
8d0a3e87 527 n = 0;
528 lastval = dest[idx];
6ff6ade2 529 }//end for
530 return numBits;
531}
8d0a3e87 532
6ff6ade2 533//by marshmellow (from holiman's base)
534// full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod)
535int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow)
536{
8d0a3e87 537 // FSK demodulator
538 size = fsk_wave_demod(dest, size, fchigh, fclow);
539 if ( size > 0 )
540 size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow);
541 else
542 return -1;
543 return size;
6ff6ade2 544}
8d0a3e87 545
6ff6ade2 546// loop to get raw HID waveform then FSK demodulate the TAG ID from it
547int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo)
548{
8d0a3e87 549 size_t idx = 0;
550 int numshifts = 0;
551
6ff6ade2 552 // FSK demodulator
8d0a3e87 553 size = fskdemod(dest, size, 50, 0, 10, 8);
6ff6ade2 554
555 // final loop, go over previously decoded manchester data and decode into usable tag ID
556 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
557 uint8_t frame_marker_mask[] = {1,1,1,0,0,0};
8d0a3e87 558
559 uint8_t mask_len = sizeof frame_marker_mask / sizeof frame_marker_mask[0];
560
6ff6ade2 561 //one scan
8d0a3e87 562 while( idx + mask_len < size) {
6ff6ade2 563 // search for a start of frame marker
564 if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
565 { // frame marker found
8d0a3e87 566 idx += mask_len;
6ff6ade2 567 while(dest[idx] != dest[idx+1] && idx < size-2)
568 {
569 // Keep going until next frame marker (or error)
570 // Shift in a bit. Start by shifting high registers
8d0a3e87 571 *hi2 = ( *hi2 << 1 ) | ( *hi >> 31 );
572 *hi = ( *hi << 1 ) | ( *lo >> 31 );
6ff6ade2 573 //Then, shift in a 0 or one into low
574 if (dest[idx] && !dest[idx+1]) // 1 0
8d0a3e87 575 *lo = ( *lo << 1 ) | 0;
6ff6ade2 576 else // 0 1
8d0a3e87 577 *lo = ( *lo << 1 ) | 1;
6ff6ade2 578 numshifts++;
579 idx += 2;
580 }
581 // Hopefully, we read a tag and hit upon the next frame marker
8d0a3e87 582 if(idx + mask_len < size)
6ff6ade2 583 {
584 if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
585 {
586 //good return
587 return idx;
588 }
589 }
590 // reset
591 *hi2 = *hi = *lo = 0;
592 numshifts = 0;
593 }else {
594 idx++;
595 }
596 }
597 return -1;
598}
599
8d0a3e87 600uint32_t bytebits_to_byte(uint8_t *src, int numbits)
6ff6ade2 601{
8d0a3e87 602 //HACK: potential overflow in numbits is larger then uint32 bits.
603
6ff6ade2 604 uint32_t num = 0;
8d0a3e87 605 for(int i = 0 ; i < numbits ; ++i) {
6ff6ade2 606 num = (num << 1) | (*src);
607 src++;
608 }
609 return num;
610}
611
612int IOdemodFSK(uint8_t *dest, size_t size)
613{
6ff6ade2 614 //make sure buffer has data
8d0a3e87 615 if (size < 100) return -1;
616
617 uint32_t idx = 0;
618 uint8_t testMax = 0;
619
6ff6ade2 620 //test samples are not just noise
8d0a3e87 621 for (; idx < 65; ++idx ){
622 if (testMax < dest[idx])
623 testMax = dest[idx];
6ff6ade2 624 }
8d0a3e87 625
6ff6ade2 626 //if not just noise
8d0a3e87 627 if (testMax < 170) return -2;
628
629 // FSK demodulator
630 size = fskdemod(dest, size, 64, 1, 10, 8); // RF/64 and invert
631
632 //did we get a good demod?
633 if (size < 65) return -3;
634
635 //Index map
636 //0 10 20 30 40 50 60
637 //| | | | | | |
638 //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
639 //-----------------------------------------------------------------------------
640 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
641 //
642 //XSF(version)facility:codeone+codetwo
643 //Handle the data
644
645 uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1};
646
647 for( idx = 0; idx < (size - 65); ++idx) {
648 if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
649 //frame marker found
650 if (!dest[idx+8] &&
651 dest[idx+17] == 1 &&
652 dest[idx+26] == 1 &&
653 dest[idx+35] == 1 &&
654 dest[idx+44] == 1 &&
655 dest[idx+53] == 1){
656 //confirmed proper separator bits found
657 //return start position
658 return (int) idx;
659 }
660 }
661 }
6ff6ade2 662 return 0;
663}
664
665// by marshmellow
666// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
667// maybe somehow adjust peak trimming value based on samples to fix?
668int DetectASKClock(uint8_t dest[], size_t size, int clock)
669{
8d0a3e87 670 int i = 0;
671 int clk[] = {16,32,40,50,64,100,128,256};
672 uint8_t clkLen = sizeof clk / sizeof clk[0];
673
674 //if we already have a valid clock quit
675 for (; i < clkLen; ++i)
676 if (clk[i] == clock)
677 return clock;
678
679 int peak = 0;
680 int low = 128;
681 int loopCnt = 256;
682 if (size < loopCnt)
683 loopCnt = size;
684
685 //get high and low peak
686 for ( i = 0; i < loopCnt; ++i ){
687 if(dest[i] > peak)
688 peak = dest[i];
689 if(dest[i] < low)
690 low = dest[i];
691 }
692
693 peak = (int)(peak * .75);
694 low = (int)(low+128 * .25);
695
696 int ii, cnt, bestErr, tol = 0;
697 int errCnt[clkLen];
698 memset(errCnt, 0x00, clkLen);
699
700 int tmpIndex, tmphigh, tmplow;
701
702 //test each valid clock from smallest to greatest to see which lines up
703 for( cnt = 0; cnt < clkLen; ++cnt ){
704
705 tol = (clk[cnt] == 32) ? 1 : 0;
706 bestErr = 1000;
707 tmpIndex = tmphigh = tmplow = 0;
708
709 //try lining up the peaks by moving starting point (try first 256)
710 for (ii=0; ii < loopCnt; ++ii){
711
712 // not a peak? continue
713 if ( (dest[ii] < peak) && (dest[ii] > low))
714 continue;
715
716 errCnt[cnt] = 0;
717
718 // now that we have the first one lined up test rest of wave array
719 for ( i = 0; i < ((int)(size / clk[cnt]) - 1); ++i){
720
721 tmpIndex = ii + (i * clk[cnt] );
722 tmplow = dest[ tmpIndex - tol];
723 tmphigh = dest[ tmpIndex + tol];
724
725 if ( dest[tmpIndex] >= peak || dest[tmpIndex] <= low ) {
726 }
727 else if ( tmplow >= peak || tmplow <= low){
728 }
729 else if ( tmphigh >= peak || tmphigh <= low){
730 }
731 else
732 errCnt[cnt]++; //error no peak detected
733 }
734
735 //if we found no errors this is correct one - return this clock
736 if ( errCnt[cnt] == 0 )
737 return clk[cnt];
738
739 if ( errCnt[cnt] < bestErr)
740 bestErr = errCnt[cnt];
741 }
742 // save the least error.
743 errCnt[cnt] = bestErr;
744 }
745 // find best clock which has lowest number of errors
746 int j = 0, bestIndex = 0;
747 for (; j < clkLen; ++j){
748 if ( errCnt[j] < errCnt[bestIndex] )
749 bestIndex = j;
750 }
751 return clk[bestIndex];
6ff6ade2 752}
Impressum, Datenschutz