lf demod code cleanup - added fskraw arguments

merged code and added arguments to data fskrawdemod to allow other fsk
mode demodulations (FSK2a = RF/10 & RF/8) another might be (RF/8 & RF/5)
This commit is contained in:
marshmellow42 2014-12-31 02:27:30 -05:00
commit f822a063b3
10 changed files with 132194 additions and 194 deletions

View file

@ -823,10 +823,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
code = bytebits_to_byte(dest+idx,32); code = bytebits_to_byte(dest+idx,32);
code2 = bytebits_to_byte(dest+idx+32,32); code2 = bytebits_to_byte(dest+idx+32,32);
version = bytebits_to_byte(dest+idx+27,8); //14,4 version = bytebits_to_byte(dest+idx+27,8); //14,4
facilitycode = bytebits_to_byte(dest+idx+19,8) ; facilitycode = bytebits_to_byte(dest+idx+18,8) ;
number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
// if we're only looking for one tag // if we're only looking for one tag
if (findone){ if (findone){
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();

View file

@ -194,6 +194,7 @@ int CmdEm410xDecode(const char *Cmd)
return 0; return 0;
} }
//by marshmellow //by marshmellow
//takes 2 arguments - clock and invert both as integers //takes 2 arguments - clock and invert both as integers
//attempts to demodulate ask while decoding manchester //attempts to demodulate ask while decoding manchester
@ -209,25 +210,16 @@ int Cmdaskmandemod(const char *Cmd)
return 0; return 0;
} }
uint32_t BitLen = getFromGraphBuf(BitStream); uint32_t BitLen = getFromGraphBuf(BitStream);
// PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
int errCnt=0; int errCnt=0;
errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
if (errCnt==-1){ //if fatal error (or -1) if (errCnt<0){ //if fatal error (or -1)
//PrintAndLog("no data found"); // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
return 0; return 0;
} }
PrintAndLog("Using Clock: %d and invert=%d",clk,invert); if (BitLen<16) return 0;
//no longer put BitStream back into GraphBuffer... PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
//PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
//move BitStream back to GraphBuffer
/*
ClearGraph(0);
for (i=0; i < bitnum; ++i){
GraphBuffer[i]=BitStream[i];
}
GraphTraceLen=bitnum;
RepaintGraphWindow();
*/
//output //output
if (errCnt>0){ if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
@ -352,7 +344,8 @@ int Cmdaskrawdemod(const char *Cmd)
PrintAndLog("no data found"); PrintAndLog("no data found");
return 0; return 0;
} }
PrintAndLog("Using Clock: %d and invert=%d",clk,invert); if (BitLen<16) return 0;
PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
//PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
//move BitStream back to GraphBuffer //move BitStream back to GraphBuffer
@ -371,7 +364,7 @@ int Cmdaskrawdemod(const char *Cmd)
// Now output the bitstream to the scrollback by line of 16 bits // Now output the bitstream to the scrollback by line of 16 bits
printBitStream(BitStream,BitLen); printBitStream(BitStream,BitLen);
return 0; return 1;
} }
int CmdAutoCorr(const char *Cmd) int CmdAutoCorr(const char *Cmd)
@ -523,31 +516,31 @@ int CmdDetectClockRate(const char *Cmd)
//by marshmellow //by marshmellow
//fsk raw demod and print binary //fsk raw demod and print binary
//takes 2 arguments - Clock and invert //takes 4 arguments - Clock, invert, rchigh, rclow
//defaults: clock = 50, invert=0 //defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
int CmdFSKrawdemod(const char *Cmd) int CmdFSKrawdemod(const char *Cmd)
{ {
//raw fsk demod no manchester decoding no start bit finding just get binary from wave //raw fsk demod no manchester decoding no start bit finding just get binary from wave
//set defaults //set defaults
uint8_t rfLen = 50; int rfLen = 50;
uint8_t invert=0; int invert=0;
int fchigh=10;
int fclow=8;
//set options from parameters entered with the command //set options from parameters entered with the command
sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
rfLen=param_get8(Cmd, 0); //if rfLen option only is used //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
if (rfLen==1){ if (rfLen==1){
invert=1; //if invert option only is used invert=1; //if invert option only is used
rfLen = 50; rfLen = 50;
} else if(rfLen==0) rfLen=50; } else if(rfLen==0) rfLen=50;
} }
if (strlen(Cmd)>2) { PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
rfLen=param_get8(Cmd, 0); //if both options are used
invert=param_get8(Cmd,1);
}
PrintAndLog("Args invert: %d \nClock:%d",invert,rfLen);
uint32_t i=0; uint32_t i=0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
uint32_t BitLen = getFromGraphBuf(BitStream); uint32_t BitLen = getFromGraphBuf(BitStream);
int size = fskdemod(BitStream,BitLen,rfLen,invert); int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
if (size>0){ if (size>0){
PrintAndLog("FSK decoded bitstream:"); PrintAndLog("FSK decoded bitstream:");
ClearGraph(0); ClearGraph(0);
@ -677,19 +670,19 @@ int CmdFSKdemodIO(const char *Cmd)
if (idx+64>BitLen) return 0; if (idx+64>BitLen) return 0;
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]); 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]);
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]); 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]);
PrintAndLog("%d%d%d%d%d%d%d%d %d",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]); 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]);
PrintAndLog("%d%d%d%d%d%d%d%d %d",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]); 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]);
PrintAndLog("%d%d%d%d%d%d%d%d %d",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]); 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]);
PrintAndLog("%d%d%d%d%d%d%d%d %d",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]); 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]);
PrintAndLog("%d%d%d%d%d%d%d%d %d%d",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]); 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]);
uint32_t code = bytebits_to_byte(BitStream+idx,32); uint32_t code = bytebits_to_byte(BitStream+idx,32);
uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32);
short version = bytebits_to_byte(BitStream+idx+27,8); //14,4 uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
uint8_t facilitycode = bytebits_to_byte(BitStream+idx+19,8) ; uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
PrintAndLog("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
setGraphBuf(BitStream,BitLen); setGraphBuf(BitStream,BitLen);
return 1; return 1;
} }

