// Indala 26 bit decode // by marshmellow // optional arguments - same as PSKDemod (clock & invert & maxerr) int CmdIndalaDemod(const char *Cmd) { int ans; if (strlen(Cmd) > 0) ans = PSKDemod(Cmd, 0); else //default to RF/32 ans = PSKDemod("32", 0); if (!ans){ PrintAndLogEx(DEBUG, "DEBUG: Error - Indala can't demod signal: %d",ans); return 0; } uint8_t invert = 0; size_t size = DemodBufferLen; int idx = indala64decode(DemodBuffer, &size, &invert); if (idx < 0 || size != 64) { // try 224 indala invert = 0; size = DemodBufferLen; idx = indala224decode(DemodBuffer, &size, &invert); if (idx < 0 || size != 224) { PrintAndLogEx(DEBUG, "DEBUG: Error - Indala wrong size, expected [64|224] got: %d (startindex %i)", size, idx); return -1; } } setDemodBuf(DemodBuffer, size, (size_t)idx); setClockGrid(g_DemodClock, g_DemodStartIdx + (idx * g_DemodClock)); if (invert) { PrintAndLogEx(DEBUG, "DEBUG: Error - Indala had to invert bits"); for (size_t i = 0; i < size; i++) DemodBuffer[i] ^= 1; } //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; uid1 = bytebits_to_byte(DemodBuffer,32); uid2 = bytebits_to_byte(DemodBuffer+32,32); if (DemodBufferLen == 64){ PrintAndLogEx(SUCCESS, "Indala Found - bitlength %d, UID = (0x%x%08x)\n%s", DemodBufferLen, uid1, uid2, sprint_bin_break(DemodBuffer,DemodBufferLen,32) ); } else { uid3 = bytebits_to_byte(DemodBuffer+64,32); uid4 = bytebits_to_byte(DemodBuffer+96,32); uid5 = bytebits_to_byte(DemodBuffer+128,32); uid6 = bytebits_to_byte(DemodBuffer+160,32); uid7 = bytebits_to_byte(DemodBuffer+192,32); PrintAndLogEx(SUCCESS, "Indala Found - bitlength %d, UID = (0x%x%08x%08x%08x%08x%08x%08x)\n%s", DemodBufferLen, uid1, uid2, uid3, uid4, uid5, uid6, uid7, sprint_bin_break(DemodBuffer, DemodBufferLen, 32) ); } if (g_debugMode){ PrintAndLogEx(DEBUG, "DEBUG: Indala - printing demodbuffer:"); printDemodBuff(); } return 1; }
//see ASKDemod for what args are accepted int CmdVisa2kDemod(const char *Cmd) { //sCmdAskEdgeDetect(""); //ASK / Manchester bool st = true; if (!ASKDemod_ext("64 0 0", false, false, 1, &st)) { if (g_debugMode) PrintAndLog("DEBUG: Error - Visa2k: ASK/Manchester Demod failed"); return 0; } size_t size = DemodBufferLen; int ans = Visa2kDemod_AM(DemodBuffer, &size); if (ans < 0){ if (g_debugMode){ if (ans == -1) PrintAndLog("DEBUG: Error - Visa2k: too few bits found"); else if (ans == -2) PrintAndLog("DEBUG: Error - Visa2k: preamble not found"); else if (ans == -3) PrintAndLog("DEBUG: Error - Visa2k: Size not correct: %d", size); else PrintAndLog("DEBUG: Error - Visa2k: ans: %d", ans); } return 0; } setDemodBuf(DemodBuffer, 96, ans); //setGrid_Clock(64); //got a good demod uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32); uint32_t raw3 = bytebits_to_byte(DemodBuffer+64, 32); // chksum uint8_t calc = visa_chksum(raw2); uint8_t chk = raw3 & 0xF; // test checksums if ( chk != calc ) { printf("DEBUG: error: Visa2000 checksum failed %x - %x\n", chk, calc); return 0; } // parity uint8_t calc_par = visa_parity(raw2); uint8_t chk_par = (raw3 & 0xFF0) >> 4; if ( calc_par != chk_par) { printf("DEBUG: error: Visa2000 parity failed %x - %x\n", chk_par, calc_par); return 0; } PrintAndLog("Visa2000 Tag Found: Card ID %u, Raw: %08X%08X%08X", raw2, raw1 ,raw2, raw3); return 1; }
//see NRZDemod for what args are accepted int CmdPacDemod(const char *Cmd) { //NRZ if (!NRZrawDemod(Cmd, false)) { if (g_debugMode) PrintAndLog("DEBUG: Error - PAC: NRZ Demod failed"); return 0; } size_t size = DemodBufferLen; int ans = PacFind(DemodBuffer, &size); if (ans < 0) { if (g_debugMode) { if (ans == -1) PrintAndLog("DEBUG: Error - PAC: too few bits found"); else if (ans == -2) PrintAndLog("DEBUG: Error - PAC: preamble not found"); else if (ans == -3) PrintAndLog("DEBUG: Error - PAC: Size not correct: %d", size); else PrintAndLog("DEBUG: Error - PAC: ans: %d", ans); } return 0; } setDemodBuf(DemodBuffer, 128, ans); setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock)); //got a good demod uint32_t raw1 = bytebits_to_byte(DemodBuffer , 32); uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32); uint32_t raw3 = bytebits_to_byte(DemodBuffer+64, 32); uint32_t raw4 = bytebits_to_byte(DemodBuffer+96, 32); // preamble then appears to have marker bits of "10" CS? // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001 // unknown checksum 9 bits at the end PrintAndLog("PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1 ,raw2, raw3, raw4); PrintAndLog("\nHow the Raw ID is translated by the reader is unknown"); return 1; }
int CmdPSKNexWatch(const char *Cmd) { if (!PSKDemod("", false)) return 0; uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; size_t startIdx = 0, size = DemodBufferLen; bool invert = false; if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){ // if didn't find preamble try again inverting if (!PSKDemod("1", false)) return 0; size = DemodBufferLen; if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)) return 0; invert = true; } if (size != 128) return 0; setDemodBuf(DemodBuffer, size, startIdx+4); startIdx = 8+32; //4 = extra i added, 8 = preamble, 32 = reserved bits (always 0) //get ID uint32_t ID = 0; for (uint8_t wordIdx=0; wordIdx<4; wordIdx++){ for (uint8_t idx=0; idx<8; idx++){ ID = (ID << 1) | DemodBuffer[startIdx+wordIdx+(idx*4)]; } } //parity check (TBD) //checksum check (TBD) //output PrintAndLog("NexWatch ID: %d", ID); if (invert){ PrintAndLog("Had to Invert - probably NexKey"); for (uint8_t idx=0; idx<size; idx++) DemodBuffer[idx] ^= 1; } CmdPrintDemodBuff("x"); 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; int waveIdx=0; //get binary from fsk wave int idx = PyramiddemodFSK(BitStream, &size, &waveIdx); if (idx < 0){ if (g_debugMode){ 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); setClockGrid(50, waveIdx + (idx*50)); size = removeParity(BitStream, idx+8, 8, 1, 120); if (size != 105){ if (g_debugMode) 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; 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 CmdFdxDemod(const char *Cmd){ //Differential Biphase / di-phase (inverted biphase) //get binary from ask wave if (!ASKbiphaseDemod("0 32 1 0", false)) { if (g_debugMode) PrintAndLog("DEBUG: Error - FDX-B ASKbiphaseDemod failed"); return 0; } size_t size = DemodBufferLen; int preambleIndex = FDXBdemodBI(DemodBuffer, &size); if (preambleIndex < 0){ if (g_debugMode){ if (preambleIndex == -1) PrintAndLog("DEBUG: Error - FDX-B too few bits found"); else if (preambleIndex == -2) PrintAndLog("DEBUG: Error - FDX-B preamble not found"); else if (preambleIndex == -3) PrintAndLog("DEBUG: Error - FDX-B Size not correct: %d", size); else PrintAndLog("DEBUG: Error - FDX-B ans: %d", preambleIndex); } return 0; } // set and leave DemodBuffer intact setDemodBuf(DemodBuffer, 128, preambleIndex); setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex*g_DemodClock)); uint8_t bits_no_spacer[117]; memcpy(bits_no_spacer, DemodBuffer + 11, 117); // remove marker bits (1's every 9th digit after preamble) (pType = 2) size = removeParity(bits_no_spacer, 0, 9, 2, 117); if ( size != 104 ) { if (g_debugMode) PrintAndLog("DEBUG: Error removeParity:: %d", size); return 0; } //got a good demod uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(bits_no_spacer+32,6)) << 32) | bytebits_to_byteLSBF(bits_no_spacer,32); uint32_t countryCode = bytebits_to_byteLSBF(bits_no_spacer+38,10); uint8_t dataBlockBit = bits_no_spacer[48]; uint32_t reservedCode = bytebits_to_byteLSBF(bits_no_spacer+49,14); uint8_t animalBit = bits_no_spacer[63]; uint32_t crc16 = bytebits_to_byteLSBF(bits_no_spacer+64,16); uint32_t extended = bytebits_to_byteLSBF(bits_no_spacer+80,24); uint64_t rawid = ((uint64_t)bytebits_to_byte(bits_no_spacer,32)<<32) | bytebits_to_byte(bits_no_spacer+32,32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); if (g_debugMode) { PrintAndLog("DEBUG: bits_no_spacer:\n%s",sprint_bin_break(bits_no_spacer,size,16)); PrintAndLog("DEBUG: Start marker %d; Size %d", preambleIndex, size); PrintAndLog("DEBUG: Raw ID Hex: %s", sprint_hex(raw,8)); } uint16_t calcCrc = crc16_ccitt_kermit(raw, 8); PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); PrintAndLog("Animal ID: %04u-%012" PRIu64, countryCode, NationalCode); PrintAndLog("National Code: %012" PRIu64, NationalCode); PrintAndLog("CountryCode: %04u", countryCode); PrintAndLog("Reserved Code: %u", reservedCode); PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); PrintAndLog("Has Extended: %s [0x%X]", dataBlockBit ? "True" : "False", extended); PrintAndLog("CRC: 0x%04X - 0x%04X - [%s]\n", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); // set block 0 for later //g_DemodConfig = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT; return 1; }
int CmdLFNedapDemod(const char *Cmd) { //raw ask demod no start bit finding just get binary from wave if (!ASKbiphaseDemod("0 64 1 0", false)) { if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap ASKbiphaseDemod failed"); return 0; } size_t size = DemodBufferLen; int idx = detectNedap(DemodBuffer, &size); if (idx < 0){ if (g_debugMode){ // if (idx == -5) // PrintAndLogEx(DEBUG, "DEBUG: Error - not enough samples"); // else if (idx == -1) // PrintAndLogEx(DEBUG, "DEBUG: Error - only noise found"); // else if (idx == -2) // PrintAndLogEx(DEBUG, "DEBUG: Error - problem during ASK/Biphase demod"); if (idx == -3) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap Size not correct: %d", size); else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap preamble not found"); else PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap idx: %d",idx); } return 0; } /* Index map E E preamble enc tag type encrypted uid P d 33 d 90 d 04 d 71 d 40 d 45 d E7 P 1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1 uid2 uid1 uid0 I I R R 1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1 Tag ID is 049033 I = Identical on all tags R = Random ? UID2, UID1, UID0 == card number */ //get raw ID before removing parities uint32_t raw[4] = {0,0,0,0}; raw[0] = bytebits_to_byte(DemodBuffer+idx+96,32); raw[1] = bytebits_to_byte(DemodBuffer+idx+64,32); raw[2] = bytebits_to_byte(DemodBuffer+idx+32,32); raw[3] = bytebits_to_byte(DemodBuffer+idx,32); setDemodBuf(DemodBuffer, 128, idx); setClockGrid(g_DemodClock, g_DemodStartIdx + (idx*g_DemodClock)); uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63); if ( firstParity != DemodBuffer[63] ) { PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap 1st 64bit parity check failed: %d|%d ", DemodBuffer[63], firstParity); return 0; } uint8_t secondParity = GetParity( DemodBuffer+64, EVEN, 63); if ( secondParity != DemodBuffer[127] ) { PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap 2st 64bit parity check failed: %d|%d ", DemodBuffer[127], secondParity); return 0; } // ok valid card found! uint32_t uid = 0; uid = bytebits_to_byte(DemodBuffer+65, 8); uid |= bytebits_to_byte(DemodBuffer+74, 8) << 8; uid |= bytebits_to_byte(DemodBuffer+83, 8) << 16; uint16_t two = 0; two = bytebits_to_byte(DemodBuffer+92, 8); two |= bytebits_to_byte(DemodBuffer+101, 8) << 8; uint16_t chksum2 = 0; chksum2 = bytebits_to_byte(DemodBuffer+110, 8); chksum2 |= bytebits_to_byte(DemodBuffer+119, 8) << 8; PrintAndLogEx(NORMAL, "NEDAP ID Found - Raw: %08x%08x%08x%08x", raw[3], raw[2], raw[1], raw[0]); PrintAndLogEx(NORMAL, " - UID: %06X", uid); PrintAndLogEx(NORMAL, " - i: %04X", two); PrintAndLogEx(NORMAL, " - Checksum2 %04X", chksum2); if (g_debugMode){ PrintAndLogEx(DEBUG, "DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); printDemodBuff(); PrintAndLogEx(NORMAL, "BIN:\n%s", sprint_bin_break( DemodBuffer, 128, 64) ); } return 1; }