}
//by marshmellow
-//get high and low with passed in fuzz factor. also return noise test = 1 for passed or 0 for only noise
+//get high and low values of a wave with passed in fuzz factor. also return noise test = 1 for passed or 0 for only noise
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo)
{
*high=0;
}
//by marshmellow
-//search for given preamble in given BitStream and return startIndex and length
+//search for given preamble in given BitStream and return success=1 or fail=0 and startIndex and length
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx)
{
uint8_t foundCnt=0;
//by marshmellow
//takes 1s and 0s and searches for EM410x format - output EM ID
-uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx)
+uint64_t Em410xDecodeOld(uint8_t *BitStream, size_t *size, size_t *startIdx)
{
//no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
// otherwise could be a void with no arguments
return 0;
}
+//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)
+{
+ //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
+ // otherwise could be a void with no arguments
+ //set defaults
+ uint32_t i = 0;
+ if (BitStream[1]>1){ //allow only 1s and 0s
+ // PrintAndLog("no data found");
+ return 0;
+ }
+ // 111111111 bit pattern represent start of frame
+ uint8_t preamble[] = {1,1,1,1,1,1,1,1,1};
+ uint32_t idx = 0;
+ uint32_t parityBits = 0;
+ uint8_t errChk = 0;
+ uint8_t FmtLen = 10;
+ *startIdx = 0;
+ for (uint8_t extraBitChk=0; extraBitChk<5; extraBitChk++){
+ errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
+ if (errChk == 0) return 0;
+ if (*size>64) FmtLen = 22;
+ idx = *startIdx + 9;
+ for (i=0; i<FmtLen; i++){ //loop through 10 or 22 sets of 5 bits (50-10p = 40 bits or 88 bits)
+ parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
+ //check even parity
+ if (parityTest(parityBits, 5, 0) == 0){
+ //parity failed try next bit (in the case of 1111111111) but last 9 = preamble
+ startIdx++;
+ errChk = 0;
+ break;
+ }
+ //set uint64 with ID from BitStream
+ for (uint8_t ii=0; ii<4; ii++){
+ *hi = (*hi << 1) | (*lo >> 63);
+ *lo = (*lo << 1) | (BitStream[(i*5)+ii+idx]);
+ }
+ }
+ if (errChk != 0) return 1;
+ //skip last 5 bit parity test for simplicity.
+ // *size = 64 | 128;
+ }
+ return 0;
+}
+
//by marshmellow
//takes 3 arguments - clock, invert, maxErr as integers
//attempts to demodulate ask while decoding manchester
int iii = 0;
uint32_t gLen = *size;
if (gLen > 3000) gLen=3000;
+ //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
+ if (!maxErr) gLen=*clk*2;
uint8_t errCnt =0;
uint16_t MaxBits = 500;
uint32_t bestStart = *size;
}
//by marshmellow
-//take 01 or 10 = 0 and 11 or 00 = 1
+//take 01 or 10 = 1 and 11 or 00 = 0
+//check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
{
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){
+ size_t i=offset;
+ uint16_t MaxBits=512;
+ //if not enough samples - error
+ if (*size < 51) return -1;
+ //check for phase change faults - skip one sample if faulty
+ uint8_t offsetA = 1, offsetB = 1;
+ for (; i<48; i+=2){
+ if (BitStream[i+1]==BitStream[i+2]) offsetA=0;
+ if (BitStream[i+2]==BitStream[i+3]) offsetB=0;
+ }
+ if (!offsetA && offsetB) offset++;
+ for (i=offset; i<*size-3; i+=2){
+ //check for phase error
+ if (i<*size-3 && BitStream[i+1]==BitStream[i+2]) {
+ BitStream[bitnum++]=77;
+ errCnt++;
+ }
if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
BitStream[bitnum++]=1^invert;
} else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
//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 maxErr, uint8_t amp)
{
uint32_t i;
uint32_t iii = 0;
uint32_t gLen = *size;
if (gLen > 500) gLen=500;
+ //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
+ if (!maxErr) gLen=*clk*2;
uint8_t errCnt =0;
uint32_t bestStart = *size;
uint32_t bestErrCnt = maxErr; //(*size/1000);
}
return bestErrCnt;
}
+
+// 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;
+}
+
//translate wave to 11111100000 (1 for each short wave 0 for each long wave)
size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow)
{
size_t i=1;
uint8_t lastBit=BitStream[0];
for (; i<size; i++){
- if (lastBit!=BitStream[i]){
+ if (BitStream[i]==77){
+ //ignore errors
+ } else if (lastBit!=BitStream[i]){
lastBit=BitStream[i];
BitStream[i]=1;
} else {
return;
}
+// by marshmellow
+// convert psk2 demod to psk1 demod
+// from only transition waves are 1s to phase shifts change bit
+void psk2TOpsk1(uint8_t *BitStream, size_t size)
+{
+ uint8_t phase=0;
+ for (size_t i=0; i<size; i++){
+ if (BitStream[i]==1){
+ phase ^=1;
+ }
+ BitStream[i]=phase;
+ }
+ return;
+}
+
// 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)
if (*size<loopCnt) loopCnt = *size;
uint8_t curPhase = *invert;
- size_t i, waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
+ size_t i, waveStart=1, waveEnd=0, firstFullWave=0, lastClkBit=0;
uint8_t fc=0, fullWaveLen=0, tol=1;
uint16_t errCnt=0, waveLenCnt=0;
fc = countPSK_FC(dest, *size);
*clock = DetectPSKClock(dest, *size, *clock);
if (*clock==0) return -1;
int avgWaveVal=0, lastAvgWaveVal=0;
- //find first full wave
+ //find first phase shift
for (i=0; i<loopCnt; i++){
if (dest[i]+fc < dest[i+1] && dest[i+1] >= 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){
+ if (waveLenCnt > fc && waveStart > fc){ //not first peak and is a large wave
+ lastAvgWaveVal = avgWaveVal/(waveLenCnt);
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;
+ if (lastAvgWaveVal > 123) curPhase^=1; //fudge graph 0 a little 123 vs 128
break;
}
- waveStart=0;
- avgWaveVal=0;
+ waveStart = i+1;
+ avgWaveVal = 0;
}
+ avgWaveVal+=dest[i+2];
}
- avgWaveVal+=dest[i+1];
- }
//PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);
lastClkBit = firstFullWave; //set start of wave as clock align
+ //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit);
waveStart = 0;
errCnt=0;
size_t numBits=0;
- //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit);
-
+ //set skipped bits
+ memset(dest+numBits,curPhase^1,firstFullWave / *clock);
+ numBits += (firstFullWave / *clock);
+ dest[numBits++] = curPhase; //set first read bit
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]){
//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++;
+ dest[numBits++] = curPhase;
lastClkBit += *clock;
- } else if (i<lastClkBit+10){
+ } else if (i<lastClkBit+10+fc){
//noise after a phase shift - ignore
} else { //phase shift before supposed to based on clock
errCnt++;
- dest[numBits] = 77;
- numBits++;
+ dest[numBits++] = 77;
}
} else if (i+1 > lastClkBit + *clock + tol + fc){
lastClkBit += *clock; //no phase shift but clock bit
- dest[numBits] = curPhase;
- numBits++;
+ dest[numBits++] = curPhase;
}
avgWaveVal=0;
waveStart=i+1;