View file

@ -155,8 +155,11 @@ void setGraphBuf(uint8_t *buff,int size)
int getFromGraphBuf(uint8_t *buff) int getFromGraphBuf(uint8_t *buff)
{ {
uint32_t i; uint32_t i;
for (i=0;i<GraphTraceLen;++i) for (i=0;i<GraphTraceLen;++i){
if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
buff[i]=(uint8_t)(GraphBuffer[i]+128); buff[i]=(uint8_t)(GraphBuffer[i]+128);
}
return i; return i;
} }
/* Get or auto-detect clock rate */ /* Get or auto-detect clock rate */

View file

@ -8,22 +8,9 @@
// Low frequency commands // Low frequency commands
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
//#include <inttypes.h>
//#include <limits.h>
#include "lfdemod.h" #include "lfdemod.h"
//#include "proxmark3.h"
//#include "data.h"
//#include "ui.h"
//#include "graph.h"
//#include "cmdparser.h"
//#include "util.h"
//#include "cmdmain.h"
//#include "cmddata.h"
//uint8_t BinStream[MAX_GRAPH_TRACE_LEN];
//uint8_t BinStreamLen;
//by marshmellow //by marshmellow
//takes 1s and 0s and searches for EM410x format - output EM ID //takes 1s and 0s and searches for EM410x format - output EM ID
@ -32,7 +19,7 @@ uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen)
//no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
// otherwise could be a void with no arguments // otherwise could be a void with no arguments
//set defaults //set defaults
int high=0, low=0; int high=0, low=128;
uint64_t lo=0; //hi=0, uint64_t lo=0; //hi=0,
uint32_t i = 0; uint32_t i = 0;
@ -97,20 +84,16 @@ uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen)
//prints binary found and saves in graphbuffer for further commands //prints binary found and saves in graphbuffer for further commands
int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert)
{ {
uint32_t i; int i;
//int invert=0; //invert default int high = 0, low = 128;
int high = 0, low = 0; *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default
*clk=DetectClock2(BinStream,(size_t)*BitLen,*clk); //clock default
uint8_t BitStream[252] = {0};
//sscanf(Cmd, "%i %i", &clk, &invert);
if (*clk<8) *clk =64; if (*clk<8) *clk =64;
if (*clk<32) *clk=32; if (*clk<32) *clk=32;
if (*invert != 0 && *invert != 1) *invert=0; if (*invert != 0 && *invert != 1) *invert=0;
uint32_t initLoopMax = 200; uint32_t initLoopMax = 200;
if (initLoopMax>*BitLen) initLoopMax=*BitLen; if (initLoopMax>*BitLen) initLoopMax=*BitLen;
// Detect high and lows // Detect high and lows
//PrintAndLog("Using Clock: %d and invert=%d",clk,invert);
for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values
{ {
if (BinStream[i] > high) if (BinStream[i] > high)
@ -118,153 +101,178 @@ int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert)
else if (BinStream[i] < low) else if (BinStream[i] < low)
low = BinStream[i]; low = BinStream[i];
} }
if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first) if ((high < 158) ){ //throw away static
//PrintAndLog("no data found"); //PrintAndLog("no data found");
return -1; return -2;
} }
//13% fuzz in case highs and lows aren't clipped [marshmellow] //25% fuzz in case highs and lows aren't clipped [marshmellow]
high=(int)(0.75*high); high=(int)((high-128)*.75)+128;
low=(int)(0.75*low); low= (int)((low-128)*.75)+128;
//PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
int lastBit = 0; //set first clock check int lastBit = 0; //set first clock check
uint32_t bitnum = 0; //output counter uint32_t bitnum = 0; //output counter
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 int tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
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 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
uint32_t iii = 0; int iii = 0;
uint32_t gLen = *BitLen; uint32_t gLen = *BitLen;
if (gLen > 500) gLen=500; if (gLen > 3000) gLen=3000;
uint8_t errCnt =0; uint8_t errCnt =0;
uint32_t bestStart = *BitLen; uint32_t bestStart = *BitLen;
uint32_t bestErrCnt = (*BitLen/1000); uint32_t bestErrCnt = (*BitLen/1000);
uint32_t maxErr = (*BitLen/1000);
//PrintAndLog("DEBUG - lastbit - %d",lastBit); //PrintAndLog("DEBUG - lastbit - %d",lastBit);
//loop to find first wave that works //loop to find first wave that works
for (iii=0; iii < gLen; ++iii){ for (iii=0; iii < gLen; ++iii){
if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){
lastBit=iii-*clk; lastBit=iii-*clk;
bitnum=0; errCnt=0;
//loop through to see if this start location works //loop through to see if this start location works
for (i = iii; i < *BitLen; ++i) { for (i = iii; i < *BitLen; ++i) {
if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
lastBit+=*clk; lastBit+=*clk;
BitStream[bitnum] = *invert;
bitnum++;
} else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
//low found and we are expecting a bar //low found and we are expecting a bar
lastBit+=*clk; lastBit+=*clk;
BitStream[bitnum] = 1-*invert;
bitnum++;
} else { } else {
//mid value found or no bar supposed to be here //mid value found or no bar supposed to be here
if ((i-lastBit)>(*clk+tol)){ if ((i-lastBit)>(*clk+tol)){
//should have hit a high or low based on clock!! //should have hit a high or low based on clock!!
//debug //debug
//PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
if (bitnum > 0){
BitStream[bitnum]=77;
bitnum++;
}
errCnt++; errCnt++;
lastBit+=*clk;//skip over until hit too many errors lastBit+=*clk;//skip over until hit too many errors
if (errCnt>((*BitLen/1000))){ //allow 1 error for every 1000 samples else start over if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over
errCnt=0;
bitnum=0;//start over
break;
}
} }
} }
if (bitnum >250) break; if ((i-iii) >(400 * *clk)) break; //got plenty of bits
} }
//we got more than 64 good bits and not all errors //we got more than 64 good bits and not all errors
if ((bitnum > (64+errCnt)) && (errCnt<(*BitLen/1000))) { if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<maxErr)) {
//possible good read //possible good read
if (errCnt==0) break; //great read - finish if (errCnt==0){
if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish bestStart=iii;
bestErrCnt=errCnt;
break; //great read - finish
}
if (errCnt<bestErrCnt){ //set this as new best run if (errCnt<bestErrCnt){ //set this as new best run
bestErrCnt=errCnt; bestErrCnt=errCnt;
bestStart = iii; bestStart = iii;
} }
} }
} }
if (iii>=gLen){ //exhausted test
//if there was a ok test go back to that one and re-run the best run (then dump after that run)
if (bestErrCnt < (*BitLen/1000)) iii=bestStart;
}
} }
if (bitnum>16){ if (bestErrCnt<maxErr){
//best run is good enough set to best run and set overwrite BinStream
// PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); iii=bestStart;
//move BitStream back to GraphBuffer lastBit=bestStart-*clk;
//ClearGraph(0); bitnum=0;
for (i=0; i < bitnum; ++i){ for (i = iii; i < *BitLen; ++i) {
BinStream[i]=BitStream[i]; if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
lastBit+=*clk;
BinStream[bitnum] = *invert;
bitnum++;
} else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
//low found and we are expecting a bar
lastBit+=*clk;
BinStream[bitnum] = 1-*invert;
bitnum++;
} else {
//mid value found or no bar supposed to be here
if ((i-lastBit)>(*clk+tol)){
//should have hit a high or low based on clock!!
//debug
//PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
if (bitnum > 0){
BinStream[bitnum]=77;
bitnum++;
}
lastBit+=*clk;//skip over error
}
}
if (bitnum >=400) break;
} }
*BitLen=bitnum; *BitLen=bitnum;
//RepaintGraphWindow(); } else{
//output *invert=bestStart;
//if (errCnt>0){ *clk=iii;
// PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); return -1;
//} }
// PrintAndLog("ASK decoded bitstream:"); return bestErrCnt;
// Now output the bitstream to the scrollback by line of 16 bits
// printBitStream2(BitStream,bitnum);
// Em410xDecode(Cmd);
}
return errCnt;
} }
//by marshmellow //by marshmellow
//take 10 and 01 and manchester decode //take 10 and 01 and manchester decode
//run through 2 times and take least errCnt //run through 2 times and take least errCnt
int manrawdemod(uint8_t * BitStream, int *bitLen) int manrawdecode(uint8_t * BitStream, int *bitLen)
{ {
uint8_t BitStream2[252]={0};
int bitnum=0; int bitnum=0;
int errCnt =0; int errCnt =0;
int i=1; int i=1;
int bestErr = 1000; int bestErr = 1000;
int bestRun = 0; int bestRun = 0;
int finish = 0;
int ii=1; int ii=1;
for (ii=1;ii<3;++ii){ for (ii=1;ii<3;++ii){
i=1; i=1;
for (i=i+ii;i<*bitLen-2;i+=2){ for (i=i+ii;i<*bitLen-2;i+=2){
if(BitStream[i]==1 && (BitStream[i+1]==0)){ if(BitStream[i]==1 && (BitStream[i+1]==0)){
BitStream2[bitnum++]=0;
} else if((BitStream[i]==0)&& BitStream[i+1]==1){ } else if((BitStream[i]==0)&& BitStream[i+1]==1){
BitStream2[bitnum++]=1;
} else { } else {
BitStream2[bitnum++]=77;
errCnt++; errCnt++;
} }
if(bitnum>250) break; if(bitnum>300) break;
} }
if (bestErr>errCnt){ if (bestErr>errCnt){
bestErr=errCnt; bestErr=errCnt;
bestRun=ii; bestRun=ii;
} }
if (ii>1 || finish==1) {
if (bestRun==ii) {
break;
} else{
ii=bestRun-1;
finish=1;
}
}
errCnt=0; errCnt=0;
bitnum=0;
} }
errCnt=bestErr; errCnt=bestErr;
if (errCnt<20){ if (errCnt<20){
for (i=0; i<bitnum;++i){ ii=bestRun;
BitStream[i]=BitStream2[i]; i=1;
} for (i=i+ii;i<*bitLen-2;i+=2){
*bitLen=bitnum; if(BitStream[i]==1 && (BitStream[i+1]==0)){
} BitStream[bitnum++]=0;
} else if((BitStream[i]==0)&& BitStream[i+1]==1){
BitStream[bitnum++]=1;
} else {
BitStream[bitnum++]=77;
//errCnt++;
}
if(bitnum>300) break;
}
*bitLen=bitnum;
}
return errCnt;
}
//by marshmellow
//take 01 or 10 = 0 and 11 or 00 = 1
int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset)
{
uint8_t bitnum=0;
uint32_t errCnt =0;
uint32_t i=1;
i=offset;
for (;i<*bitLen-2;i+=2){
if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){
BitStream[bitnum++]=1;
} else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){
BitStream[bitnum++]=0;
} else {
BitStream[bitnum++]=77;
errCnt++;
}
if(bitnum>250) break;
}
*bitLen=bitnum;
return errCnt; return errCnt;
} }
@ -276,8 +284,8 @@ int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert)
{ {
uint32_t i; uint32_t i;
// int invert=0; //invert default // int invert=0; //invert default
int high = 0, low = 0; int high = 0, low = 128;
*clk=DetectClock2(BinStream,*bitLen,*clk); //clock default *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default
uint8_t BitStream[502] = {0}; uint8_t BitStream[502] = {0};
if (*clk<8) *clk =64; if (*clk<8) *clk =64;
@ -293,13 +301,13 @@ int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert)
else if (BinStream[i] < low) else if (BinStream[i] < low)
low = BinStream[i]; low = BinStream[i];
} }
if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first) if ((high < 158)){ //throw away static
// PrintAndLog("no data found"); // PrintAndLog("no data found");
return -1; return -2;
} }
//25% fuzz in case highs and lows aren't clipped [marshmellow] //25% fuzz in case highs and lows aren't clipped [marshmellow]
high=(int)(0.75*high); high=(int)((high-128)*.75)+128;
low=(int)(0.75*low); low= (int)((low-128)*.75)+128;
//PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
int lastBit = 0; //set first clock check int lastBit = 0; //set first clock check
@ -411,29 +419,32 @@ int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert)
return errCnt; return errCnt;
} }
//translate wave to 11111100000 (1 for each short wave 0 for each long wave) //translate wave to 11111100000 (1 for each short wave 0 for each long wave)
size_t fsk_wave_demod(uint8_t * dest, size_t size) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow)
{ {
uint32_t last_transition = 0; uint32_t last_transition = 0;
uint32_t idx = 1; uint32_t idx = 1;
uint32_t maxVal=0; uint32_t maxVal=0;
if (fchigh==0) fchigh=10;
if (fclow==0) fclow=8;
// we do care about the actual theshold value as sometimes near the center of the // we do care about the actual theshold value as sometimes near the center of the
// wave we may get static that changes direction of wave for one value // wave we may get static that changes direction of wave for one value
// if our value is too low it might affect the read. and if our tag or // if our value is too low it might affect the read. and if our tag or
// antenna is weak a setting too high might not see anything. [marshmellow] // antenna is weak a setting too high might not see anything. [marshmellow]
if (size<100) return 0; if (size<100) return 0;
for(idx=1; idx<100; idx++){ for(idx=1; idx<100; idx++){
if(maxVal<dest[idx]) maxVal = dest[idx]; if(maxVal<dest[idx]) maxVal = dest[idx];
} }
// set close to the top of the wave threshold with 13% margin for error // set close to the top of the wave threshold with 25% margin for error
// less likely to get a false transition up there. // less likely to get a false transition up there.
// (but have to be careful not to go too high and miss some short waves) // (but have to be careful not to go too high and miss some short waves)
uint8_t threshold_value = (uint8_t)(maxVal*.87); idx=1; uint8_t threshold_value = (uint8_t)(((maxVal-128)*.75)+128);
// idx=1;
//uint8_t threshold_value = 127; //uint8_t threshold_value = 127;
// sync to first lo-hi transition, and threshold // sync to first lo-hi transition, and threshold
// Need to threshold first sample // Need to threshold first sample
if(dest[0] < threshold_value) dest[0] = 0; if(dest[0] < threshold_value) dest[0] = 0;
else dest[0] = 1; else dest[0] = 1;
@ -443,14 +454,15 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size)
// between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
for(idx = 1; idx < size; idx++) { for(idx = 1; idx < size; idx++) {
// threshold current value // threshold current value
if (dest[idx] < threshold_value) dest[idx] = 0; if (dest[idx] < threshold_value) dest[idx] = 0;
else dest[idx] = 1; else dest[idx] = 1;
// Check for 0->1 transition // Check for 0->1 transition
if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
if (idx-last_transition<6){ //0-5 = garbage noise if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise
//do nothing with extra garbage //do nothing with extra garbage
} else if (idx-last_transition < 9) { //6-8 = 8 waves } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
dest[numBits]=1; dest[numBits]=1;
} else { //9+ = 10 waves } else { //9+ = 10 waves
dest[numBits]=0; dest[numBits]=0;
@ -469,7 +481,7 @@ uint32_t myround2(float f)
} }
//translate 11111100000 to 10 //translate 11111100000 to 10
size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value,
{ {
uint8_t lastval=dest[0]; uint8_t lastval=dest[0];
uint32_t idx=0; uint32_t idx=0;
@ -484,10 +496,10 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxCons
} }
//if lastval was 1, we have a 1->0 crossing //if lastval was 1, we have a 1->0 crossing
if ( dest[idx-1]==1 ) { if ( dest[idx-1]==1 ) {
n=myround2((float)(n+1)/((float)(rfLen)/(float)8)); n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
//n=(n+1) / h2l_crossing_value; //n=(n+1) / h2l_crossing_value;
} else {// 0->1 crossing } else {// 0->1 crossing
n=myround2((float)(n+1)/((float)(rfLen-2)/(float)10)); //-2 for fudge factor n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor
//n=(n+1) / l2h_crossing_value; //n=(n+1) / l2h_crossing_value;
} }
if (n == 0) n = 1; if (n == 0) n = 1;
@ -508,23 +520,11 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxCons
} }
//by marshmellow (from holiman's base) //by marshmellow (from holiman's base)
// full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod)
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow)
{ {
//uint8_t h2l_crossing_value = 6; // FSK demodulator
//uint8_t l2h_crossing_value = 5; size = fsk_wave_demod(dest, size, fchigh, fclow);
size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow);
// if (rfLen==64) //currently only know settings for RF/64 change from default if option entered
// {
// h2l_crossing_value=8; //or 8 as 64/8 = 8
// l2h_crossing_value=6; //or 6.4 as 64/10 = 6.4
// }
// size_t size = GraphTraceLen;
// FSK demodulator
size = fsk_wave_demod(dest, size);
size = aggregate_bits(dest, size,rfLen,192,invert);
// size = aggregate_bits(size, h2l_crossing_value, l2h_crossing_value,192, invert); //192=no limit to same values
//done messing with GraphBuffer - repaint
//RepaintGraphWindow();
return size; return size;
} }
// loop to get raw HID waveform then FSK demodulate the TAG ID from it // loop to get raw HID waveform then FSK demodulate the TAG ID from it
@ -533,7 +533,7 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_
size_t idx=0; //, found=0; //size=0, size_t idx=0; //, found=0; //size=0,
// FSK demodulator // FSK demodulator
size = fskdemod(dest, size,50,0); size = fskdemod(dest, size,50,0,10,8);
// final loop, go over previously decoded manchester data and decode into usable tag ID // final loop, go over previously decoded manchester data and decode into usable tag ID
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
@ -594,17 +594,18 @@ int IOdemodFSK(uint8_t *dest, size_t size)
{ {
uint32_t idx=0; uint32_t idx=0;
//make sure buffer has data //make sure buffer has data
if (size < 64) return -1; if (size < 66) return -1;
//test samples are not just noise //test samples are not just noise
uint8_t testMax=0; uint8_t testMax=0;
for(idx=0;idx<64;idx++){ for(idx=0;idx<65;idx++){
if (testMax<dest[idx]) testMax=dest[idx]; if (testMax<dest[idx]) testMax=dest[idx];
} }
idx=0; idx=0;
//if not just noise //if not just noise
if (testMax>170){ if (testMax>170){
// FSK demodulator // FSK demodulator
size = fskdemod(dest, size,64,1); size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert
if (size < 65) return -1; //did we get a good demod?
//Index map //Index map
//0 10 20 30 40 50 60 //0 10 20 30 40 50 60
//| | | | | | | //| | | | | | |
@ -615,7 +616,7 @@ int IOdemodFSK(uint8_t *dest, size_t size)
//XSF(version)facility:codeone+codetwo //XSF(version)facility:codeone+codetwo
//Handle the data //Handle the data
uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1};
for( idx=0; idx < (size - 74); idx++) { for( idx=0; idx < (size - 65); idx++) {
if ( memcmp(dest + idx, mask, sizeof(mask))==0) { if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
//frame marker found //frame marker found
if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){
@ -632,33 +633,36 @@ int IOdemodFSK(uint8_t *dest, size_t size)
// by marshmellow // by marshmellow
// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
// maybe somehow adjust peak trimming value based on samples to fix? // maybe somehow adjust peak trimming value based on samples to fix?
int DetectClock2(uint8_t dest[], size_t size, int clock) int DetectASKClock(uint8_t dest[], size_t size, int clock)
{ {
int i=0; int i=0;
int peak=0; int peak=0;
int low=0; int low=128;
int clk[]={16,32,40,50,64,100,128,256}; int clk[]={16,32,40,50,64,100,128,256};
int loopCnt = 256; //don't need to loop through entire array...
if (size<loopCnt) loopCnt = size;
//if we already have a valid clock quit
for (;i<8;++i) for (;i<8;++i)
if (clk[i]==clock) return clock; if (clk[i]==clock) return clock;
if (!peak){
for (i=0;i<size;++i){ //get high and low peak
if(dest[i]>peak){ for (i=0;i<loopCnt;++i){
peak = dest[i]; if(dest[i]>peak){
} peak = dest[i];
if(dest[i]<low){ }
low = dest[i]; if(dest[i]<low){
} low = dest[i];
} }
peak=(int)(peak*.75);
low= (int)(low*.75);
} }
peak=(int)((peak-128)*.75)+128;
low= (int)((low-128)*.75)+128;
int ii; int ii;
int loopCnt = 256;
if (size<loopCnt) loopCnt = size;
int clkCnt; int clkCnt;
int tol = 0; int tol = 0;
int bestErr=1000; int bestErr=1000;
int errCnt[]={0,0,0,0,0,0,0,0}; int errCnt[]={0,0,0,0,0,0,0,0};
//test each valid clock from smallest to greatest to see which lines up
for(clkCnt=0; clkCnt<6;++clkCnt){ for(clkCnt=0; clkCnt<6;++clkCnt){
if (clk[clkCnt]==32){ if (clk[clkCnt]==32){
tol=1; tol=1;
@ -666,22 +670,25 @@ int DetectClock2(uint8_t dest[], size_t size, int clock)
tol=0; tol=0;
} }
bestErr=1000; bestErr=1000;
//try lining up the peaks by moving starting point (try first 256)
for (ii=0; ii<loopCnt; ++ii){ for (ii=0; ii<loopCnt; ++ii){
if ((dest[ii]>=peak) || (dest[ii]<=low)){ if ((dest[ii]>=peak) || (dest[ii]<=low)){
errCnt[clkCnt]=0; errCnt[clkCnt]=0;
// now that we have the first one lined up test rest of wave array
for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){
if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
}else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
}else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
}else{ //error no peak detected }else{ //error no peak detected
errCnt[clkCnt]++; errCnt[clkCnt]++;
} }
} }
//if we found no errors this is correct one - return this clock
if(errCnt[clkCnt]==0) return clk[clkCnt]; if(errCnt[clkCnt]==0) return clk[clkCnt];
//if we found errors see if it is lowest so far and save it as best run
if(errCnt[clkCnt]<bestErr) bestErr=errCnt[clkCnt]; if(errCnt[clkCnt]<bestErr) bestErr=errCnt[clkCnt];
} }
} }
errCnt[clkCnt]=bestErr;
} }
int iii=0; int iii=0;
int best=0; int best=0;

View file

@ -11,18 +11,15 @@
#define LFDEMOD_H__ #define LFDEMOD_H__
#include <stdint.h> #include <stdint.h>
int DetectClock2(uint8_t dest[], size_t size, int clock); int DetectASKClock(uint8_t dest[], size_t size, int clock);
int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert);
uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen);
int manrawdemod(uint8_t *BitStream, int *bitLen); int manrawdecode(uint8_t *BitStream, int *bitLen);
int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset);
int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert);
int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int IOdemodFSK(uint8_t *dest, size_t size); int IOdemodFSK(uint8_t *dest, size_t size);
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert); int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
uint32_t bytebits_to_byte(uint8_t* src, int numbits); uint32_t bytebits_to_byte(uint8_t* src, int numbits);
//
//#define MAX_BitStream_LEN (1024*128)
//extern int BitStreamLen;
#endif #endif

16000
traces/Casi-12ed825c29.pm3 Normal file

File diff suppressed because it is too large Load diff

40000
traces/EM4102-Fob.pm3 Normal file

File diff suppressed because it is too large Load diff

20000
traces/indala-504278295.pm3 Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff