- //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);
- if (idx < 0){
- if (g_debugMode==1){
- if (idx == -5)
- PrintAndLog("DEBUG: Error - not enough samples");
- else if (idx == -1)
- PrintAndLog("DEBUG: Error - only noise found");
- else if (idx == -2)
- PrintAndLog("DEBUG: Error - problem during FSK demod");
- else if (idx == -3)
- PrintAndLog("DEBUG: Error - Size not correct: %d", size);
- else if (idx == -4)
- PrintAndLog("DEBUG: Error - Pyramid preamble not found");
- else
- PrintAndLog("DEBUG: Error - idx: %d",idx);
- }
- return 0;
- }
- // Index map
- // 0 10 20 30 40 50 60
- // | | | | | | |
- // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
- // -----------------------------------------------------------------------------
- // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
- // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
-
- // 64 70 80 90 100 110 120
- // | | | | | | |
- // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
- // -----------------------------------------------------------------------------
- // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
- // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
- // |---115---||---------71---------|
- // s = format start bit, o = odd parity of last 7 bits
- // f = facility code, c = card number
- // w = wiegand parity, x = extra space for other formats
- // p = unknown checksum
- // (26 bit format shown)
-
- //get bytes for checksum calc
- uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
- uint8_t csBuff[14] = {0x00};
- for (uint8_t i = 0; i < 13; i++){
- csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
- }
- //check checksum calc
- int checkCS = CRC8Maxim(csBuff,13);
-
- //get raw ID before removing parities
- uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
- uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
- uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32);
- uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32);
- setDemodBuf(BitStream,128,idx);
-
- size = removeParity(BitStream, idx+8, 8, 1, 120);
- if (size != 105){
- if (g_debugMode==1)
- PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
- return 0;
- }
-
- // ok valid card found!
-
- // Index map
- // 0 10 20 30 40 50 60 70
- // | | | | | | | |
- // 01234567890123456789012345678901234567890123456789012345678901234567890
- // -----------------------------------------------------------------------
- // 00000000000000000000000000000000000000000000000000000000000000000000000
- // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
- // 71 80 90 100
- // | | | |
- // 1 2 34567890 1234567890123456 7 8901234
- // ---------------------------------------
- // 1 1 01110011 0000000001000110 0 1001010
- // s w ffffffff cccccccccccccccc w ppppppp
- // |--115-| |------71------|
- // s = format start bit, o = odd parity of last 7 bits
- // f = facility code, c = card number
- // w = wiegand parity, x = extra space for other formats
- // p = unknown checksum
- // (26 bit format shown)
-
- //find start bit to get fmtLen
- int j;
- for (j=0; j<size; j++){
- if(BitStream[j]) break;
- }
- uint8_t fmtLen = size-j-8;
- uint32_t fc = 0;
- uint32_t cardnum = 0;
- uint32_t code1 = 0;
- //uint32_t code2 = 0;
- if (fmtLen==26){
- fc = bytebits_to_byte(BitStream+73, 8);
- cardnum = bytebits_to_byte(BitStream+81, 16);
- code1 = bytebits_to_byte(BitStream+72,fmtLen);
- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
- } else if (fmtLen==45){
- fmtLen=42; //end = 10 bits not 7 like 26 bit fmt
- fc = bytebits_to_byte(BitStream+53, 10);
- cardnum = bytebits_to_byte(BitStream+63, 32);
- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- } else {
- cardnum = bytebits_to_byte(BitStream+81, 16);
- if (fmtLen>32){
- //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
- //code2 = bytebits_to_byte(BitStream+(size-32),32);
- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- } else{
- //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- }
- }
- if (checksum == checkCS)
- PrintAndLog("Checksum %02x passed", checksum);
- else
- PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
-
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
- printDemodBuff();
- }
- return 1;
-}
-
-int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
-{
- static const int LowTone[] = {
- 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, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1
- };
- static const int HighTone[] = {
- 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, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1, -1,
- };
-
- int lowLen = sizeof (LowTone) / sizeof (int);
- int highLen = sizeof (HighTone) / sizeof (int);
- int convLen = (highLen > lowLen) ? highLen : lowLen;
- uint32_t hi = 0, lo = 0;
-
- int i, j;
- int minMark = 0, maxMark = 0;
-
- for (i = 0; i < GraphTraceLen - convLen; ++i) {
- int lowSum = 0, highSum = 0;
-
- for (j = 0; j < lowLen; ++j) {
- lowSum += LowTone[j]*GraphBuffer[i+j];
- }
- for (j = 0; j < highLen; ++j) {
- highSum += HighTone[j] * GraphBuffer[i + j];
- }
- lowSum = abs(100 * lowSum / lowLen);
- highSum = abs(100 * highSum / highLen);
- GraphBuffer[i] = (highSum << 16) | lowSum;
- }
-
- for(i = 0; i < GraphTraceLen - convLen - 16; ++i) {
- int lowTot = 0, highTot = 0;
- // 10 and 8 are f_s divided by f_l and f_h, rounded
- for (j = 0; j < 10; ++j) {
- lowTot += (GraphBuffer[i+j] & 0xffff);
- }
- for (j = 0; j < 8; j++) {
- highTot += (GraphBuffer[i + j] >> 16);
- }
- GraphBuffer[i] = lowTot - highTot;
- if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i];
- if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i];
- }
-
- GraphTraceLen -= (convLen + 16);
- RepaintGraphWindow();
-
- // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
- int max = 0, maxPos = 0;
- for (i = 0; i < 6000; ++i) {
- int dec = 0;
- for (j = 0; j < 3 * lowLen; ++j) {
- dec -= GraphBuffer[i + j];
- }
- for (; j < 3 * (lowLen + highLen ); ++j) {
- dec += GraphBuffer[i + j];
- }
- if (dec > max) {
- max = dec;
- maxPos = i;
- }
- }
-
- // place start of bit sync marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos + 1] = minMark;
-
- maxPos += j;
-
- // place end of bit sync marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos+1] = minMark;
-
- PrintAndLog("actual data bits start at sample %d", maxPos);
- PrintAndLog("length %d/%d", highLen, lowLen);
-
- uint8_t bits[46] = {0x00};
-
- // find bit pairs and manchester decode them
- for (i = 0; i < arraylen(bits) - 1; ++i) {
- int dec = 0;
- for (j = 0; j < lowLen; ++j) {
- dec -= GraphBuffer[maxPos + j];
- }
- for (; j < lowLen + highLen; ++j) {
- dec += GraphBuffer[maxPos + j];
- }
- maxPos += j;
- // place inter bit marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos + 1] = minMark;
-
- // hi and lo form a 64 bit pair
- hi = (hi << 1) | (lo >> 31);
- lo = (lo << 1);
- // store decoded bit as binary (in hi/lo) and text (in bits[])
- if(dec < 0) {
- bits[i] = '1';
- lo |= 1;
- } else {
- bits[i] = '0';
- }
- }
- PrintAndLog("bits: '%s'", bits);
- PrintAndLog("hex: %08x %08x", hi, lo);
- return 0;
+ //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);
+ if (idx < 0){
+ if (g_debugMode==1){
+ if (idx == -5)
+ PrintAndLog("DEBUG: Error - not enough samples");
+ else if (idx == -1)
+ PrintAndLog("DEBUG: Error - only noise found");
+ else if (idx == -2)
+ PrintAndLog("DEBUG: Error - problem during FSK demod");
+ else if (idx == -3)
+ PrintAndLog("DEBUG: Error - Size not correct: %d", size);
+ else if (idx == -4)
+ PrintAndLog("DEBUG: Error - Pyramid preamble not found");
+ else
+ PrintAndLog("DEBUG: Error - idx: %d",idx);
+ }
+ return 0;
+ }
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
+ // -----------------------------------------------------------------------------
+ // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
+ // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
+
+ // 64 70 80 90 100 110 120
+ // | | | | | | |
+ // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
+ // -----------------------------------------------------------------------------
+ // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
+ // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
+ // |---115---||---------71---------|
+ // s = format start bit, o = odd parity of last 7 bits
+ // f = facility code, c = card number
+ // w = wiegand parity, x = extra space for other formats
+ // p = unknown checksum
+ // (26 bit format shown)
+
+ //get bytes for checksum calc
+ uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
+ uint8_t csBuff[14] = {0x00};
+ for (uint8_t i = 0; i < 13; i++){
+ csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
+ }
+ //check checksum calc
+ //checksum calc thanks to ICEMAN!!
+ uint32_t checkCS = CRC8Maxim(csBuff,13);
+
+ //get raw ID before removing parities
+ uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
+ uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
+ uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32);
+ uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32);
+ setDemodBuf(BitStream,128,idx);
+
+ size = removeParity(BitStream, idx+8, 8, 1, 120);
+ if (size != 105){
+ if (g_debugMode==1)
+ PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
+ return 0;
+ }
+
+ // ok valid card found!
+
+ // Index map
+ // 0 10 20 30 40 50 60 70
+ // | | | | | | | |
+ // 01234567890123456789012345678901234567890123456789012345678901234567890
+ // -----------------------------------------------------------------------
+ // 00000000000000000000000000000000000000000000000000000000000000000000000
+ // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+ // 71 80 90 100
+ // | | | |
+ // 1 2 34567890 1234567890123456 7 8901234
+ // ---------------------------------------
+ // 1 1 01110011 0000000001000110 0 1001010
+ // s w ffffffff cccccccccccccccc w ppppppp
+ // |--115-| |------71------|
+ // s = format start bit, o = odd parity of last 7 bits
+ // f = facility code, c = card number
+ // w = wiegand parity, x = extra space for other formats
+ // p = unknown checksum
+ // (26 bit format shown)
+
+ //find start bit to get fmtLen
+ int j;
+ for (j=0; j<size; j++){
+ if(BitStream[j]) break;
+ }
+ uint8_t fmtLen = size-j-8;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ uint32_t code1 = 0;
+ //uint32_t code2 = 0;
+ if (fmtLen==26){
+ fc = bytebits_to_byte(BitStream+73, 8);
+ cardnum = bytebits_to_byte(BitStream+81, 16);
+ code1 = bytebits_to_byte(BitStream+72,fmtLen);
+ PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
+ } else if (fmtLen==45){
+ fmtLen=42; //end = 10 bits not 7 like 26 bit fmt
+ fc = bytebits_to_byte(BitStream+53, 10);
+ cardnum = bytebits_to_byte(BitStream+63, 32);
+ PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+ } else {
+ cardnum = bytebits_to_byte(BitStream+81, 16);
+ if (fmtLen>32){
+ //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
+ //code2 = bytebits_to_byte(BitStream+(size-32),32);
+ PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+ } else{
+ //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
+ PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+ }
+ }
+ if (checksum == checkCS)
+ PrintAndLog("Checksum %02x passed", checksum);
+ else
+ PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
+
+ if (g_debugMode){
+ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
+// 8 databits + 1 parity (1)
+// CIITT 16 chksum
+// NATIONAL CODE, ICAR database
+// COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf
+// FLAG (animal/non-animal)
+/*
+38 IDbits
+10 country code
+1 extra app bit
+14 reserved bits
+1 animal bit
+16 ccitt CRC chksum over 64bit ID CODE.
+24 appli bits.
+
+-- sample: 985121004515220 [ 37FF65B88EF94 ]
+*/
+int CmdFDXBdemodBI(const char *Cmd){
+
+ int invert = 1;
+ int clk = 32;
+ int errCnt = 0;
+ int maxErr = 0;
+ uint8_t BitStream[MAX_DEMOD_BUF_LEN];
+ size_t size = getFromGraphBuf(BitStream);
+
+ errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
+ if ( errCnt < 0 || errCnt > maxErr ) {
+ if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);
+ return 0;
+ }
+
+ errCnt = BiphaseRawDecode(BitStream, &size, maxErr, 1);
+ if (errCnt < 0 || errCnt > maxErr ) {
+ if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
+ return 0;
+ }
+
+ int preambleIndex = FDXBdemodBI(BitStream, &size);
+ if (preambleIndex < 0){
+ if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex);
+ return 0;
+ }
+
+ setDemodBuf(BitStream, 128, preambleIndex);
+
+ // remove but don't verify parity. (pType = 2)
+ size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
+ if ( size <= 103 ) {
+ if (g_debugMode) PrintAndLog("Error removeParity:: %d", size);
+ return 0;
+ }
+ if (g_debugMode) {
+ char *bin = sprint_bin_break(BitStream,size,16);
+ PrintAndLog("DEBUG BinStream:\n%s",bin);
+ }
+ PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:");
+ if (g_debugMode) PrintAndLog("Start marker %d; Size %d", preambleIndex, size);
+
+ //got a good demod
+ uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32);
+ uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10);
+ uint8_t dataBlockBit = BitStream[48];
+ uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14);
+ uint8_t animalBit = BitStream[63];
+ uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16);
+ uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24);
+
+ uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream,32)<<32) | bytebits_to_byte(BitStream+32,32);
+ uint8_t raw[8];
+ num_to_bytes(rawid, 8, raw);
+
+ if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw,8));
+
+ uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
+ PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode);
+ PrintAndLog("National Code: %012llu", NationalCode);
+ PrintAndLog("CountryCode: %04u", countryCode);
+ PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False");
+ PrintAndLog("reserved Code: %u", reservedCode);
+ PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False");
+ PrintAndLog("CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed");
+ PrintAndLog("Extended: 0x%X\n", extended);
+
+ return 1;