int GetNedapBits(uint32_t cn, uint8_t *nedapBits) { uint8_t pre[128]; memset(pre, 0x00, sizeof(pre)); // preamble 1111 1111 10 = 0xFF8 num_to_bytebits(0xFF8, 12, pre); // fixed tagtype code? 0010 1101 = 0x2D num_to_bytebits(0x2D, 8, pre+10); // 46 encrypted bits - UNKNOWN ALGO // -- 16 bits checksum. Should be 4x4 checksum, based on UID and 2 constant values. // -- 30 bits undocumented? //num_to_bytebits(cn, 46, pre+18); //----from this part, the UID in clear text, with a 1bit ZERO as separator between bytes. pre[64] = 0; pre[73] = 0; pre[82] = 0; pre[91] = 0; pre[100] = 0; pre[109] = 0; pre[118] = 0; // cardnumber (uid) num_to_bytebits( (cn >> 0) & 0xFF, 8, pre+65); num_to_bytebits( (cn >> 8) & 0xFF, 8, pre+74); num_to_bytebits( (cn >> 16) & 0xFF, 8, pre+83); // two ? num_to_bytebits( 0, 8, pre+92); num_to_bytebits( 0, 8, pre+101); // chksum num_to_bytebits( (0 >> 0) & 0xFF, 8, pre+110); num_to_bytebits( (0 >> 8) & 0xFF, 8, pre+119); // add paritybits (bitsource, dest, sourcelen, paritylen, parityType (odd, even,) addParity(pre, pre+64, 64, 8, 1); addParity(pre+64, pre+64, 64, 8, 1); pre[63] = GetParity( DemodBuffer, EVEN, 63); pre[127] = GetParity( DemodBuffer+64, EVEN, 63); memcpy(nedapBits, pre, 128); // 1111111110001011010000010110100011001001000010110101001101011001000110011010010000000000100001110001001000000001000101011100111 return 1; }
int CommOpen(const char *device_name, unsigned long speed, unsigned data_bits, char parity, unsigned stop_bits) { struct termios tio; int i = -1, fd = -1; Trapdoor(); if (!CheckParity(parity) || !CheckBaudRate(speed) || !CheckStopBits(stop_bits)) return -1; /* open port */ fd = open(device_name, O_RDWR|O_NOCTTY|O_NONBLOCK); if (fd < 0) { #if defined(_DEBUG_SERIAL_) CsDebug(1, (1, "CommOpen: open failed")); #endif return -1; } #if defined(_DEBUG_SERIAL_) CsDebug(1, (1, "CommOpen: opened %s (fd:%d)", device_name, fd)); #endif /* find a handle */ for (i = 0; i < MAX_PORTS; i++) { if (HANDLE(i).fd == -1) break; } if (i == MAX_PORTS) return -1; HANDLE(i).fd = fd; /* don't wory about these for now */ //HANDLE(i).baud = GetBaudRate(speed); //HANDLE(i).parity = GetParity(parity); //HANDLE(i).stop_bits = GetStopBits(stop_bits); //HANDLE(i).data_bits = GetWordLen(data_bits); /* setup baudrate and other communication port configuration */ //newtio.c_cflag = HANDLE(i).baud | // HANDLE(i).parity | // HANDLE(i).stop_bits | // HANDLE(i).data_bits | // CLOCAL|CREAD|PARENB; /* setup baudrate and other communication port configuration */ /* get current attributes */ tcgetattr(fd, &tio); /* set input/ouput baud rate */ cfsetispeed(&tio, GetBaudRate(speed)); cfsetospeed(&tio, GetBaudRate(speed)); /* reset current databits, parity and stopbits settings */ tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); /* set new settings */ tio.c_cflag |= (GetWordLen(data_bits) | GetParity(parity) | GetStopBits(stop_bits) | CREAD | CLOCAL); tio.c_iflag = 0; tio.c_oflag = 0; tio.c_lflag = 0; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; /* write out the attributes */ tcsetattr(fd, TCSAFLUSH, &tio); CsDebug(1, (1, "CommOpen: opened handle %d(%d)", i, fd)); return i; }
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; }