From: marshmellow42 Date: Tue, 16 Feb 2016 17:49:30 +0000 (-0500) Subject: Add LF ASK Sequence Terminator detection... X-Git-Tag: v2.3.0~4^2~8 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/d1869c3336e82b7f2eb68b7fa9a5bdb865ff6b23 Add LF ASK Sequence Terminator detection... ...and demodulate data beginning after the first ST also add some type casts in print calls. --- diff --git a/client/cmddata.c b/client/cmddata.c index 900cfc83..c7fdc91e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -277,7 +277,8 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { - if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0; + bool st = TRUE; + if (!ASKDemod_ext(Cmd, FALSE, FALSE, 1, &st)) return 0; return AskEm410xDecode(verbose, hi, lo); } @@ -312,8 +313,7 @@ int CmdAskEM410xDemod(const char *Cmd) //verbose will print results and demoding messages //emSearch will auto search for EM410x format in bitstream //askType switches decode: ask/raw = 0, ask/manchester = 1 -int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) -{ +int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) { int invert=0; int clk=0; int maxErr=100; @@ -334,15 +334,22 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) if (amp == 'a' || amp == 'A') askAmp=1; size_t BitLen = getFromGraphBuf(BitStream); if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - if (BitLen<255) return 0; - if (maxLenmaxErr){ + if (errCnt > maxErr){ if (g_debugMode) PrintAndLog("DEBUG: Too many errors found, errors:%d, bits:%d, clock:%d",errCnt, BitLen, clk); return 0; } @@ -365,6 +372,10 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) } return 1; } +int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) { + bool st = false; + return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st); +} //by marshmellow //takes 5 arguments - clock, invert, maxErr, maxLen as integers and amplify as char == 'a' @@ -374,7 +385,8 @@ int Cmdaskmandemod(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod am [clock] [maxError] [maxLen] [amplify]"); + PrintAndLog("Usage: data rawdemod am [clock] [maxError] [maxLen] [amplify]"); + PrintAndLog(" ['s'] optional, check for Sequence Terminator"); PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); PrintAndLog(" , 1 to invert output"); PrintAndLog(" [set maximum allowed errors], default = 100"); @@ -388,7 +400,13 @@ int Cmdaskmandemod(const char *Cmd) PrintAndLog(" : data rawdemod am 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; } - return ASKDemod(Cmd, TRUE, TRUE, 1); + bool st = TRUE; + if (Cmd[0]=='s') + return ASKDemod_ext(Cmd++, TRUE, TRUE, 1, &st); + else if (Cmd[1] == 's') + return ASKDemod_ext(Cmd+=2, TRUE, TRUE, 1, &st); + else + return ASKDemod(Cmd, TRUE, TRUE, 1); } //by marshmellow @@ -595,7 +613,7 @@ int CmdG_Prox_II_Demod(const char *Cmd) if ((idx+1) % 5 == 0){ //spacer bit - should be 0 if (DemodBuffer[startIdx+idx] != 0) { - if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx); + if (g_debugMode) PrintAndLog("Error spacer not 0: %u, pos: %u", (unsigned int)DemodBuffer[startIdx+idx],(unsigned int)(startIdx+idx)); return 0; } continue; @@ -603,21 +621,21 @@ int CmdG_Prox_II_Demod(const char *Cmd) if (keyCnt<8){ //lsb first xorKey = xorKey | (DemodBuffer[startIdx+idx]<>1); Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d", fmtLen, FC, Card); } else if(fmtLen==26){ FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7); Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",(unsigned int)fmtLen,FC,Card); } else { - PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen); + PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",(int)fmtLen); } PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3); setDemodBuf(DemodBuffer+ans, 96, 0); @@ -664,7 +682,7 @@ int CmdVikingDemod(const char *Cmd) uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32); uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8); - PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum); + PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, (unsigned int) checksum); PrintAndLog("Raw: %08X%08X", raw1,raw2); setDemodBuf(DemodBuffer+ans, 64, 0); return 1; @@ -952,6 +970,7 @@ int FSKrawDemod(const char *Cmd, bool verbose) invert = param_get8(Cmd, 1); fchigh = param_get8(Cmd, 2); fclow = param_get8(Cmd, 3); + if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (rfLen==1) { invert = 1; //if invert option only is used @@ -961,7 +980,6 @@ int FSKrawDemod(const char *Cmd, bool verbose) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; - if (g_debugMode==2) PrintAndLog("DEBUG: Got samples"); //get field clock lengths uint16_t fcs=0; if (!fchigh || !fclow) { @@ -989,6 +1007,7 @@ int FSKrawDemod(const char *Cmd, bool verbose) PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert)); printDemodBuff(); } + return 1; } else { if (g_debugMode) PrintAndLog("no FSK data found"); diff --git a/client/cmddata.h b/client/cmddata.h index c3303c54..20bdbd2b 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -63,6 +63,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ); int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose); int ASKbiphaseDemod(const char *Cmd, bool verbose); int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); +int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck); int FSKrawDemod(const char *Cmd, bool verbose); int PSKDemod(const char *Cmd, bool verbose); int NRZrawDemod(const char *Cmd, bool verbose); diff --git a/client/cmdlf.c b/client/cmdlf.c index 41feec20..93a1398d 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1193,7 +1193,8 @@ int CmdLFfind(const char *Cmd) return 1; } } - ans=ASKDemod("0 0 0",TRUE,FALSE,1); + bool st = TRUE; + ans=ASKDemod_ext("0 0 0",TRUE,FALSE,1,&st); if (ans>0) { PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'"); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index dfee9aa6..b8e39c30 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -48,6 +48,7 @@ int usage_t55xx_config(){ PrintAndLog(" i [1] Invert data signal, defaults to normal"); PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream"); PrintAndLog(" Q5 Set as Q5(T5555) chip instead of T55x7"); + PrintAndLog(" ST Set Sequence Terminator on"); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx config d FSK - FSK demodulation"); @@ -270,6 +271,11 @@ int CmdT55xxSetConfig(const char *Cmd) { config.Q5 = TRUE; cmdp++; break; + case 'S': + case 's': + config.ST = TRUE; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = TRUE; @@ -370,6 +376,7 @@ bool DecodeT55xxBlock(){ char buf[30] = {0x00}; char *cmdStr = buf; int ans = 0; + bool ST = config.ST; uint8_t bitRate[8] = {8,16,32,40,50,64,100,128}; DemodBufferLen = 0x00; @@ -390,7 +397,7 @@ bool DecodeT55xxBlock(){ break; case DEMOD_ASK: snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted ); - ans = ASKDemod(cmdStr, FALSE, FALSE, 1); + ans = ASKDemod_ext(cmdStr, FALSE, FALSE, 1, &ST); break; case DEMOD_PSK1: // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) @@ -482,7 +489,6 @@ bool tryDetectModulation(){ t55xx_conf_block_t tests[15]; int bitRate=0; uint8_t fc1 = 0, fc2 = 0, clk=0; - if (GetFskClock("", FALSE, FALSE)){ fskClocks(&fc1, &fc2, &clk, FALSE); if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -494,6 +500,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -505,19 +512,22 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } } else { clk = GetAskClock("", FALSE, FALSE); if (clk>0) { - if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { + tests[hits].ST = TRUE; + if ( ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { tests[hits].modulation = DEMOD_ASK; tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { + tests[hits].ST = TRUE; + if ( ASKDemod_ext("0 1 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { tests[hits].modulation = DEMOD_ASK; tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; @@ -529,6 +539,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } if ( ASKbiphaseDemod("0 0 1 2", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5) ) { @@ -536,6 +547,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } } @@ -548,6 +560,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } @@ -556,6 +569,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } } @@ -571,6 +585,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } if ( PSKDemod("0 1 6", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -578,6 +593,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } // PSK2 - needs a call to psk1TOpsk2. @@ -588,6 +604,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } } // inverse waves does not affect this demod @@ -599,6 +616,7 @@ bool tryDetectModulation(){ tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].ST = FALSE; ++hits; } } // inverse waves does not affect this demod @@ -613,6 +631,7 @@ bool tryDetectModulation(){ config.offset = tests[0].offset; config.block0 = tests[0].block0; config.Q5 = tests[0].Q5; + config.ST = tests[0].ST; printConfiguration( config ); return TRUE; } @@ -836,6 +855,7 @@ int printConfiguration( t55xx_conf_block_t b){ PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) ); PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" ); PrintAndLog("Offset : %d", b.offset); + PrintAndLog("Seq. Term. : %d", (b.ST) ? "Yes" : "No" ); PrintAndLog("Block0 : 0x%08X", b.block0); PrintAndLog(""); return 0; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 8ad98597..5c2ec79d 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -63,6 +63,7 @@ typedef struct { RF_128 = 0x07, } bitrate; bool Q5; + bool ST; } t55xx_conf_block_t; t55xx_conf_block_t Get_t55xx_Config(); void Set_t55xx_Config(t55xx_conf_block_t conf); diff --git a/client/util.c b/client/util.c index e5cbc4aa..9b99cdf1 100644 --- a/client/util.c +++ b/client/util.c @@ -94,7 +94,7 @@ void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount) memset(fileName, 0x00, 200); for (int j = 0; j < byteCount; j++, fnameptr += 2) - sprintf(fnameptr, "%02x", uid[j]); + sprintf(fnameptr, "%02x", (unsigned int) uid[j]); sprintf(fnameptr, "%s", ext); } @@ -119,7 +119,7 @@ char *sprint_hex(const uint8_t *data, const size_t len) { size_t i; for (i=0; i < maxLen; ++i, tmp += 3) - sprintf(tmp, "%02x ", data[i]); + sprintf(tmp, "%02x ", (unsigned int) data[i]); return buf; } @@ -142,7 +142,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea for (size_t out_index=0; out_index < max_len; out_index++) { // set character - (should be binary but verify it isn't more than 1 digit) if (data[in_index]<10) - sprintf(tmp++, "%u", data[in_index]); + sprintf(tmp++, "%u", (unsigned int) data[in_index]); // check if a line break is needed and we have room to print it in our array if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != max_len) ) { // increment and print line break @@ -215,7 +215,7 @@ char * printBits(size_t const size, void const * const ptr) { byte = b[i] & (1<>= j; - sprintf(tmp, "%u", byte); + sprintf(tmp, "%u", (unsigned int)byte); tmp++; } } @@ -451,7 +451,7 @@ int binarraytohex(char *target,char *source, int length) { for(i= x= 0 ; i < 4 ; ++i) x += ( source[i] << (3 - i)); - sprintf(target,"%X", x); + sprintf(target,"%X", (unsigned int)x); ++target; source += 4; j -= 4; diff --git a/common/lfdemod.c b/common/lfdemod.c index 982a724a..5ed2d16c 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -9,11 +9,10 @@ //----------------------------------------------------------------------------- #include -#include #include "lfdemod.h" -#include "common.h" +#include -//un_comment to allow debug print calls when used not on device +//to allow debug print calls when used not on device void dummy(char *fmt, ...){} #ifndef ON_DEVICE @@ -218,6 +217,7 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int if (smplCnt > clk-(clk/4)-1) { //full clock if (smplCnt > clk + (clk/4)+1) { //too many samples errCnt++; + if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i); BinStream[bitCnt++]=7; } else if (waveHigh) { BinStream[bitCnt++] = invert; @@ -274,7 +274,7 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr if (*clk==0 || start < 0) return -3; if (*invert != 1) *invert = 0; if (amp==1) askAmp(BinStream, *size); - if (g_debugMode==2) prnt("DEBUG: clk %d, beststart %d", *clk, start); + if (g_debugMode==2) prnt("DEBUG ASK: clk %d, beststart %d", *clk, start); uint8_t initLoopMax = 255; if (initLoopMax > *size) initLoopMax = *size; @@ -287,20 +287,21 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr size_t errCnt = 0; // if clean clipped waves detected run alternate demod if (DetectCleanAskWave(BinStream, *size, high, low)) { - if (g_debugMode==2) prnt("DEBUG: Clean Wave Detected"); + if (g_debugMode==2) prnt("DEBUG ASK: Clean Wave Detected - using clean wave demod"); errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low); if (askType) //askman return manrawdecode(BinStream, size, 0); else //askraw return errCnt; } + if (g_debugMode==2) prnt("DEBUG ASK: Weak Wave Detected - using weak wave demod"); - int lastBit; //set first clock check - can go negative + int lastBit; //set first clock check - can go negative size_t i, bitnum = 0; //output counter uint8_t midBit = 0; 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 + or - 1 but could be increased for poor waves or removed entirely - size_t MaxBits = 3072; + 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 + size_t MaxBits = 3072; //max bits to collect lastBit = start - *clk; for (i = start; i < *size; ++i) { @@ -311,6 +312,7 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr BinStream[bitnum++] = *invert ^ 1; } else if (i-lastBit >= *clk+tol) { if (bitnum > 0) { + if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i); BinStream[bitnum++]=7; errCnt++; } @@ -1199,7 +1201,7 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) return (int) startidx; } -// by marshmellow - demodulate NRZ wave +// by marshmellow - demodulate NRZ wave - requires a read with strong signal // peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert){ if (justNoise(dest, *size)) return -1; @@ -1518,3 +1520,158 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) *size = numBits; return errCnt; } + +//by marshmellow +//attempt to identify a Sequence Terminator in ASK modulated raw wave +bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) { + size_t bufsize = *size; + //need to loop through all samples and identify our clock, look for the ST pattern + uint8_t fndClk[] = {8,16,32,40,50,64,128}; + int clk = 0; + int tol = 0; + int i, j, skip, start, end, low, high, minClk; + bool complete = false; + int tmpbuff[bufsize / 64]; + size_t testsize = (bufsize < 512) ? bufsize : 512; + //int phaseoff = 0; + high = low = 128; + memset(tmpbuff, 0, sizeof(tmpbuff)); + + if ( getHiLo(buffer, testsize, &high, &low, 80, 80) == -1 ) { + if (g_debugMode==2) prnt("DEBUG STT: just noise detected - quitting"); + return false; //just noise + } + + i = 0; + j = 0; + minClk = 255; + // get to first full low to prime loop and skip incomplete first pulse + while ((buffer[i] < high) && (i < bufsize)) + ++i; + while ((buffer[i] > low) && (i < bufsize)) + ++i; + skip = i; + + // populate tmpbuff buffer with pulse lengths + while (i < bufsize) { + // measure from low to low + while ((buffer[i] > low) && (i < bufsize)) + ++i; + start= i; + while ((buffer[i] < high) && (i < bufsize)) + ++i; + while ((buffer[i] > low) && (i < bufsize)) + ++i; + if (j >= (bufsize/64)) { + break; + } + tmpbuff[j++] = i - start; + if (i-start < minClk && i < bufsize) { + minClk = i - start; + } + } + // set clock - might be able to get this externally and remove this work... + if (!clk) { + for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) { + tol = fndClk[clkCnt]/8; + if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) { + clk=fndClk[clkCnt]; + break; + } + } + // clock not found - ERROR + if (!clk) { + if (g_debugMode==2) prnt("DEBUG STT: clock not found - quitting"); + return false; + } + } else tol = clk/8; + + *foundclock = clk; + + // look for Sequence Terminator - should be pulses of clk*(1 or 1.5), clk*2, clk*(1.5 or 2) + start = -1; + for (i = 0; i < j - 4; ++i) { + skip += tmpbuff[i]; + if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol) { //1 to 2 clocks depending on 2 bits prior + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) { //2 clocks + if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol) { //1 1/2 to 2 clocks + if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= (clk*3)/2+tol) { //1 to 1 1/2 clocks for end of ST + first bit + start = i + 3; + break; + } + } + } + } + } + // first ST not found - ERROR + if (start < 0) { + if (g_debugMode==2) prnt("DEBUG STT: first STT not found - quitting"); + return false; + } + + // skip over the remainder of ST + skip += clk*7/2; //3.5 clocks from tmpbuff[i] = end of st - also aligns for ending point + + // now do it again to find the end + end = skip; + for (i += 3; i < j - 4; ++i) { + end += tmpbuff[i]; + if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol) { //1 to 2 clocks depending on 2 bits prior + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) { //2 clocks + if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol) { //1 1/2 to 2 clocks + if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= (clk*3)/2+tol) { //1 to 1 1/2 clocks for end of ST + first bit + complete = true; + break; + } + } + } + } + } + //didn't find second ST - ERROR + if (!complete) { + if (g_debugMode==2) prnt("DEBUG STT: second STT not found - quitting"); + return false; + } + if (g_debugMode==2) prnt("DEBUG STT: start of data: %d end of data: %d, datalen: %d, clk: %d, bits: %d", skip, end, end-skip, clk, (end-skip)/clk); + //now begin to trim out ST so we can use normal demod cmds + start = skip; + size_t datalen = end - start; + // check validity of datalen (should be even clock increments) - use a tolerance of up to 1/8th a clock + if (datalen % clk > clk/8) { + if (g_debugMode==2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk); + return false; + } else { + // padd the amount off - could be problematic... but shouldn't happen often + datalen += datalen % clk; + } + // if datalen is less than one t55xx block - ERROR + if (datalen/clk < 8*4) { + if (g_debugMode==2) prnt("DEBUG STT: datalen is less than 1 full t55xx block - quitting"); + return false; + } + size_t dataloc = start; + size_t newloc = 0; + i=0; + // warning - overwriting buffer given with raw wave data with ST removed... + while ( dataloc < bufsize-(clk/2) ) { + //compensate for long high at end of ST not being high... (we cut out the high part) + if (buffer[dataloc]low && buffer[dataloc+3]low) { + for(i=0; i < clk/2-tol; ++i) { + buffer[dataloc+i] = high+5; + } + } + for (i=0; i +#include "common.h" //for bool //generic size_t addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType); @@ -28,6 +29,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t f int DetectNRZClock(uint8_t dest[], size_t size, int clock); int DetectPSKClock(uint8_t dest[], size_t size, int clock); int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low); +bool DetectST(uint8_t buffer[], size_t *size, int *foundclock); int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow); int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); uint32_t manchesterEncode2Bytes(uint16_t datain);