+ return FSKrawDemod(Cmd, TRUE);
+}
+
+//by marshmellow (based on existing demod + holiman's refactor)
+//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
+//print full HID Prox ID and some bit format details if found
+int CmdFSKdemodHID(const char *Cmd)
+{
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ uint32_t hi2=0, hi=0, lo=0;
+
+ 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 = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
+ if (idx<0){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Error - HID just noise detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: Error - HID problem during FSK demod");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: Error - HID preamble not found");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Error - HID error in Manchester data, SIZE: %d", BitLen);
+ } else {
+ PrintAndLog("DEBUG: Error - HID error demoding fsk %d", idx);
+ }
+ }
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - HID no values found");
+ return 0;
+ }
+ if (hi2 != 0){ //extra large HID tags
+ 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
+ uint8_t fmtLen = 0;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
+ uint32_t lo2=0;
+ lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
+ uint8_t idx3 = 1;
+ while(lo2>1){ //find last bit set to 1 (format len bit)
+ lo2=lo2>>1;
+ idx3++;
+ }
+ fmtLen =idx3+19;
+ fc =0;
+ cardnum=0;
+ if(fmtLen==26){
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
+ if(fmtLen==34){
+ cardnum = (lo>>1)&0xFFFF;
+ fc= ((hi&1)<<15)|(lo>>17);
+ }
+ if(fmtLen==35){
+ cardnum = (lo>>1)&0xFFFFF;
+ fc = ((hi&1)<<11)|(lo>>21);
+ }
+ }
+ else { //if bit 38 is not set then 37 bit format is used
+ fmtLen = 37;
+ fc = 0;
+ cardnum = 0;
+ if(fmtLen == 37){
+ 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",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
+ (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
+ }
+ setDemodBuf(BitStream,BitLen,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: HID idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+//by marshmellow
+//Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded)
+//print full Paradox Prox ID and some bit format details if found
+int CmdFSKdemodParadox(const char *Cmd)
+{
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ uint32_t hi2=0, hi=0, lo=0;
+
+ 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){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Error - Paradox just noise detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: Error - Paradox error demoding fsk");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: Error - Paradox preamble not found");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Error - Paradox error in Manchester data");
+ } else {
+ PrintAndLog("DEBUG: Error - Paradox error demoding fsk %d", idx);
+ }
+ }
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0){
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Paradox no value found");
+ return 0;
+ }
+ uint32_t fc = ((hi & 0x3)<<6) | (lo>>26);
+ uint32_t cardnum = (lo>>10)&0xFFFF;
+ uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
+ uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
+ uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
+
+ PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x",
+ hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo);
+ setDemodBuf(BitStream,BitLen,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: Paradox idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+//by marshmellow
+//IO-Prox demod - FSK RF/64 with preamble of 000000001
+//print ioprox ID and some format details
+int CmdFSKdemodIO(const char *Cmd)
+{
+ int retval = 0;
+ int idx = 0;
+ char crcStr[20];
+ memset(crcStr, 0x00, sizeof(crcStr) );
+
+ //something in graphbuffer?
+ if (GraphTraceLen < 65) {
+ if (g_debugMode)PrintAndLog("DEBUG: Error - IO prox not enough samples in GraphBuffer");
+ return retval;
+ }
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t bitlen = getFromGraphBuf(BitStream);
+ if (bitlen == 0) return retval;
+
+ //get binary from fsk wave
+ idx = IOdemodFSK(BitStream, bitlen);
+ if (idx<0){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Error - IO prox just noise detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: Error - IO prox not enough samples");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: Error - IO prox error during fskdemod");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Error - IO prox preamble not found");
+ } else if (idx == -5) {
+ PrintAndLog("DEBUG: Error - IO prox separator bits not found");
+ } else {
+ PrintAndLog("DEBUG: Error - IO prox error demoding fsk %d", idx);
+ }
+ }
+ return retval;
+ }
+ if (idx==0){
+ if (g_debugMode){
+ PrintAndLog("DEBUG: Error - IO prox data not found - FSK Bits: %d", bitlen);
+ if (bitlen > 92) PrintAndLog("%s", sprint_bin_break(BitStream,92,16));
+ }
+ return retval;
+ }
+ //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 (raw)
+ //Handle the data
+ if (idx + 64 > bitlen) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - IO prox not enough bits found - bitlen: %d", bitlen);
+ return retval;
+ }
+
+ if (g_debugMode) {
+ 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 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]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d code2", BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]);
+ 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);
+ 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
+ uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
+ uint16_t calccrc = 0;
+
+ for (uint8_t i = 1; i < 6; ++i){
+ calccrc += bytebits_to_byte(BitStream + idx + 9 * i ,8);
+ }
+ calccrc &= 0xff;
+ calccrc = 0xff - calccrc;
+
+ if (crc == calccrc) {
+ snprintf(crcStr, 3, "ok");
+ retval = 1;
+ } else {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - IO prox crc failed");
+
+ snprintf(crcStr, 20, "failed 0x%02X != 0x%02X", crc, calccrc);
+ retval = 0;
+ }
+
+ PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [crc %s]",version,facilitycode,number,code,code2, crcStr);
+ setDemodBuf(BitStream,64,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: IO prox idx: %d, Len: %d, Printing demod buffer:", idx, 64);
+ printDemodBuff();
+ }
+ return retval;
+}
+
+//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
+int CmdFSKdemodAWID(const char *Cmd)
+{
+ 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);
+ if (idx<=0){
+ if (g_debugMode){
+ if (idx == -1)
+ PrintAndLog("DEBUG: Error - AWID not enough samples");
+ else if (idx == -2)
+ PrintAndLog("DEBUG: Error - AWID only noise found");
+ else if (idx == -3)
+ PrintAndLog("DEBUG: Error - AWID problem during FSK demod");
+ else if (idx == -4)
+ PrintAndLog("DEBUG: Error - AWID preamble not found");
+ else if (idx == -5)
+ PrintAndLog("DEBUG: Error - AWID size not correct: %d", size);
+ else
+ PrintAndLog("DEBUG: Error - AWID error %d",idx);
+ }
+ return 0;
+ }
+
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
+ // -----------------------------------------------------------------------------
+ // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
+ // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
+ // |---26 bit---| |-----117----||-------------142-------------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+ // (26 bit format shown)
+
+ //get raw ID before removing parities
+ uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
+ uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
+ uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
+ setDemodBuf(BitStream,96,idx);
+
+ size = removeParity(BitStream, idx+8, 4, 1, 88);
+ if (size != 66){
+ if (g_debugMode) PrintAndLog("DEBUG: Error - AWID at parity check-tag size does not match AWID format");
+ return 0;
+ }
+ // ok valid card found!
+
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
+ // -----------------------------------------------------------------------------
+ // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
+ // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ // |26 bit| |-117--| |-----142------|
+ //
+ // 00110010 0 0000111110100000 00000000000100010010100010000111 1 000000000
+ // bbbbbbbb w ffffffffffffffff cccccccccccccccccccccccccccccccc w xxxxxxxxx
+ // |50 bit| |----4000------| |-----------2248975------------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ uint32_t code1 = 0;
+ uint32_t code2 = 0;
+ uint8_t fmtLen = bytebits_to_byte(BitStream, 8);
+ switch(fmtLen) {
+ case 26:
+ fc = bytebits_to_byte(BitStream + 9, 8);
+ cardnum = bytebits_to_byte(BitStream + 17, 16);
+ code1 = bytebits_to_byte(BitStream + 8,fmtLen);
+ PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
+ break;
+ case 50:
+ fc = bytebits_to_byte(BitStream + 9, 16);
+ cardnum = bytebits_to_byte(BitStream + 25, 32);
+ code1 = bytebits_to_byte(BitStream + 8, (fmtLen-32) );
+ code2 = bytebits_to_byte(BitStream + 8 + (fmtLen-32), 32);
+ PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
+ break;
+ default:
+ if (fmtLen > 32 ) {
+ cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16);
+ code1 = bytebits_to_byte(BitStream+8,fmtLen-32);
+ code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32);
+ PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
+ } else {
+ cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16);
+ code1 = bytebits_to_byte(BitStream+8,fmtLen);
+ PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
+ }
+ break;
+ }
+
+ if (g_debugMode){
+ PrintAndLog("DEBUG: AWID idx: %d, Len: %d Printing Demod Buffer:", idx, 96);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+//by marshmellow
+//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
+//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
+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);
+ if (idx < 0){
+ if (g_debugMode){
+ if (idx == -5)
+ PrintAndLog("DEBUG: Error - Pyramid: not enough samples");
+ else if (idx == -1)
+ PrintAndLog("DEBUG: Error - Pyramid: only noise found");
+ else if (idx == -2)
+ PrintAndLog("DEBUG: Error - Pyramid: problem during FSK demod");
+ else if (idx == -3)
+ PrintAndLog("DEBUG: Error - Pyramid: size not correct: %d", size);
+ else if (idx == -4)
+ PrintAndLog("DEBUG: Error - Pyramid: preamble not found");
+ else
+ PrintAndLog("DEBUG: Error - Pyramid: 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 = CRC8maxim 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) {
+ if ( size == 0)
+ PrintAndLog("DEBUG: Error - Pyramid: parity check failed - IDX: %d, hi3: %08X", idx, rawHi3);
+ else
+ PrintAndLog("DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %08X", 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 = CRC8-Maxim 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;
+
+ 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);
+ 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: Pyramid: 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: Error - FDXB 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("DEBUG: Error - FDXB BiphaseRawDecode: %d", errCnt);
+ return 0;
+ }
+
+ int preambleIndex = FDXBdemodBI(BitStream, &size);
+ if (preambleIndex < 0){
+ if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB preamble not found :: %d",preambleIndex);
+ return 0;
+ }
+ if (size != 128) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB incorrect data length found");
+ return 0;
+ }
+
+ setDemodBuf(BitStream, 128, preambleIndex);
+
+ // remove marker bits (1's every 9th digit after preamble) (pType = 2)
+ size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
+ if ( size != 104 ) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB 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;