+ bool errBitHigh = 0;
+ bool bitHigh = 0;
+ uint8_t ignoreCnt = 0;
+ uint8_t ignoreWindow = 4;
+ bool lastPeakHigh = 0;
+ int lastBit = 0;
+ size_t bestStart[]={0,0,0,0,0,0,0,0,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 smallest peak
+ if (clk[clkCnt] < maxPeak - (clk[clkCnt]/4)) continue;
+ //try lining up the peaks by moving starting point (try first 256)
+ for (ii=20; ii < loopCnt; ++ii){
+ if ((dest[ii] >= peak) || (dest[ii] <= low)){
+ peakcnt = 0;
+ bitHigh = false;
+ ignoreCnt = 0;
+ lastBit = ii-clk[clkCnt];
+ //loop through to see if this start location works
+ for (i = ii; i < size-20; ++i) {
+ //if we are at a clock bit
+ if ((i >= lastBit + clk[clkCnt] - tol) && (i <= lastBit + clk[clkCnt] + tol)) {
+ //test high/low
+ if (dest[i] >= peak || dest[i] <= low) {
+ //if same peak don't count it
+ if ((dest[i] >= peak && !lastPeakHigh) || (dest[i] <= low && lastPeakHigh)) {
+ peakcnt++;
+ }
+ lastPeakHigh = (dest[i] >= peak);
+ bitHigh = true;
+ errBitHigh = false;
+ ignoreCnt = ignoreWindow;
+ lastBit += clk[clkCnt];
+ } else if (i == lastBit + clk[clkCnt] + tol) {
+ lastBit += clk[clkCnt];
+ }
+ //else if not a clock bit and no peaks
+ } else if (dest[i] < peak && dest[i] > low){
+ if (ignoreCnt==0){
+ bitHigh=false;
+ if (errBitHigh==true) peakcnt--;
+ errBitHigh=false;
+ } else {
+ ignoreCnt--;
+ }
+ // else if not a clock bit but we have a peak
+ } else if ((dest[i]>=peak || dest[i]<=low) && (!bitHigh)) {
+ //error bar found no clock...
+ errBitHigh=true;
+ }
+ }
+ if(peakcnt>peaksdet[clkCnt]) {
+ bestStart[clkCnt]=ii;
+ peaksdet[clkCnt]=peakcnt;
+ }
+ }
+ }
+ }
+ int iii=7;
+ uint8_t best=0;
+ for (iii=7; iii > 0; iii--){
+ if ((peaksdet[iii] >= (peaksdet[best]-1)) && (peaksdet[iii] <= peaksdet[best]+1) && lowestTransition) {
+ if (clk[iii] > (lowestTransition - (clk[iii]/8)) && clk[iii] < (lowestTransition + (clk[iii]/8))) {
+ best = iii;
+ }
+ } else if (peaksdet[iii] > peaksdet[best]){
+ best = iii;
+ }
+ if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, maxPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],maxPeak, clk[best], lowestTransition);
+ }
+ *clockStartIdx = bestStart[best];
+ return clk[best];
+}
+
+int DetectNRZClock(uint8_t dest[], size_t size, int clock) {
+ size_t bestStart=0;
+ return DetectNRZClock_ext(dest, size, clock, &bestStart);
+}
+
+//by marshmellow
+//countFC is to detect the field clock lengths.
+//counts and returns the 2 most common wave lengths
+//mainly used for FSK field clock detection
+uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) {
+ uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t fcLensFnd = 0;
+ uint8_t lastFCcnt = 0;
+ uint8_t fcCounter = 0;
+ size_t i;
+ if (size < 180) return 0;
+
+ // prime i to first up transition
+ for (i = 160; i < size-20; i++)
+ if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1])
+ break;
+
+ for (; i < size-20; i++){
+ if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){
+ // new up transition
+ fcCounter++;
+ if (fskAdj){
+ //if we had 5 and now have 9 then go back to 8 (for when we get a fc 9 instead of an 8)
+ if (lastFCcnt==5 && fcCounter==9) fcCounter--;
+ //if fc=9 or 4 add one (for when we get a fc 9 instead of 10 or a 4 instead of a 5)
+ if ((fcCounter==9) || fcCounter==4) fcCounter++;
+ // save last field clock count (fc/xx)
+ lastFCcnt = fcCounter;
+ }
+ // find which fcLens to save it to:
+ for (int ii=0; ii<15; ii++){
+ if (fcLens[ii]==fcCounter){
+ fcCnts[ii]++;
+ fcCounter=0;
+ break;
+ }
+ }
+ if (fcCounter>0 && fcLensFnd<15){
+ //add new fc length
+ fcCnts[fcLensFnd]++;
+ fcLens[fcLensFnd++]=fcCounter;
+ }
+ fcCounter=0;
+ } else {
+ // count sample
+ fcCounter++;
+ }
+ }
+
+ uint8_t best1=14, best2=14, best3=14;
+ uint16_t maxCnt1=0;
+ // go through fclens and find which ones are bigest 2
+ for (i=0; i<15; i++){
+ // get the 3 best FC values
+ if (fcCnts[i]>maxCnt1) {
+ best3=best2;
+ best2=best1;
+ maxCnt1=fcCnts[i];
+ best1=i;
+ } else if(fcCnts[i]>fcCnts[best2]){
+ best3=best2;
+ best2=i;
+ } else if(fcCnts[i]>fcCnts[best3]){
+ best3=i;
+ }
+ if (g_debugMode==2) prnt("DEBUG countfc: FC %u, Cnt %u, best fc: %u, best2 fc: %u",fcLens[i],fcCnts[i],fcLens[best1],fcLens[best2]);
+ }
+ if (fcLens[best1]==0) return 0;
+ uint8_t fcH=0, fcL=0;
+ if (fcLens[best1]>fcLens[best2]){
+ fcH=fcLens[best1];
+ fcL=fcLens[best2];
+ } else{
+ fcH=fcLens[best2];
+ fcL=fcLens[best1];
+ }
+ if ((size-180)/fcH/3 > fcCnts[best1]+fcCnts[best2]) {
+ if (g_debugMode==2) prnt("DEBUG countfc: fc is too large: %u > %u. Not psk or fsk",(size-180)/fcH/3,fcCnts[best1]+fcCnts[best2]);
+ return 0; //lots of waves not psk or fsk
+ }
+ // TODO: take top 3 answers and compare to known Field clocks to get top 2
+
+ uint16_t fcs = (((uint16_t)fcH)<<8) | fcL;
+ if (fskAdj) return fcs;
+ return fcLens[best1];
+}
+
+//by marshmellow
+//detect psk clock by reading each phase shift
+// a phase shift is determined by measuring the sample length of each wave
+int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseShift) {
+ uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock
+ uint16_t loopCnt = 4096; //don't need to loop through entire array...
+ if (size == 0) return 0;
+ if (size<loopCnt) loopCnt = size-20;
+
+ //if we already have a valid clock quit
+ size_t i=1;
+ for (; i < 8; ++i)
+ if (clk[i] == clock) return clock;
+
+ 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};
+ fc = countFC(dest, size, 0);
+ if (fc!=2 && fc!=4 && fc!=8) return -1;
+ if (g_debugMode==2) prnt("DEBUG PSK: FC: %d",fc);
+
+ //find first full wave
+ for (i=160; i<loopCnt; i++){
+ if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
+ if (waveStart == 0) {
+ waveStart = i+1;
+ //prnt("DEBUG: waveStart: %d",waveStart);
+ } else {
+ waveEnd = i+1;
+ //prnt("DEBUG: waveEnd: %d",waveEnd);
+ waveLenCnt = waveEnd-waveStart;
+ if (waveLenCnt > fc){
+ firstFullWave = waveStart;
+ fullWaveLen=waveLenCnt;
+ break;
+ }
+ waveStart=0;
+ }
+ }
+ }
+ *firstPhaseShift = firstFullWave;
+ if (g_debugMode ==2) prnt("DEBUG PSK: 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;
+ if (g_debugMode == 2) prnt("DEBUG PSK: 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
+ if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+1,fc);
+ if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit
+ peakcnt++;
+ lastClkBit+=clk[clkCnt];
+ } else if (i<lastClkBit+8){
+ //noise after a phase shift - ignore
+ } else { //phase shift before supposed to based on clock
+ errCnt++;
+ }
+ } else if (i+1 > 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;
+ }
+ if (g_debugMode == 2) prnt("DEBUG PSK: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[i],peaksdet[i],bestErr[i],clk[best]);
+ }
+ return clk[best];
+}
+
+int DetectPSKClock(uint8_t dest[], size_t size, int clock) {
+ int firstPhaseShift = 0;
+ return DetectPSKClock_ext(dest, size, clock, &firstPhaseShift);
+}
+
+//by marshmellow
+//detects the bit clock for FSK given the high and low Field Clocks
+uint8_t detectFSKClk_ext(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge) {
+ uint8_t clk[] = {8,16,32,40,50,64,100,128,0};
+ uint16_t rfLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t rfLensFnd = 0;
+ uint8_t lastFCcnt = 0;
+ uint16_t fcCounter = 0;
+ uint16_t rfCounter = 0;
+ uint8_t firstBitFnd = 0;
+ size_t i;
+ if (size == 0) return 0;
+
+ uint8_t fcTol = ((fcHigh*100 - fcLow*100)/2 + 50)/100; //(uint8_t)(0.5+(float)(fcHigh-fcLow)/2);
+ rfLensFnd=0;
+ fcCounter=0;
+ rfCounter=0;
+ firstBitFnd=0;
+ //PrintAndLog("DEBUG: fcTol: %d",fcTol);
+ // prime i to first peak / up transition
+ for (i = 160; i < size-20; i++)
+ if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1])
+ break;
+
+ for (; i < size-20; i++){
+ fcCounter++;
+ rfCounter++;
+
+ if (BitStream[i] <= BitStream[i-1] || BitStream[i] < BitStream[i+1])
+ continue;
+ // else new peak
+ // if we got less than the small fc + tolerance then set it to the small fc
+ // if it is inbetween set it to the last counter
+ if (fcCounter < fcHigh && fcCounter > fcLow)
+ fcCounter = lastFCcnt;
+ else if (fcCounter < fcLow+fcTol)
+ fcCounter = fcLow;
+ else //set it to the large fc
+ fcCounter = fcHigh;
+
+ //look for bit clock (rf/xx)
+ if ((fcCounter < lastFCcnt || fcCounter > lastFCcnt)){
+ //not the same size as the last wave - start of new bit sequence
+ if (firstBitFnd > 1){ //skip first wave change - probably not a complete bit
+ for (int ii=0; ii<15; ii++){
+ if (rfLens[ii] >= (rfCounter-4) && rfLens[ii] <= (rfCounter+4)){
+ rfCnts[ii]++;
+ rfCounter = 0;
+ break;
+ }
+ }
+ if (rfCounter > 0 && rfLensFnd < 15){
+ //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter);
+ rfCnts[rfLensFnd]++;
+ rfLens[rfLensFnd++] = rfCounter;
+ }
+ } else {
+ *firstClockEdge = i;
+ firstBitFnd++;
+ }
+ rfCounter=0;
+ lastFCcnt=fcCounter;
+ }
+ fcCounter=0;
+ }
+ uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15;
+
+ for (i=0; i<15; i++){
+ //get highest 2 RF values (might need to get more values to compare or compare all?)
+ if (rfCnts[i]>rfCnts[rfHighest]){
+ rfHighest3=rfHighest2;
+ rfHighest2=rfHighest;
+ rfHighest=i;
+ } else if(rfCnts[i]>rfCnts[rfHighest2]){
+ rfHighest3=rfHighest2;
+ rfHighest2=i;
+ } else if(rfCnts[i]>rfCnts[rfHighest3]){
+ rfHighest3=i;
+ }
+ if (g_debugMode==2) prnt("DEBUG FSK: RF %d, cnts %d",rfLens[i], rfCnts[i]);
+ }
+ // set allowed clock remainder tolerance to be 1 large field clock length+1
+ // we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off
+ uint8_t tol1 = fcHigh+1;
+
+ if (g_debugMode==2) prnt("DEBUG FSK: most counted rf values: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]);
+
+ // loop to find the highest clock that has a remainder less than the tolerance
+ // compare samples counted divided by
+ // test 128 down to 32 (shouldn't be possible to have fc/10 & fc/8 and rf/16 or less)
+ int ii=7;
+ for (; ii>=2; ii--){
+ if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){
+ if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){
+ if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){
+ if (g_debugMode==2) prnt("DEBUG FSK: clk %d divides into the 3 most rf values within tolerance",clk[ii]);
+ break;
+ }
+ }
+ }
+ }
+
+ if (ii<2) return 0; // oops we went too far
+
+ return clk[ii];
+}
+
+uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow) {
+ int firstClockEdge = 0;
+ return detectFSKClk_ext(BitStream, size, fcHigh, fcLow, &firstClockEdge);
+}
+
+//-----------------Tag format detection section--------------------------------------------------------------
+
+// by marshmellow
+// FSK Demod then try to locate an AWID ID
+int AWIDdemodFSK(uint8_t *dest, size_t *size) {
+ //make sure buffer has enough data
+ if (*size < 96*50) return -1;
+
+ if (justNoise(dest, *size)) return -2;
+
+ // FSK demodulator
+ *size = fskdemod(dest, *size, 50, 1, 10, 8); // fsk2a RF/50
+ if (*size < 96) return -3; //did we get a good demod?
+
+ uint8_t preamble[] = {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
+ if (*size != 96) return -5;
+ return (int)startIdx;
+}
+
+//by marshmellow
+//takes 1s and 0s and searches for EM410x format - output EM ID
+uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo)
+{
+ //sanity checks
+ if (*size < 64) return 0;
+ if (BitStream[1]>1) return 0; //allow only 1s and 0s
+
+ // 111111111 bit pattern represent start of frame
+ // include 0 in front to help get start pos
+ uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1};
+ uint8_t errChk = 0;
+ uint8_t FmtLen = 10; // sets of 4 bits = end data
+ *startIdx = 0;
+ errChk = preambleSearch(BitStream, preamble, sizeof(preamble), size, startIdx);
+ if ( errChk == 0 || (*size != 64 && *size != 128) ) return 0;
+ if (*size == 128) FmtLen = 22; // 22 sets of 4 bits
+
+ //skip last 4bit parity row for simplicity
+ *size = removeParity(BitStream, *startIdx + sizeof(preamble), 5, 0, FmtLen * 5);
+ if (*size == 40) { // std em410x format
+ *hi = 0;
+ *lo = ((uint64_t)(bytebits_to_byte(BitStream, 8)) << 32) | (bytebits_to_byte(BitStream + 8, 32));
+ } else if (*size == 88) { // long em format
+ *hi = (bytebits_to_byte(BitStream, 24));
+ *lo = ((uint64_t)(bytebits_to_byte(BitStream + 24, 32)) << 32) | (bytebits_to_byte(BitStream + 24 + 32, 32));
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
+// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
+// BitStream must contain previously askrawdemod and biphasedemoded data
+int FDXBdemodBI(uint8_t *dest, size_t *size) {
+ //make sure buffer has enough data
+ if (*size < 128) return -1;
+
+ size_t startIdx = 0;
+ uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,1};
+
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -2; //preamble not found
+ return (int)startIdx;
+}
+
+// by marshmellow
+// demod gProxIIDemod
+// error returns as -x
+// success returns start position in BitStream
+// BitStream must contain previously askrawdemod and biphasedemoded data
+int gProxII_Demod(uint8_t BitStream[], size_t *size) {
+ size_t startIdx=0;
+ uint8_t preamble[] = {1,1,1,1,1,0};
+
+ uint8_t errChk = preambleSearch(BitStream, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -3; //preamble not found
+ if (*size != 96) return -2; //should have found 96 bits
+ //check first 6 spacer bits to verify format
+ if (!BitStream[startIdx+5] && !BitStream[startIdx+10] && !BitStream[startIdx+15] && !BitStream[startIdx+20] && !BitStream[startIdx+25] && !BitStream[startIdx+30]){
+ //confirmed proper separator bits found
+ //return start position
+ return (int) startIdx;
+ }
+ return -5; //spacer bits not found - not a valid gproxII
+}
+
+// loop to get raw HID waveform then FSK demodulate the TAG ID from it
+int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) {
+ if (justNoise(dest, *size)) return -1;
+
+ size_t numStart=0, size2=*size, startIdx=0;
+ // FSK demodulator
+ *size = fskdemod(dest, size2,50,1,10,8); //fsk2a
+ if (*size < 96*2) return -2;
+ // 00011101 bit pattern represent start of frame, 01 pattern represents a 0 and 10 represents a 1
+ uint8_t preamble[] = {0,0,0,1,1,1,0,1};
+ // find bitstring in array
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -3; //preamble not found
+
+ numStart = startIdx + sizeof(preamble);
+ // final loop, go over previously decoded FSK data and manchester decode into usable tag ID
+ for (size_t idx = numStart; (idx-numStart) < *size - sizeof(preamble); idx+=2){
+ if (dest[idx] == dest[idx+1]){
+ return -4; //not manchester data
+ }
+ *hi2 = (*hi2<<1)|(*hi>>31);
+ *hi = (*hi<<1)|(*lo>>31);
+ //Then, shift in a 0 or one into low
+ if (dest[idx] && !dest[idx+1]) // 1 0
+ *lo=(*lo<<1)|1;
+ else // 0 1
+ *lo=(*lo<<1)|0;
+ }
+ return (int)startIdx;
+}
+
+int IOdemodFSK(uint8_t *dest, size_t size) {
+ if (justNoise(dest, size)) return -1;
+ //make sure buffer has data
+ if (size < 66*64) return -2;
+ // FSK demodulator
+ size = fskdemod(dest, size, 64, 1, 10, 8); // FSK2a RF/64
+ if (size < 65) return -3; //did we get a good demod?
+ //Index map
+ //0 10 20 30 40 50 60
+ //| | | | | | |
+ //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
+ //-----------------------------------------------------------------------------
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+ //
+ //XSF(version)facility:codeone+codetwo
+ //Handle the data
+ size_t startIdx = 0;
+ uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,1};
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), &size, &startIdx);
+ if (errChk == 0) return -4; //preamble not found
+
+ if (!dest[startIdx+8] && dest[startIdx+17]==1 && dest[startIdx+26]==1 && dest[startIdx+35]==1 && dest[startIdx+44]==1 && dest[startIdx+53]==1){
+ //confirmed proper separator bits found
+ //return start position
+ return (int) startIdx;
+ }
+ return -5;
+}
+
+// redesigned by marshmellow adjusted from existing decode functions
+// indala id decoding - only tested on 26 bit tags, but attempted to make it work for more
+int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) {
+ //26 bit 40134 format (don't know other formats)
+ uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+ uint8_t preamble_i[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
+ size_t startidx = 0;
+ if (!preambleSearch(bitStream, preamble, sizeof(preamble), size, &startidx)){
+ // if didn't find preamble try again inverting
+ if (!preambleSearch(bitStream, preamble_i, sizeof(preamble_i), size, &startidx)) return -1;
+ *invert ^= 1;
+ }
+ if (*size != 64 && *size != 224) return -2;
+ if (*invert==1)
+ for (size_t i = startidx; i < *size; i++)
+ bitStream[i] ^= 1;
+
+ return (int) startidx;
+}
+
+// loop to get raw paradox waveform then FSK demodulate the TAG ID from it
+int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) {
+ if (justNoise(dest, *size)) return -1;
+
+ size_t numStart=0, size2=*size, startIdx=0;
+ // FSK demodulator
+ *size = fskdemod(dest, size2,50,1,10,8); //fsk2a
+ if (*size < 96) return -2;
+
+ // 00001111 bit pattern represent start of frame, 01 pattern represents a 0 and 10 represents a 1
+ uint8_t preamble[] = {0,0,0,0,1,1,1,1};
+
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -3; //preamble not found
+
+ numStart = startIdx + sizeof(preamble);
+ // final loop, go over previously decoded FSK data and manchester decode into usable tag ID
+ for (size_t idx = numStart; (idx-numStart) < *size - sizeof(preamble); idx+=2){
+ if (dest[idx] == dest[idx+1])
+ return -4; //not manchester data
+ *hi2 = (*hi2<<1)|(*hi>>31);
+ *hi = (*hi<<1)|(*lo>>31);
+ //Then, shift in a 0 or one into low
+ if (dest[idx] && !dest[idx+1]) // 1 0
+ *lo=(*lo<<1)|1;
+ else // 0 1
+ *lo=(*lo<<1)|0;
+ }
+ return (int)startIdx;
+}
+
+// find presco preamble 0x10D in already demoded data
+int PrescoDemod(uint8_t *dest, size_t *size) {
+ //make sure buffer has data
+ if (*size < 64*2) return -2;
+
+ size_t startIdx = 0;
+ uint8_t preamble[] = {1,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -4; //preamble not found
+ //return start position
+ return (int) startIdx;
+}
+
+// by marshmellow
+// FSK Demod then try to locate a Farpointe Data (pyramid) ID
+int PyramiddemodFSK(uint8_t *dest, size_t *size) {
+ //make sure buffer has data
+ if (*size < 128*50) return -5;
+
+ //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?
+
+ 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
+ if (*size != 128) return -3;
+ return (int)startIdx;
+}
+
+// by marshmellow
+// find viking preamble 0xF200 in already demoded data
+int VikingDemod_AM(uint8_t *dest, size_t *size) {
+ //make sure buffer has data
+ if (*size < 64*2) return -2;
+
+ size_t startIdx = 0;
+ uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -4; //preamble not found
+ uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8)
+ ^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8)
+ ^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8);
+ if ( checkCalc != 0xA8 ) return -5;
+ if (*size != 64) return -6;
+ //return start position
+ return (int) startIdx;
+}
+
+
+// by iceman
+// find Visa2000 preamble in already demoded data
+int Visa2kDemod_AM(uint8_t *dest, size_t *size) {
+ if (*size < 96) return -1; //make sure buffer has data
+ size_t startIdx = 0;
+ uint8_t preamble[] = {0,1,0,1,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,1,0};
+ if (preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx) == 0)
+ return -2; //preamble not found
+ if (*size != 96) return -3; //wrong demoded size
+ //return start position
+ return (int)startIdx;