From: Martin Holst Swende Date: Mon, 9 Feb 2015 19:28:12 +0000 (+0100) Subject: Merge pull request #59 from marshmellow42/master X-Git-Tag: v2.0.0-rc1~26 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/904a96cd80788b29a32c7bbcde07a07d2a6e6511?hp=0c8d25ebd826f709b8e6cc2c8c1f185c633e326c Merge pull request #59 from marshmellow42/master lf demod additions/fixes --- diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 479da772..e34eab35 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -640,7 +640,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) uint8_t *dest = BigBuf_get_addr(); size_t size=0, idx=0; - int clk=0, invert=0, errCnt=0; + int clk=0, invert=0, errCnt=0, maxErr=20; uint64_t lo=0; // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); @@ -654,7 +654,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) size = BigBuf_max_traceLen(); //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode - errCnt = askmandemod(dest, &size, &clk, &invert); + errCnt = askmandemod(dest, &size, &clk, &invert, maxErr); //Dbprintf("DEBUG: ASK Got"); WDT_HIT(); diff --git a/client/cmddata.c b/client/cmddata.c index 430afb17..1bd3f6de 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -60,7 +60,7 @@ void printDemodBuff() if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty // ensure equally divided by 16 - bitLen &= 0xfff0; + bitLen &= 0xfff0; for (i = 0; i <= (bitLen-16); i+=16) { PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", @@ -188,36 +188,36 @@ int Cmdaskdemod(const char *Cmd) //by marshmellow void printBitStream(uint8_t BitStream[], uint32_t bitLen) { - uint32_t i = 0; - if (bitLen<16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen>512) bitLen=512; - - // ensure equally divided by 16 - bitLen &= 0xfff0; + uint32_t i = 0; + if (bitLen<16) { + PrintAndLog("Too few bits found: %d",bitLen); + return; + } + if (bitLen>512) bitLen=512; + // ensure equally divided by 16 + bitLen &= 0xfff0; - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } + + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } return; } //by marshmellow @@ -225,72 +225,141 @@ void printBitStream(uint8_t BitStream[], uint32_t bitLen) void printEM410x(uint64_t id) { if (id !=0){ - uint64_t iii=1; - uint64_t id2lo=0; - uint32_t ii=0; - uint32_t i=0; - for (ii=5; ii>0;ii--){ - for (i=0;i<8;i++){ - id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); - } + uint64_t iii=1; + uint64_t id2lo=0; + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); - PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); - PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); - PrintAndLog("DEZ 14/IK2 : %014lld",id); - PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); - PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); - } - return; + } + //output em id + PrintAndLog("EM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID: %010llx", id2lo); + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); + PrintAndLog("DEZ 14/IK2 : %014lld",id); + PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); + PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); + } + return; } //by marshmellow -//take binary from demod buffer and see if we can find an EM410x ID -int CmdEm410xDecode(const char *Cmd) +//takes 3 arguments - clock, invert and maxErr as integers +//attempts to demodulate ask while decoding manchester +//prints binary found and saves in graphbuffer for further commands +int CmdAskEM410xDemod(const char *Cmd) { - uint64_t id=0; - size_t size = DemodBufferLen, idx=0; - id = Em410xDecode(DemodBuffer, &size, &idx); - if (id>0){ - setDemodBuf(DemodBuffer, size, idx); + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer"); + PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data"); + PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); + + return 0; + } + + + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + size_t BitLen = getFromGraphBuf(BitStream); + + if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt<0||BitLen<16){ //if fatal error (or -1) + if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + return 0; + } + PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); + + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + //PrintAndLog("ASK/Manchester decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + setDemodBuf(BitStream,BitLen,0); + //printDemodBuff(); + uint64_t lo =0; + size_t idx=0; + lo = Em410xDecode(BitStream, &BitLen, &idx); + if (lo>0){ + //set GraphBuffer for clone or sim command + setDemodBuf(BitStream, BitLen, idx); if (g_debugMode){ - PrintAndLog("DEBUG: Printing demod buffer:"); + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); printDemodBuff(); } - printEM410x(id); - return 1; + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; } return 0; } - //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 3 arguments - clock, invert, maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { int invert=0; - int clk=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askmandemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askmandemod = demod an ask/manchester tag from GraphBuffer"); + PrintAndLog(" : data askmandemod 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askmandemod 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askmandemod 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askmandemod 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } - - size_t BitLen = getFromGraphBuf(BitStream); + if (clk==1){ + invert=1; + clk=0; + } + size_t BitLen = getFromGraphBuf(BitStream); if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0||BitLen<16){ //if fatal error (or -1) - if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt<0||BitLen<16){ //if fatal error (or -1) + if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; - } + } PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); //output @@ -299,8 +368,8 @@ int Cmdaskmandemod(const char *Cmd) } PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits - setDemodBuf(BitStream,BitLen,0); - printDemodBuff(); + setDemodBuf(BitStream,BitLen,0); + printDemodBuff(); uint64_t lo =0; size_t idx=0; lo = Em410xDecode(BitStream, &BitLen, &idx); @@ -315,7 +384,7 @@ int Cmdaskmandemod(const char *Cmd) printEM410x(lo); return 1; } - return 0; + return 1; } //by marshmellow @@ -325,31 +394,42 @@ int Cmdmandecoderaw(const char *Cmd) { int i =0; int errCnt=0; - size_t size=0; + size_t size=0; + size_t maxErr = 20; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data manrawdecode"); + PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); + return 0; + } + if (DemodBufferLen==0) return 0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; - for (;ihigh) high=DemodBuffer[i]; - else if(DemodBuffer[i]high) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); return 0; } - size=i; - errCnt=manrawdecode(BitStream, &size); - if (errCnt>=20){ + size=i; + errCnt=manrawdecode(BitStream, &size); + if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; } PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream, size); + printBitStream(BitStream, size); if (errCnt==0){ - uint64_t id = 0; + uint64_t id = 0; size_t idx=0; - id = Em410xDecode(BitStream, &size, &idx); - if (id>0){ + id = Em410xDecode(BitStream, &size, &idx); + if (id>0){ //need to adjust to set bitstream back to manchester encoded data //setDemodBuf(BitStream, size, idx); @@ -371,66 +451,106 @@ int Cmdmandecoderaw(const char *Cmd) // width waves vs small width waves to help the decode positioning) or askbiphdemod int CmdBiphaseDecodeRaw(const char *Cmd) { - int i = 0; - int errCnt=0; + int i = 0; + int errCnt=0; size_t size=0; - int offset=0; - int invert=0; - int high=0, low=0; + int offset=0; + int invert=0; + int high=0, low=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data biphaserawdecode [offset] "); + PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position"); + PrintAndLog(" [invert <0|1>], set to 1 to invert output"); + PrintAndLog(""); + PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer"); + PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output"); + return 0; + } sscanf(Cmd, "%i %i", &offset, &invert); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - //get graphbuffer & high and low + if (DemodBufferLen==0) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + //get graphbuffer & high and low for (;ihigh)high=DemodBuffer[i]; else if(DemodBuffer[i]1 || low <0){ - PrintAndLog("Error: please raw demod the wave first then decode"); - return 0; - } + } + if (high>1 || low <0){ + PrintAndLog("Error: please raw demod the wave first then decode"); + return 0; + } size=i; errCnt=BiphaseRawDecode(BitStream, &size, offset, invert); - if (errCnt>=20){ - PrintAndLog("Too many errors attempting to decode: %d",errCnt); - return 0; - } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + if (errCnt>=20){ + PrintAndLog("Too many errors attempting to decode: %d",errCnt); + return 0; + } + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); printBitStream(BitStream, size); - PrintAndLog("\nif bitstream does not look right try offset=1"); - return 1; + PrintAndLog("\nif bitstream does not look right try offset=1"); + return 1; } //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 4 arguments - clock, invert, maxErr as integers and amplify as char //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert=0; - int clk=0; + int invert=0; + int clk=0; + int maxErr=100; + uint8_t askAmp = 0; + char amp = param_getchar(Cmd, 0); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askrawdemod [clock] [maxError] [amplify]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); + PrintAndLog(""); + PrintAndLog(" sample: data askrawdemod = demod an ask tag from GraphBuffer"); + PrintAndLog(" : data askrawdemod a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLog(" : data askrawdemod 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askrawdemod 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askrawdemod 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLog(" : data askrawdemod 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data askrawdemod 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + return 0; + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); + sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; } - size_t BitLen = getFromGraphBuf(BitStream); + if (clk==1){ + invert=1; + clk=0; + } + if (amp == 'a' || amp == 'A') askAmp=1; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); - if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - PrintAndLog("no data found"); + errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + PrintAndLog("no data found"); if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); return 0; - } - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + } + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //move BitStream back to DemodBuffer - setDemodBuf(BitStream,BitLen,0); + setDemodBuf(BitStream,BitLen,0); - //output + //output 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); } PrintAndLog("ASK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@ -516,7 +636,7 @@ int CmdBitstream(const char *Cmd) } /* Get our clock */ - clock = GetClock(Cmd, high, 1); + clock = GetAskClock(Cmd, high, 1); gtl = ClearGraph(0); bit = 0; @@ -630,20 +750,70 @@ int CmdGraphShiftZero(const char *Cmd) return 0; } +//by marshmellow +//use large jumps in read samples to identify edges of waves and then amplify that wave to max +//similar to dirtheshold, threshold, and askdemod commands +//takes a threshold length which is the measured length between two samples then determines an edge +int CmdAskEdgeDetect(const char *Cmd) +{ + int thresLen = 25; + sscanf(Cmd, "%i", &thresLen); + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=thresLen) //large jump up + shift=127; + else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down + shift=-127; + + shiftedVal=GraphBuffer[i]+shift; + + if (shiftedVal>127) + shiftedVal=127; + else if (shiftedVal<-127) + shiftedVal=-127; + GraphBuffer[i-1] = shiftedVal; + } + RepaintGraphWindow(); + //CmdNorm(""); + return 0; +} + /* Print our clock rate */ // uses data from graphbuffer +// adjusted to take char parameter for type of modulation to find the clock - by marshmellow. int CmdDetectClockRate(const char *Cmd) { - GetClock("",0,0); - //int clock = DetectASKClock(0); - //PrintAndLog("Auto-detected clock rate: %d", clock); - return 0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 3 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data detectclock [modulation]"); + PrintAndLog(" [modulation as char], specify the modulation type you want to detect the clock of"); + PrintAndLog(" 'a' = ask, 'f' = fsk, 'n' = nrz/direct, 'p' = psk"); + PrintAndLog(""); + PrintAndLog(" sample: data detectclock a = detect the clock of an ask modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock f = detect the clock of an fsk modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock p = detect the clock of an psk modulated wave in the GraphBuffer"); + PrintAndLog(" data detectclock n = detect the clock of an nrz/direct modulated wave in the GraphBuffer"); + } + int ans=0; + if (cmdp == 'a'){ + ans = GetAskClock("", true, false); + } else if (cmdp == 'f'){ + ans = GetFskClock("", true, false); + } else if (cmdp == 'n'){ + ans = GetNrzClock("", true, false); + } else if (cmdp == 'p'){ + ans = GetPskClock("", true, false); + } else { + PrintAndLog ("Please specify a valid modulation to detect the clock of - see option h for help"); + } + return ans; } //by marshmellow //fsk raw demod and print binary -//takes 4 arguments - Clock, invert, rchigh, rclow -//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) +//takes 4 arguments - Clock, invert, fchigh, fclow +//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave @@ -652,22 +822,41 @@ int CmdFSKrawdemod(const char *Cmd) int invert=0; int fchigh=0; int fclow=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data fskrawdemod [clock] [fchigh] [fclow]"); + PrintAndLog(" [set clock as integer] optional, omit for autodetect."); + PrintAndLog(" , 1 for invert output, can be used even if the clock is omitted"); + PrintAndLog(" [fchigh], larger field clock length, omit for autodetect"); + PrintAndLog(" [fclow], small field clock length, omit for autodetect"); + PrintAndLog(""); + PrintAndLog(" sample: data fskrawdemod = demod an fsk tag from GraphBuffer using autodetect"); + PrintAndLog(" : data fskrawdemod 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); + PrintAndLog(" : data fskrawdemod 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); + PrintAndLog(" : data fskrawdemod 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); + PrintAndLog(" : data fskrawdemod 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); + PrintAndLog(" : data fskrawdemod 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); + return 0; + } //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); + sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (rfLen==1){ invert=1; //if invert option only is used rfLen = 0; } - } + } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get field clock lengths uint16_t fcs=0; + uint8_t dummy=0; if (fchigh==0 || fclow == 0){ - fcs=countFC(BitStream, BitLen); + fcs=countFC(BitStream, BitLen, &dummy); if (fcs==0){ fchigh=10; fclow=8; @@ -682,14 +871,15 @@ int CmdFSKrawdemod(const char *Cmd) if (rfLen == 0) rfLen = 50; } PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); + int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ PrintAndLog("FSK decoded bitstream:"); - setDemodBuf(BitStream,size,0); + setDemodBuf(BitStream,size,0); // Now output the bitstream to the scrollback by line of 16 bits 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 printBitStream(BitStream,size); + return 1; } else{ PrintAndLog("no FSK data found"); } @@ -705,13 +895,14 @@ int CmdFSKdemodHID(const char *Cmd) uint32_t hi2=0, hi=0, lo=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave - int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); + int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ if (g_debugMode){ if (idx==-1){ - PrintAndLog("DEBUG: Just Noise Detected"); + PrintAndLog("DEBUG: Just Noise Detected"); } else if (idx == -2) { PrintAndLog("DEBUG: Error demoding fsk"); } else if (idx == -3) { @@ -729,7 +920,7 @@ int CmdFSKdemodHID(const char *Cmd) return 0; } if (hi2 != 0){ //extra large HID tags - PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", + PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); } else { //standard HID tags <38 bits @@ -744,7 +935,7 @@ int CmdFSKdemodHID(const char *Cmd) lo2=lo2>>1; idx3++; } - fmtLen =idx3+19; + fmtLen =idx3+19; fc =0; cardnum=0; if(fmtLen==26){ @@ -768,8 +959,8 @@ int CmdFSKdemodHID(const char *Cmd) cardnum = (lo>>1)&0x7FFFF; fc = ((hi&0xF)<<12)|(lo>>20); } - } - PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + } + PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); } @@ -791,6 +982,7 @@ int CmdFSKdemodParadox(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo); if (idx<0){ @@ -826,7 +1018,6 @@ int CmdFSKdemodParadox(const char *Cmd) return 1; } - //by marshmellow //IO-Prox demod - FSK RF/64 with preamble of 000000001 //print ioprox ID and some format details @@ -834,17 +1025,18 @@ int CmdFSKdemodIO(const char *Cmd) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave //set defaults - int idx=0; + int idx=0; //something in graphbuffer? if (GraphTraceLen < 65) { if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer"); return 0; } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; //get binary from fsk wave - idx = IOdemodFSK(BitStream,BitLen); + idx = IOdemodFSK(BitStream,BitLen); if (idx<0){ if (g_debugMode){ if (idx==-1){ @@ -884,7 +1076,7 @@ int CmdFSKdemodIO(const char *Cmd) 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+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 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 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 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]); @@ -892,20 +1084,19 @@ int CmdFSKdemodIO(const char *Cmd) 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 code2 = bytebits_to_byte(BitStream+idx+32,32); + uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 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 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); setDemodBuf(BitStream,64,idx); - if (g_debugMode){ + if (g_debugMode){ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64); printDemodBuff(); } - return 1; + return 1; } - //by marshmellow //AWID Prox demod - FSK RF/50 with preamble of 00000001 (always a 96 bit data stream) //print full AWID Prox ID and some bit format details if found @@ -918,6 +1109,7 @@ int CmdFSKdemodAWID(const char *Cmd) //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = AWIDdemodFSK(BitStream, &size); @@ -929,8 +1121,6 @@ int CmdFSKdemodAWID(const char *Cmd) PrintAndLog("DEBUG: Error - only noise found"); else if (idx == -3) PrintAndLog("DEBUG: Error - problem during FSK demod"); - // else if (idx == -3) - // PrintAndLog("Error: thought we had a tag but the parity failed"); else if (idx == -4) PrintAndLog("DEBUG: Error - AWID preamble not found"); else if (idx == -5) @@ -1017,6 +1207,7 @@ int CmdFSKdemodPyramid(const char *Cmd) //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; //get binary from fsk wave int idx = PyramiddemodFSK(BitStream, &size); @@ -1251,92 +1442,68 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating } //by marshmellow -//attempt to detect the field clock and bit clock for FSK -int CmdFSKfcDetect(const char *Cmd) +//attempt to psk1 demod graph buffer +int PSKDemod(const char *Cmd, uint8_t verbose) { - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(BitStream); - - uint16_t ans = countFC(BitStream, size); - if (ans==0) { - if (g_debugMode) PrintAndLog("DEBUG: No data found"); - return 0; + int invert=0; + int clk=0; + int maxErr=100; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; } - uint8_t fc1, fc2; - fc1 = (ans >> 8) & 0xFF; - fc2 = ans & 0xFF; - - uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2); - if (rf1==0) { - if (g_debugMode) PrintAndLog("DEBUG: Clock detect error"); - return 0; + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; } - PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); - return 1; -} - -//by marshmellow -//attempt to detect the bit clock for PSK or NRZ modulations -int CmdDetectNRZpskClockRate(const char *Cmd) -{ - GetNRZpskClock("",0,0); - return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = pskRawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + return errCnt; } -//by marshmellow -//attempt to psk1 or nrz demod graph buffer -//NOTE CURRENTLY RELIES ON PEAKS :( -int PSKnrzDemod(const char *Cmd, uint8_t verbose) -{ - int invert=0; - int clk=0; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); - return -1; - } - if (verbose) PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); - - //prime demod buffer for output - setDemodBuf(BitStream,BitLen,0); - return errCnt; -} // Indala 26 bit decode // by marshmellow // optional arguments - same as CmdpskNRZrawDemod (clock & invert) int CmdIndalaDecode(const char *Cmd) { - int ans; - if (strlen(Cmd)>0){ - ans = PSKnrzDemod(Cmd, 0); - } else{ //default to RF/32 - ans = PSKnrzDemod("32", 0); - } + int ans; + if (strlen(Cmd)>0){ + ans = PSKDemod(Cmd, 0); + } else{ //default to RF/32 + ans = PSKDemod("32", 0); + } if (ans < 0){ if (g_debugMode==1) - PrintAndLog("Error1: %d",ans); + PrintAndLog("Error1: %d",ans); return 0; } uint8_t invert=0; ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert); if (ans < 1) { if (g_debugMode==1) - PrintAndLog("Error2: %d",ans); + PrintAndLog("Error2: %d",ans); return -1; } char showbits[251]={0x00}; if (invert) - if (g_debugMode==1) - PrintAndLog("Had to invert bits"); + if (g_debugMode==1) + PrintAndLog("Had to invert bits"); //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; @@ -1383,53 +1550,109 @@ int CmdIndalaDecode(const char *Cmd) showbits[idx]='\0'; PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); } - if (g_debugMode){ - PrintAndLog("DEBUG: printing demodbuffer:"); - printDemodBuff(); - } + if (g_debugMode){ + PrintAndLog("DEBUG: printing demodbuffer:"); + printDemodBuff(); + } return 1; } -//by marshmellow -//attempt to clean psk wave noise after a peak -//NOTE RELIES ON PEAKS :( -int CmdPskClean(const char *Cmd) +// by marshmellow +// takes 3 arguments - clock, invert, maxErr as integers +// attempts to demodulate nrz only +// prints binary found and saves in demodbuffer for further commands +int CmdNRZrawDemod(const char *Cmd) { - uint8_t bitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t bitLen = getFromGraphBuf(bitStream); - pskCleanWave(bitStream, bitLen); - setGraphBuf(bitStream, bitLen); - return 0; + int invert=0; + int clk=0; + int maxErr=100; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data nrzrawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer"); + PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); + PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + + return 0; + } + + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (clk==1){ + invert=1; + clk=0; + } + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt > maxErr){ + if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + }else{ + } + PrintAndLog("NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; } // by marshmellow -// takes 2 arguments - clock and invert both as integers +// takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate psk only // prints binary found and saves in demodbuffer for further commands -int CmdpskNRZrawDemod(const char *Cmd) +int CmdPSK1rawDemod(const char *Cmd) { int errCnt; - - errCnt = PSKnrzDemod(Cmd, 1); - //output - if (errCnt<0){ - if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk1rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk1rawdemod = demod a psk1 tag from GraphBuffer"); + PrintAndLog(" : data psk1rawdemod 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk1rawdemod 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data psk1rawdemod 1 = demod a psk1 tag from GraphBuffer while inverting data"); + PrintAndLog(" : data psk1rawdemod 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return 0; - } - if (errCnt>0){ - if (g_debugMode){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - } - }else{ - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - return 1; } - return 0; + errCnt = PSKDemod(Cmd, 1); + //output + if (errCnt<0){ + if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); + return 0; + } + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + }else{ + } + PrintAndLog("PSK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + return 1; } // by marshmellow @@ -1437,7 +1660,21 @@ int CmdpskNRZrawDemod(const char *Cmd) int CmdPSK2rawDemod(const char *Cmd) { int errCnt=0; - errCnt=PSKnrzDemod(Cmd, 1); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data psk2rawdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data psk2rawdemod = demod a psk2 tag from GraphBuffer, autodetect clock"); + PrintAndLog(" : data psk2rawdemod 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data psk2rawdemod 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); + PrintAndLog(" : data psk2rawdemod 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); + PrintAndLog(" : data psk2rawdemod 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); + return 0; + } + errCnt=PSKDemod(Cmd, 1); if (errCnt<0){ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); return 0; @@ -1505,8 +1742,8 @@ int CmdHexsamples(const char *Cmd) *(string_ptr - 1) = '\0'; PrintAndLog("%s", string_buf); string_buf[0] = '\0'; + } } - } return 0; } @@ -1650,12 +1887,12 @@ int CmdTuneSamples(const char *Cmd) GraphBuffer[i] = resp.d.asBytes[i] - 128; } - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); + PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); GraphTraceLen = 256; ShowGraphWindow(); - return 0; + return 0; } @@ -1766,7 +2003,7 @@ int CmdManchesterDemod(const char *Cmd) } /* Get our clock */ - clock = GetClock(Cmd, high, 1); + clock = GetAskClock(Cmd, high, 1); int tolerance = clock/4; @@ -1926,7 +2163,7 @@ int CmdManchesterMod(const char *Cmd) int bit, lastbit, wave; /* Get our clock */ - clock = GetClock(Cmd, 0, 1); + clock = GetAskClock(Cmd, 0, 1); wave = 0; lastbit = 1; @@ -2028,8 +2265,8 @@ int CmdThreshold(const char *Cmd) int CmdDirectionalThreshold(const char *Cmd) { - int8_t upThres = param_get8(Cmd, 0); - int8_t downThres = param_get8(Cmd, 1); + int8_t upThres = param_get8(Cmd, 0); + int8_t downThres = param_get8(Cmd, 1); printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); @@ -2095,25 +2332,27 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, - {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"}, + {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave - default = 25"}, + {"askem410xdemod",CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, + {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in demod buffer (offset = 0|1 bits to shift the decode start)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate graph window as an AWID FSK tag using raw"}, - {"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, + //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK tag using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox tag FSK using raw"}, {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate graph window as a Pyramid FSK tag using raw"}, {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate graph window as a Paradox FSK tag using raw"}, {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"}, @@ -2122,23 +2361,24 @@ static command_t CommandTable[] = {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, + //{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"nrzrawdemod", CmdNRZrawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, - {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 indala tags and output ID binary & hex (args optional)"}, - {"psk1nrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 or nrz tags and output binary (args optional)"}, - {"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk2 tags and output binary (args optional)"}, + //{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 indala tags and output ID binary & hex (args optional)"}, + {"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"}, + {"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, {"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"}, {"shiftgraphzero",CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, - {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmddata.h b/client/cmddata.h index 514be3a2..29b3bbc9 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -17,6 +17,7 @@ int CmdData(const char *Cmd); void printDemodBuff(); int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); +int CmdAskEM410xDemod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); int Cmdaskmandemod(const char *Cmd); int CmdAutoCorr(const char *Cmd); @@ -33,8 +34,8 @@ int CmdFSKdemodIO(const char *Cmd); int CmdFSKdemodParadox(const char *Cmd); int CmdFSKdemodPyramid(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); -int CmdDetectNRZpskClockRate(const char *Cmd); -int CmdpskNRZrawDemod(const char *Cmd); +int CmdPSK1rawDemod(const char *Cmd); +int CmdPSK2rawDemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd); @@ -46,6 +47,7 @@ int Cmdmandecoderaw(const char *Cmd); int CmdManchesterDemod(const char *Cmd); int CmdManchesterMod(const char *Cmd); int CmdNorm(const char *Cmd); +int CmdNRZrawDemod(const char *Cmd); int CmdPlot(const char *Cmd); int CmdSamples(const char *Cmd); int CmdTuneSamples(const char *Cmd); diff --git a/client/cmdlf.c b/client/cmdlf.c index f56aa1b7..b7c1b13f 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -662,26 +662,31 @@ int CmdVchDemod(const char *Cmd) int CmdLFfind(const char *Cmd) { int ans=0; - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1>"); - PrintAndLog(" , if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf search"); - PrintAndLog(" : lf search 1"); - return 0; - } + char cmdp = param_getchar(Cmd, 0); + char testRaw = param_getchar(Cmd, 1); + if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: lf search <0|1> [u]"); + PrintAndLog(" , if not set, try reading data from tag."); + PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); + PrintAndLog(""); + PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); + PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); + PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); - if (!offline && (cmdp != '1')){ + return 0; + } + + if (!offline && (cmdp != '1')){ ans=CmdLFRead(""); ans=CmdSamples("20000"); - } else if (GraphTraceLen < 1000) { - PrintAndLog("Data in Graphbuffer was too small."); - return 0; + } else if (GraphTraceLen < 1000) { + PrintAndLog("Data in Graphbuffer was too small."); + return 0; } - + if (cmdp == 'u' || cmdp == 'U') testRaw = 'u'; PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("False Positives ARE possible\n"); PrintAndLog("\nChecking for known tags:\n"); ans=CmdFSKdemodIO(""); if (ans>0) { @@ -714,12 +719,37 @@ int CmdLFfind(const char *Cmd) PrintAndLog("\nValid Indala ID Found!"); return 1; } - ans=Cmdaskmandemod(""); + ans=CmdAskEM410xDemod(""); if (ans>0) { PrintAndLog("\nValid EM410x ID Found!"); return 1; } - PrintAndLog("No Known Tags Found!\n"); + PrintAndLog("\nNo Known Tags Found!\n"); + if (testRaw=='u' || testRaw=='U'){ + //test unknown tag formats (raw mode) + PrintAndLog("\nChecking for Unknown tags:\n"); + ans=CmdDetectClockRate("f"); + if (ans != 0){ //fsk + ans=CmdFSKrawdemod(""); + if (ans>0) { + PrintAndLog("\nUnknown FSK Modulated Tag Found!"); + return 1; + } + } + ans=Cmdaskmandemod(""); + if (ans>0) { + PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); + return 1; + } + ans=CmdPSK1rawDemod(""); + if (ans>0) { + PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'"); + PrintAndLog("\nCould also be PSK3 - [currently not supported]"); + PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); + return 1; + } + PrintAndLog("\nNo Data Found!\n"); + } return 0; } @@ -735,7 +765,7 @@ static command_t CommandTable[] = {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, {"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, - {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 95b0342d..232d5635 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -61,7 +61,7 @@ int CmdEM410xRead(const char *Cmd) } /* get clock */ - clock = GetClock(Cmd, high, 0); + clock = GetAskClock(Cmd, false, false); /* parity for our 4 columns */ parity[0] = parity[1] = parity[2] = parity[3] = 0; diff --git a/client/graph.c b/client/graph.c index 95050f55..11dbc4d5 100644 --- a/client/graph.c +++ b/client/graph.c @@ -56,52 +56,24 @@ void setGraphBuf(uint8_t *buff, size_t size) uint16_t i = 0; if ( size > MAX_GRAPH_TRACE_LEN ) size = MAX_GRAPH_TRACE_LEN; - ClearGraph(0); - for (; i < size; ++i){ + ClearGraph(0); + for (; i < size; ++i){ GraphBuffer[i]=buff[i]-128; - } - GraphTraceLen=size; - RepaintGraphWindow(); - return; + } + GraphTraceLen=size; + RepaintGraphWindow(); + return; } size_t getFromGraphBuf(uint8_t *buff) { - if ( buff == NULL ) return 0; - - uint32_t i; - for (i=0;i127) GraphBuffer[i]=127; //trim - if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim - buff[i]=(uint8_t)(GraphBuffer[i]+128); - } - return i; -} - - -// Get or auto-detect clock rate -int GetClock(const char *str, int peak, int verbose) -{ - int clock; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; - - // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(grph); - if ( size == 0 ) { - PrintAndLog("Failed to copy from graphbuffer"); - return -1; - } - clock = DetectASKClock(grph,size,0); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - } + if (buff == NULL ) return 0; + uint32_t i; + for (i=0;i127) GraphBuffer[i]=127; //trim + if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim + buff[i]=(uint8_t)(GraphBuffer[i]+128); } - return clock; + return i; } // A simple test to see if there is any data inside Graphbuffer. @@ -136,27 +108,116 @@ void DetectHighLowInGraph(int *high, int *low, bool addFuzz) { } } -int GetNRZpskClock(const char *str, int peak, int verbose) +// Get or auto-detect ask clock rate +int GetAskClock(const char str[], bool printAns, bool verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + if (clock != 0) + return clock; + // Auto-detect clock + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if (size == 0) { + if (verbose) + PrintAndLog("Failed to copy from graphbuffer"); + return -1; + } + DetectASKClock(grph, size, &clock, 20); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); + } + return clock; +} + +int GetPskClock(const char str[], bool printAns, bool verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + if (clock!=0) + return clock; + // Auto-detect clock + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if ( size == 0 ) { + if (verbose) + PrintAndLog("Failed to copy from graphbuffer"); + return -1; + } + clock = DetectPSKClock(grph,size,0); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); + } + return clock; +} + +uint8_t GetNrzClock(const char str[], bool printAns, bool verbose) { int clock; sscanf(str, "%i", &clock); if (!strcmp(str, "")) clock = 0; + if (clock!=0) + return clock; // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(grph); - if ( size == 0 ) { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + if ( size == 0 ) { + if (verbose) PrintAndLog("Failed to copy from graphbuffer"); - return -1; - } - clock = DetectpskNRZClock(grph,size,0); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - } + return -1; + } + clock = DetectNRZClock(grph, size, 0); + // Only print this message if we're not looping something + if (printAns){ + PrintAndLog("Auto-detected clock rate: %d", clock); } return clock; } +//by marshmellow +//attempt to detect the field clock and bit clock for FSK +uint8_t GetFskClock(const char str[], bool printAns, bool verbose) +{ + int clock; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + if (clock != 0) return (uint8_t)clock; + + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(BitStream); + if (size==0) return 0; + uint8_t dummy = 0; + uint16_t ans = countFC(BitStream, size, &dummy); + if (ans==0) { + if (verbose) PrintAndLog("DEBUG: No data found"); + return 0; + } + uint8_t fc1, fc2; + fc1 = (ans >> 8) & 0xFF; + fc2 = ans & 0xFF; + + uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2); + if (rf1==0) { + if (verbose) PrintAndLog("DEBUG: Clock detect error"); + return 0; + } + if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ + if (printAns) PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + return rf1; + } + if (verbose){ + PrintAndLog("DEBUG: unknown fsk field clock detected"); + PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + } + return 0; +} diff --git a/client/graph.h b/client/graph.h index 9817d776..e4872afc 100644 --- a/client/graph.h +++ b/client/graph.h @@ -16,8 +16,10 @@ void AppendGraph(int redraw, int clock, int bit); int ClearGraph(int redraw); //int DetectClock(int peak); size_t getFromGraphBuf(uint8_t *buff); -int GetClock(const char *str, int peak, int verbose); -int GetNRZpskClock(const char *str, int peak, int verbose); +int GetAskClock(const char str[], bool printAns, bool verbose); +int GetPskClock(const char str[], bool printAns, bool verbose); +uint8_t GetNrzClock(const char str[], bool printAns, bool verbose); +uint8_t GetFskClock(const char str[], bool printAns, bool verbose); void setGraphBuf(uint8_t *buff, size_t size); bool HasGraphData(); diff --git a/common/lfdemod.c b/common/lfdemod.c index 88a250d8..47e63ef6 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -50,7 +50,7 @@ uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) for (uint8_t i = 0; i < bitLen; i++){ ans ^= ((bits >> i) & 1); } - //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType); + //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType); return (ans == pType); } @@ -120,18 +120,19 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx) } //by marshmellow -//takes 2 arguments - clock and invert both as integers +//takes 3 arguments - clock, invert, maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr) { int i; - int clk2=*clk; - *clk=DetectASKClock(BinStream, *size, *clk); //clock default - + //int clk2=*clk; + int start = DetectASKClock(BinStream, *size, clk, 20); //clock default + if (*clk==0) return -3; + if (start < 0) return -3; // if autodetected too low then adjust //MAY NEED ADJUSTMENT - if (clk2==0 && *clk<8) *clk =64; - if (clk2==0 && *clk<32) *clk=32; + //if (clk2==0 && *clk<8) *clk =64; + //if (clk2==0 && *clk<32) *clk=32; if (*invert != 0 && *invert != 1) *invert=0; uint32_t initLoopMax = 200; if (initLoopMax > *size) initLoopMax=*size; @@ -145,14 +146,14 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) int lastBit = 0; //set first clock check uint32_t bitnum = 0; //output counter 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 int iii = 0; uint32_t gLen = *size; if (gLen > 3000) gLen=3000; uint8_t errCnt =0; + uint16_t MaxBits = 500; uint32_t bestStart = *size; - uint32_t bestErrCnt = (*size/1000); - uint32_t maxErr = (*size/1000); + int bestErrCnt = maxErr+1; // PrintAndLog("DEBUG - lastbit - %d",lastBit); // loop to find first wave that works for (iii=0; iii < gLen; ++iii){ @@ -179,10 +180,10 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over } } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits + if ((i-iii) >(MaxBits * *clk)) break; //got plenty of bits } //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt (64)) && (errCnt<=maxErr)) { //possible good read if (errCnt==0){ bestStart=iii; @@ -196,7 +197,7 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) } } } - if (bestErrCnt=400) break; + if (bitnum >=MaxBits) break; } *size=bitnum; } else{ @@ -243,14 +244,14 @@ int ManchesterEncode(uint8_t *BitStream, size_t size) { size_t modIdx=20000, i=0; if (size>modIdx) return -1; - for (size_t idx=0; idx < size; idx++){ - BitStream[idx+modIdx++] = BitStream[idx]; - BitStream[idx+modIdx++] = BitStream[idx]^1; - } - for (; i<(size*2); i++){ - BitStream[i] = BitStream[i+20000]; - } - return i; + for (size_t idx=0; idx < size; idx++){ + BitStream[idx+modIdx++] = BitStream[idx]; + BitStream[idx+modIdx++] = BitStream[idx]^1; + } + for (; i<(size*2); i++){ + BitStream[i] = BitStream[i+20000]; + } + return i; } //by marshmellow @@ -258,12 +259,14 @@ int ManchesterEncode(uint8_t *BitStream, size_t size) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, size_t *size) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; + uint16_t bitnum=0; + uint16_t MaxBits = 500; + uint16_t errCnt = 0; + size_t i=1; + uint16_t bestErr = 1000; + uint16_t bestRun = 0; + size_t ii=1; + if (size == 0) return -1; for (ii=1;ii<3;++ii){ i=1; for (i=i+ii;i<*size-2;i+=2){ @@ -272,7 +275,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) } else { errCnt++; } - if(bitnum>300) break; + if(bitnum>MaxBits) break; } if (bestErr>errCnt){ bestErr=errCnt; @@ -284,7 +287,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) if (errCnt<20){ ii=bestRun; i=1; - for (i=i+ii;i < *size-2;i+=2){ + for (i=i+ii; i < *size-2; i+=2){ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){ BitStream[bitnum++]=0; } else if((BitStream[i] == 0) && BitStream[i+1] == 1){ @@ -293,7 +296,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) BitStream[bitnum++]=77; //errCnt++; } - if(bitnum>300) break; + if(bitnum>MaxBits) break; } *size=bitnum; } @@ -304,10 +307,12 @@ int manrawdecode(uint8_t * BitStream, size_t *size) //take 01 or 10 = 0 and 11 or 00 = 1 int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) { - uint8_t bitnum=0; + uint16_t bitnum=0; uint32_t errCnt =0; uint32_t i; + uint16_t MaxBits=500; i=offset; + if (size == 0) return -1; for (;i<*size-2; i+=2){ if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ BitStream[bitnum++]=1^invert; @@ -317,56 +322,76 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) BitStream[bitnum++]=77; errCnt++; } - if(bitnum>250) break; + if(bitnum>MaxBits) break; } *size=bitnum; return errCnt; } //by marshmellow -//takes 2 arguments - clock and invert both as integers +void askAmp(uint8_t *BitStream, size_t size) +{ + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=30) //large jump up + shift=127; + else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down + shift=-127; + + shiftedVal=BitStream[i]+shift; + + if (shiftedVal>255) + shiftedVal=255; + else if (shiftedVal<0) + shiftedVal=0; + BitStream[i-1] = shiftedVal; + } + return; +} + +//by marshmellow +//takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp) { uint32_t i; - // int invert=0; //invert default - int clk2 = *clk; - *clk=DetectASKClock(BinStream, *size, *clk); //clock default - //uint8_t BitStream[502] = {0}; - - //HACK: if clock not detected correctly - default - if (clk2==0 && *clk<8) *clk =64; - if (clk2==0 && *clk<32 && clk2==0) *clk=32; + if (*size==0) return -1; + int start = DetectASKClock(BinStream, *size, clk, 20); //clock default + if (*clk==0) return -1; + if (start<0) return -1; if (*invert != 0 && *invert != 1) *invert =0; uint32_t initLoopMax = 200; if (initLoopMax > *size) initLoopMax=*size; // Detect high and lows //25% fuzz in case highs and lows aren't clipped [marshmellow] int high, low, ans; + if (amp==1) askAmp(BinStream, *size); ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75); - if (ans<1) return -2; //just noise + if (ans<1) return -1; //just noise //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); int lastBit = 0; //set first clock check 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 - if (*clk == 32) tol=1; //clock tolerance may not be needed anymore currently set to + if (*clk == 32) tol=0; //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; uint32_t gLen = *size; if (gLen > 500) gLen=500; uint8_t errCnt =0; uint32_t bestStart = *size; - uint32_t bestErrCnt = (*size/1000); - uint32_t maxErr = bestErrCnt; + uint32_t bestErrCnt = maxErr; //(*size/1000); uint8_t midBit=0; + uint16_t MaxBits=1000; //PrintAndLog("DEBUG - lastbit - %d",lastBit); //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ + for (iii=start; iii < gLen; ++iii){ if ((BinStream[iii]>=high) || (BinStream[iii]<=low)){ lastBit=iii-*clk; + errCnt=0; //loop through to see if this start location works for (i = iii; i < *size; ++i) { if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ @@ -395,16 +420,16 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) errCnt++; lastBit+=*clk;//skip over until hit too many errors - if (errCnt > ((*size/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; + if (errCnt > maxErr){ + //errCnt=0; break; } } } - if ((i-iii)>(500 * *clk)) break; //got enough bits + if ((i-iii)>(MaxBits * *clk)) break; //got enough bits } //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<(*size/1000))) { + if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) { //possible good read if (errCnt==0){ bestStart=iii; @@ -418,9 +443,9 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) } } } - if (bestErrCnt (*clk-tol))){ //low found and we are expecting a bar lastBit+=*clk; - BinStream[bitnum] = 1-*invert; + BinStream[bitnum] = 1 - *invert; bitnum++; midBit=0; } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ @@ -462,11 +487,10 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) BinStream[bitnum]=77; bitnum++; } - lastBit+=*clk;//skip over error } } - if (bitnum >=400) break; + if (bitnum >= MaxBits) break; } *size=bitnum; } else{ @@ -688,7 +712,7 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p for (int word = 0; word < (bLen); word+=pLen){ for (int bit=0; bit < pLen; bit++){ parityWd = (parityWd << 1) | BitStream[startIdx+word+bit]; - BitStream[j++] = (BitStream[startIdx+word+bit]); + BitStream[j++] = (BitStream[startIdx+word+bit]); } j--; // if parity fails then return 0 @@ -726,17 +750,17 @@ int AWIDdemodFSK(uint8_t *dest, size_t *size) // FSK Demod then try to locate an Farpointe Data (pyramid) ID int PyramiddemodFSK(uint8_t *dest, size_t *size) { - //make sure buffer has data - if (*size < 128*50) return -5; + //make sure buffer has data + if (*size < 128*50) return -5; - //test samples are not just noise - if (justNoise(dest, *size)) return -1; + //test samples are not just noise + if (justNoise(dest, *size)) return -1; - // FSK demodulator - *size = fskdemod(dest, *size, 50, 1, 10, 8); // fsk2a RF/50 - if (*size < 128) return -2; //did we get a good demod? + // FSK demodulator + *size = fskdemod(dest, *size, 50, 1, 10, 8); // fsk2a RF/50 + if (*size < 128) return -2; //did we get a good demod? - uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; size_t startIdx = 0; uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); if (errChk == 0) return -4; //preamble not found @@ -744,32 +768,71 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) return (int)startIdx; } + +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) +{ + uint8_t allPeaks=1; + uint16_t cntPeaks=0; + for (size_t i=20; i<255; i++){ + if (dest[i]>low && dest[i]190) return 1; + } + return allPeaks; +} + // by marshmellow // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) // maybe somehow adjust peak trimming value based on samples to fix? -int DetectASKClock(uint8_t dest[], size_t size, int clock) +// return start index of best starting position for that clock and return clock (by reference) +int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) { int i=0; int clk[]={8,16,32,40,50,64,100,128,256}; int loopCnt = 256; //don't need to loop through entire array... + if (size == 0) return -1; if (size> 8; + uint8_t fc2 = fcTest & 0xFF; + + for (i=0; i<8; i++){ + if (clk[i] == fc1) { + *clock=fc1; + return 0; + } + if (clk[i] == fc2) { + *clock=fc2; + return 0; + } + } + } + int ii; int clkCnt; int tol = 0; int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; + int bestStart[]={0,0,0,0,0,0,0,0,0}; int errCnt=0; //test each valid clock from smallest to greatest to see which lines up - for(clkCnt=0; clkCnt < 8; ++clkCnt){ + for(clkCnt=0; clkCnt < 8; clkCnt++){ if (clk[clkCnt] == 32){ tol=1; }else{ @@ -777,7 +840,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) } bestErr[clkCnt]=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)){ errCnt=0; // now that we have the first one lined up test rest of wave array @@ -792,9 +855,15 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) //if we found no errors then we can stop here // this is correct one - return this clock //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); - if(errCnt==0 && clkCnt<6) return clk[clkCnt]; + if(errCnt==0 && clkCnt<6) { + *clock = clk[clkCnt]; + return ii; + } //if we found errors see if it is lowest so far and save it as best run - if(errCntmaxErr) return -1; + *clock=clk[best]; + return bestStart[best]; } //by marshmellow -//detect psk clock by reading #peaks vs no peaks(or errors) -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock) +//detect psk clock by reading each phase shift +// a phase shift is determined by measuring the sample length of each wave +int DetectPSKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 2048; //don't need to loop through entire array... - if (size= peak) || (dest[ii] <= low)){ - errCnt=0; - peakcnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - peakcnt++; - }else{ //error no peak detected - errCnt++; - } - } - if(peakcnt>peaksdet[clkCnt]) { - peaksdet[clkCnt]=peakcnt; - bestErr[clkCnt]=errCnt; - } - } - } - } - int iii=0; - int best=0; - //int ratio2; //debug - int ratio; - //int bits; - for (iii=0; iii < 7; ++iii){ - ratio=1000; - //ratio2=1000; //debug - //bits=size/clk[iii]; //debug - if (peaksdet[iii] > 0){ - ratio=bestErr[iii]/peaksdet[iii]; - if (((bestErr[best]/peaksdet[best]) > (ratio)+1)){ - best = iii; - } - //ratio2=bits/peaksdet[iii]; //debug - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); - } - return clk[best]; + size_t waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0; + uint8_t clkCnt, fc=0, fullWaveLen=0, tol=1; + uint16_t peakcnt=0, errCnt=0, waveLenCnt=0; + uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; + uint16_t peaksdet[]={0,0,0,0,0,0,0,0,0}; + countFC(dest, size, &fc); + //PrintAndLog("DEBUG: FC: %d",fc); + + //find first full wave + for (i=0; i= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + //PrintAndLog("DEBUG: waveStart: %d",waveStart); + } else { + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + break; + } + waveStart=0; + } + } + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + + //test each valid clock from greatest to smallest to see which lines up + for(clkCnt=7; clkCnt >= 1 ; clkCnt--){ + lastClkBit = firstFullWave; //set end of wave as clock align + waveStart = 0; + errCnt=0; + peakcnt=0; + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d",clk[clkCnt],lastClkBit); + + for (i = firstFullWave+fullWaveLen-1; i < loopCnt-2; i++){ + //top edge of wave = start of new wave + if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt=0; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + //if this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, ii: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,ii+1,fc); + if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit + peakcnt++; + lastClkBit+=clk[clkCnt]; + } else if (i lastClkBit + clk[clkCnt] + tol + fc){ + lastClkBit+=clk[clkCnt]; //no phase shift but clock bit + } + waveStart=i+1; + } + } + } + if (errCnt == 0){ + return clk[clkCnt]; + } + if (errCnt <= bestErr[clkCnt]) bestErr[clkCnt]=errCnt; + if (peakcnt > peaksdet[clkCnt]) peaksdet[clkCnt]=peakcnt; + } + //all tested with errors + //return the highest clk with the most peaks found + uint8_t best=7; + for (i=7; i>=1; i--){ + if (peaksdet[i] > peaksdet[best]) { + best = i; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } -// by marshmellow (attempt to get rid of high immediately after a low) -void pskCleanWave(uint8_t *BitStream, size_t size) +//by marshmellow +//detect nrz clock by reading #peaks vs no peaks(or errors) +int DetectNRZClock(uint8_t dest[], size_t size, int clock) { - int i; - int gap = 4; - int newLow=0; - int newHigh=0; - int high, low; - getHiLo(BitStream, size, &high, &low, 80, 90); - - for (i=0; i < size; ++i){ - if (newLow == 1){ - if (BitStream[i]>low){ - BitStream[i]=low+8; - gap--; - } - if (gap == 0){ - newLow=0; - gap=4; - } - }else if (newHigh == 1){ - if (BitStream[i]= high) newHigh=1; - } - return; + int i=0; + int clk[]={8,16,32,40,50,64,100,128,256}; + int loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return 0; + if (size= peak || dest[i] <= low){ + peakcnt++; + } else { + if (peakcnt>0 && maxPeak < peakcnt){ + maxPeak = peakcnt; + } + peakcnt=0; + } + } + peakcnt=0; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt < 8; ++clkCnt){ + //ignore clocks smaller than largest peak + if (clk[clkCnt]= peak) || (dest[ii] <= low)){ + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + } + } + } + } + int iii=7; + int best=0; + for (iii=7; iii > 0; iii--){ + if (peaksdet[iii] > peaksdet[best]){ + best = iii; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } // by marshmellow @@ -1007,137 +1131,166 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) return 1; } -// by marshmellow - demodulate PSK1 wave or NRZ wave (both similar enough) +// by marshmellow - demodulate NRZ wave (both similar enough) // peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak -int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) +// there probably is a much simpler way to do this.... +int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr) { - if (justNoise(dest, *size)) return -1; - pskCleanWave(dest,*size); - int clk2 = DetectpskNRZClock(dest, *size, *clk); - *clk=clk2; - uint32_t i; - int high, low, ans; - ans = getHiLo(dest, 1260, &high, &low, 75, 80); //25% fuzz on high 20% fuzz on low - if (ans<1) return -2; //just noise - uint32_t gLen = *size; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - uint8_t tol = 1; //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 = 2; //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; - uint8_t errCnt =0; - uint32_t bestStart = *size; - uint32_t maxErr = (*size/1000); - uint32_t bestErrCnt = maxErr; - uint8_t curBit=0; - uint8_t bitHigh=0; - uint8_t ignorewin=*clk/8; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - align to clock - for (iii=0; iii < gLen; ++iii){ - if ((dest[iii]>=high) || (dest[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i] < high && dest[i] > low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i >= lastBit+*clk+tol){ //clock val - lastBit+=*clk; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt++; - } - if (bitnum>=1000) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt < (maxErr))) { - //possible good read - if (errCnt == 0){ - bestStart = iii; - bestErrCnt = errCnt; - break; //great read - finish - } - if (errCnt < bestErrCnt){ //set this as new best run - bestErrCnt = errCnt; - bestStart = iii; - } - } - } - } - if (bestErrCnt < maxErr){ - //best run is good enough set to best run and set overwrite BinStream - iii=bestStart; - lastBit=bestStart-*clk; - bitnum=0; - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=1-*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - lastBit+=*clk; - dest[bitnum]=curBit; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ - //error bar found no clock... - bitHigh=1; - dest[bitnum]=77; - bitnum++; - errCnt++; - } - if (bitnum >=1000) break; - } - *size=bitnum; - } else{ - *size=bitnum; - *clk=bestStart; - return -1; - } + if (justNoise(dest, *size)) return -1; + *clk = DetectNRZClock(dest, *size, *clk); + if (*clk==0) return -2; + uint32_t i; + int high, low, ans; + ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low + if (ans<1) return -2; //just noise + uint32_t gLen = 256; + if (gLen>*size) gLen = *size; + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + uint8_t tol = 1; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + uint32_t iii = 0; + uint16_t errCnt =0; + uint16_t MaxBits = 1000; + uint32_t bestErrCnt = maxErr+1; + uint32_t bestPeakCnt = 0; + uint32_t bestPeakStart=0; + uint8_t curBit=0; + uint8_t bitHigh=0; + uint8_t errBitHigh=0; + uint16_t peakCnt=0; + uint8_t ignoreWindow=4; + uint8_t ignoreCnt=ignoreWindow; //in case of noice near peak + //loop to find first wave that works - align to clock + for (iii=0; iii < gLen; ++iii){ + if ((dest[iii]>=high) || (dest[iii]<=low)){ + lastBit=iii-*clk; + peakCnt=0; + errCnt=0; + bitnum=0; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + bitnum++; + peakCnt++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + bitnum++; + peakCnt++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if no bars found + }else if(dest[i] < high && dest[i] > low) { + if (ignoreCnt==0){ + bitHigh=0; + if (errBitHigh==1){ + errCnt++; + } + errBitHigh=0; + } else { + ignoreCnt--; + } + //if we are past a clock point + if (i >= lastBit+*clk+tol){ //clock val + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errBitHigh=1; + } + if (bitnum>=MaxBits) break; + } + //we got more than 64 good bits and not all errors + if (bitnum > (64) && (errCnt <= (maxErr))) { + //possible good read + if (errCnt == 0){ + //bestStart = iii; + bestErrCnt = errCnt; + bestPeakCnt = peakCnt; + bestPeakStart = iii; + break; //great read - finish + } + if (errCnt < bestErrCnt){ //set this as new best run + bestErrCnt = errCnt; + //bestStart = iii; + } + if (peakCnt > bestPeakCnt){ + bestPeakCnt=peakCnt; + bestPeakStart=iii; + } + } + } + } + //PrintAndLog("DEBUG: bestErrCnt: %d, maxErr: %d, bestStart: %d, bestPeakCnt: %d, bestPeakStart: %d",bestErrCnt,maxErr,bestStart,bestPeakCnt,bestPeakStart); + if (bestErrCnt <= maxErr){ + //best run is good enough set to best run and set overwrite BinStream + iii=bestPeakStart; + lastBit=bestPeakStart-*clk; + bitnum=0; + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + bitnum++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + bitnum++; + errBitHigh=0; + ignoreCnt=ignoreWindow; + //else if no bars found + }else if(dest[i]low) { + if (ignoreCnt==0){ + bitHigh=0; + //if peak is done was it an error peak? + if (errBitHigh==1){ + dest[bitnum]=77; + bitnum++; + errCnt++; + } + errBitHigh=0; + } else { + ignoreCnt--; + } + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + errBitHigh=1; + } + if (bitnum >= MaxBits) break; + } + *size=bitnum; + } else{ + *size=bitnum; + return -1; + } - if (bitnum>16){ - *size=bitnum; - } else return -1; - return errCnt; + if (bitnum>16){ + *size=bitnum; + } else return -1; + return errCnt; } //by marshmellow @@ -1153,6 +1306,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc uint16_t rfCounter = 0; uint8_t firstBitFnd = 0; size_t i; + if (size == 0) return 0; uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); rfLensFnd=0; @@ -1175,7 +1329,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc fcCounter = fcLow; else //set it to the large fc fcCounter = fcHigh; - + //look for bit clock (rf/xx) if ((fcCounterlastFCcnt)){ //not the same size as the last wave - start of new bit sequence @@ -1249,7 +1403,8 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc //by marshmellow //countFC is to detect the field clock lengths. //counts and returns the 2 most common wave lengths -uint16_t countFC(uint8_t *BitStream, size_t size) +//mainly used for FSK field clock detection +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC) { uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; @@ -1257,7 +1412,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size) uint8_t lastFCcnt=0; uint32_t fcCounter = 0; size_t i; - + if (size == 0) return 0; + // prime i to first up transition for (i = 1; i < size-1; i++) if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) @@ -1320,7 +1476,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size) fcH=fcLens[best2]; fcL=fcLens[best1]; } - + + *mostFC=fcLens[best1]; // TODO: take top 3 answers and compare to known Field clocks to get top 2 uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; @@ -1328,3 +1485,152 @@ uint16_t countFC(uint8_t *BitStream, size_t size) return fcs; } + +//by marshmellow +//countPSK_FC is to detect the psk carrier clock length. +//counts and returns the 1 most common wave length +uint8_t countPSK_FC(uint8_t *BitStream, size_t size) +{ + uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; + uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t fcLensFnd = 0; + uint32_t fcCounter = 0; + size_t i; + if (size == 0) return 0; + + // prime i to first up transition + for (i = 1; i < size-1; i++) + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) + break; + + for (; i < size-1; i++){ + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ + // new up transition + fcCounter++; + + // save last field clock count (fc/xx) + // find which fcLens to save it to: + for (int ii=0; ii<10; ii++){ + if (fcLens[ii]==fcCounter){ + fcCnts[ii]++; + fcCounter=0; + break; + } + } + if (fcCounter>0 && fcLensFnd<10){ + //add new fc length + fcCnts[fcLensFnd]++; + fcLens[fcLensFnd++]=fcCounter; + } + fcCounter=0; + } else { + // count sample + fcCounter++; + } + } + + uint8_t best1=9; + uint16_t maxCnt1=0; + // go through fclens and find which ones are bigest + for (i=0; i<10; i++){ + //PrintAndLog("DEBUG: FC %d, Cnt %d",fcLens[i],fcCnts[i]); + // get the best FC value + if (fcCnts[i]>maxCnt1) { + maxCnt1=fcCnts[i]; + best1=i; + } + } + return fcLens[best1]; +} + +//by marshmellow - demodulate PSK1 wave +//uses wave lengths (# Samples) +int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) +{ + uint16_t loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return -1; + if (*size= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + avgWaveVal=dest[i+1]; + //PrintAndLog("DEBUG: waveStart: %d",waveStart); + } else { + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + lastAvgWaveVal = avgWaveVal/waveLenCnt; + if (waveLenCnt > fc){ + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + //if average wave value is > graph 0 then it is an up wave or a 1 + if (lastAvgWaveVal > 128) curPhase^=1; + break; + } + waveStart=0; + avgWaveVal=0; + } + } + avgWaveVal+=dest[i+1]; + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + lastClkBit = firstFullWave; //set start of wave as clock align + waveStart = 0; + errCnt=0; + size_t numBits=0; + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit); + + for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){ + //top edge of wave = start of new wave + if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt=0; + avgWaveVal = dest[i+1]; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + lastAvgWaveVal = avgWaveVal/waveLenCnt; + if (waveLenCnt > fc){ + //PrintAndLog("DEBUG: avgWaveVal: %d, waveSum: %d",lastAvgWaveVal,avgWaveVal); + //if this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc); + if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit + curPhase^=1; + dest[numBits] = curPhase; + numBits++; + lastClkBit += *clock; + } else if (i lastClkBit + *clock + tol + fc){ + lastClkBit += *clock; //no phase shift but clock bit + dest[numBits] = curPhase; + numBits++; + } + avgWaveVal=0; + waveStart=i+1; + } + } + avgWaveVal+=dest[i+1]; + } + *size = numBits; + return errCnt; +} diff --git a/common/lfdemod.h b/common/lfdemod.h index dbeab0f7..2880ff82 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -15,31 +15,34 @@ #define LFDEMOD_H__ #include -int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr); uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx); int ManchesterEncode(uint8_t *BitStream, size_t size); int manrawdecode(uint8_t *BitStream, size_t *size); int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp); 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 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, size_t numbits); -int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert); +int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr); void psk1TOpsk2(uint8_t *BitStream, size_t size); -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int DetectNRZClock(uint8_t dest[], size_t size, int clock); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); void pskCleanWave(uint8_t *bitStream, size_t size); int PyramiddemodFSK(uint8_t *dest, size_t *size); int AWIDdemodFSK(uint8_t *dest, size_t *size); size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); -uint16_t countFC(uint8_t *BitStream, size_t size); +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC); uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow); int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); uint8_t justNoise(uint8_t *BitStream, size_t size); +uint8_t countPSK_FC(uint8_t *BitStream, size_t size); +int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert); +int DetectPSKClock(uint8_t dest[], size_t size, int clock); #endif