#include "uFR.h" #define PROCESS_EXT(length) \ EXTPacket extPacket(length); \ if (extPacket.getErrorCode() != 0) return extPacket.getErrorCode() #define PROCESS_ACK(command) \ CommonPacket ackPacket(PACKET_ACK, command); \ if (ackPacket.getErrorCode() != 0) return ackPacket.getErrorCode() #define PROCESS_RSP(command) \ CommonPacket rspPacket(PACKET_RSP, command); \ if (rspPacket.getErrorCode() != 0) return rspPacket.getErrorCode() #ifdef ESP32 uFR::uFR(uint8_t uart) : readerSerial(HardwareSerial(uart)) { setPacketSerial(); } uFR::uFR(uint8_t uart, uint8_t rx_pin, uint8_t tx_pin) : readerSerial(HardwareSerial(uart)) { esp32_rx_pin = rx_pin; esp32_tx_pin = tx_pin; setPacketSerial(); } uFR::uFR(uint8_t uart, uint8_t reset) : readerSerial(HardwareSerial(uart)) { pinMode(reset, OUTPUT); digitalWrite(reset, HIGH); resetPin = reset; setPacketSerial(); } uFR::uFR(uint8_t uart, uint8_t reset, uint8_t rx_pin, uint8_t tx_pin) : readerSerial(HardwareSerial(uart)) { pinMode(reset, OUTPUT); digitalWrite(reset, HIGH); resetPin = reset; esp32_rx_pin = rx_pin; esp32_tx_pin = tx_pin; setPacketSerial(); } #else uFR::uFR(uint8_t rx, uint8_t tx) : readerSerial(SoftwareSerial(rx, tx)) { setPacketSerial(); } uFR::uFR(uint8_t rx, uint8_t tx, uint8_t reset) : readerSerial(SoftwareSerial(rx, tx)) { pinMode(reset, OUTPUT); digitalWrite(reset, HIGH); resetPin = reset; setPacketSerial(); } #endif void uFR::setPacketSerial() { Packet::serial = &readerSerial; } void uFR::begin(unsigned long baud) { if(resetPin != 0) { delay(10); digitalWrite(resetPin, LOW); } #ifdef ESP32 if(esp32_rx_pin != 0 && esp32_tx_pin != 0) { readerSerial.begin(baud, SERIAL_8N1, esp32_rx_pin, esp32_tx_pin); } else { readerSerial.begin(baud); } #else readerSerial.begin(baud); #endif } void uFR::hardReset() { if (resetPin != 0) { digitalWrite(resetPin, HIGH); delay(10); digitalWrite(resetPin, LOW); } } void uFR::flushSerial() { while (readerSerial.available() > 0) readerSerial.read(); } void uFR::sendPacketCMD(uint8_t command, uint8_t EXTlength, uint8_t par0, uint8_t par1) { uint8_t packet[PACKET_LENGTH] = { CMD_HEADER, command, CMD_TRAILER, EXTlength, par0, par1, Packet::checksum(packet) }; readerSerial.write(packet, PACKET_LENGTH); } void uFR::sendPacketEXT(uint8_t *packet, uint8_t length) { readerSerial.write(packet, length); readerSerial.write(Packet::checksum(packet, length)); } // ======================================================================================== uint8_t uFR::setRedLED(bool state) { flushSerial(); sendPacketCMD(RED_LIGHT_CONTROL, 0, state); PROCESS_RSP(RED_LIGHT_CONTROL); return 0; } uint8_t uFR::setUserInterfaceSignal(uint8_t light_signal_mode, uint8_t beep_signal_mode) { flushSerial(); sendPacketCMD(USER_INTERFACE_SIGNAL, 0, light_signal_mode, beep_signal_mode); PROCESS_RSP(USER_INTERFACE_SIGNAL); return 0; } uint8_t uFR::setGreenLightBlinking(bool state) { flushSerial(); sendPacketCMD(SET_LED_CONFIG, 0, state); PROCESS_RSP(SET_LED_CONFIG); return 0; } uint8_t uFR::getReaderType(uint8_t readerType[READER_TYPE_SIZE]) { flushSerial(); sendPacketCMD(GET_READER_TYPE); PROCESS_RSP(GET_READER_TYPE); PROCESS_EXT(READER_TYPE_SIZE); extPacket.copyDataReverse(readerType, 0, READER_TYPE_SIZE); return 0; } uint8_t uFR::getReaderSerial(uint8_t readerSerialNumber[READER_SERIAL_SIZE]) { flushSerial(); sendPacketCMD(GET_READER_SERIAL); PROCESS_RSP(GET_READER_SERIAL); PROCESS_EXT(READER_SERIAL_SIZE); extPacket.copyDataReverse(readerSerialNumber, 0, READER_SERIAL_SIZE); return 0; } uint8_t uFR::setReaderKey(uint8_t key[READER_KEY_SIZE], uint8_t index) { flushSerial(); sendPacketCMD(READER_KEY_WRITE, READER_KEY_SIZE + 1, index); PROCESS_ACK(READER_KEY_WRITE); sendPacketEXT(key, READER_KEY_SIZE); PROCESS_RSP(READER_KEY_WRITE); return 0; } uint8_t uFR::getUserData(uint8_t data[USER_DATA_SIZE]) { flushSerial(); sendPacketCMD(USER_DATA_READ); PROCESS_RSP(USER_DATA_READ); PROCESS_EXT(USER_DATA_SIZE); extPacket.copyData(data, 0, USER_DATA_SIZE); return 0; } uint8_t uFR::setUserData(uint8_t data[USER_DATA_SIZE]) { flushSerial(); sendPacketCMD(USER_DATA_WRITE, USER_DATA_SIZE + 1); PROCESS_ACK(USER_DATA_WRITE); sendPacketEXT(data, USER_DATA_SIZE); PROCESS_RSP(USER_DATA_WRITE); return 0; } uint8_t uFR::softReset() { flushSerial(); sendPacketCMD(SELF_RESET); PROCESS_RSP(SELF_RESET); return 0; } uint8_t uFR::getCardIDSimple(uint8_t cardID[CARD_ID_SIZE], uint8_t *cardType) { flushSerial(); sendPacketCMD(GET_CARD_ID); PROCESS_RSP(GET_CARD_ID); PROCESS_EXT(CARD_ID_SIZE); extPacket.copyDataReverse(cardID, 0, CARD_ID_SIZE); if (cardType) *cardType = rspPacket[PAR0_BYTE]; return 0; } uint8_t uFR::getCardID(uint8_t cardID[CARD_ID_EX_SIZE], uint8_t *length, uint8_t *cardType) { flushSerial(); sendPacketCMD(GET_CARD_ID_EX); PROCESS_RSP(GET_CARD_ID_EX); PROCESS_EXT(CARD_ID_EX_SIZE); //extPacket.copyDataReverse(cardID, 0, rspPacket[PAR1_BYTE]); //extPacket.copyData is used to make the order of bytes of cardID as on the card extPacket.copyData(cardID, 0, rspPacket[PAR1_BYTE]); if (cardType) *cardType = rspPacket[PAR0_BYTE]; if (length) *length = rspPacket[PAR1_BYTE]; return 0; } uint8_t uFR::getDesfireUID(uint8_t cardID[CARD_ID_EX_SIZE], uint8_t *length, uint8_t InternalAESKeyIndexReader, uint32_t AID, uint8_t key_number_in_application) { uint8_t desfire_uid_size = 7; //as I can see in protocol, there are no length definitions. UID is always 7B. *length = desfire_uid_size; uint8_t data_to_send[22]; memset(data_to_send, 0, 22); data_to_send[0]=1; data_to_send[1]=InternalAESKeyIndexReader; data_to_send[18] = *((uint8_t *)&AID); data_to_send[19] = *((uint8_t *)&AID+1); data_to_send[20] = *((uint8_t *)&AID+2); data_to_send[21]= key_number_in_application; /* Serial.print("data_to_send = "); for(int i;i<22;i++) { Serial.print(data_to_send[i], HEX); Serial.print(" "); } Serial.print("\n"); */ flushSerial(); sendPacketCMD(GET_DESFIRE_UID, 23); PROCESS_ACK(GET_DESFIRE_UID); sendPacketEXT(data_to_send, 22); PROCESS_RSP(GET_DESFIRE_UID); /* Serial.print("RSP:"); for(int i;i<7;++i) { Serial.print(rspPacket[i], HEX); Serial.print(" "); } Serial.print("\n"); */ if(rspPacket[3]!=12) { return PARAMETERS_ERROR; } PROCESS_EXT(11); extPacket.copyData(cardID, 0, desfire_uid_size); return 0; } uint8_t uFR::getDesfireUIDPK(uint8_t cardID[CARD_ID_EX_SIZE], uint8_t *length, uint8_t *AESKey, uint32_t AID, uint8_t key_number_in_application) { uint8_t desfire_uid_size = 7; //as I can see in protocol, there are no length definitions. UID is always 7B. *length = desfire_uid_size; uint8_t data_to_send[22]; memset(data_to_send, 0, 22); data_to_send[0]=0; data_to_send[1]=0; memcpy(&data_to_send[2], AESKey, 16); data_to_send[18] = *((uint8_t *)&AID); data_to_send[19] = *((uint8_t *)&AID+1); data_to_send[20] = *((uint8_t *)&AID+2); data_to_send[21]= key_number_in_application; /* Serial.print("data_to_send = "); for(int i;i<22;i++) { Serial.print(data_to_send[i], HEX); Serial.print(" "); } Serial.print("\n"); */ flushSerial(); sendPacketCMD(GET_DESFIRE_UID, 23); PROCESS_ACK(GET_DESFIRE_UID); sendPacketEXT(data_to_send, 22); PROCESS_RSP(GET_DESFIRE_UID); /* Serial.print("RSP:"); for(int i;i<7;++i) { Serial.print(rspPacket[i], HEX); Serial.print(" "); } Serial.print("\n"); */ if(rspPacket[3]!=12) { return PARAMETERS_ERROR; } PROCESS_EXT(11); extPacket.copyData(cardID, 0, desfire_uid_size); return 0; } uint8_t uFR::getCardTypeDLogic(uint8_t *cardType) { flushSerial(); sendPacketCMD(GET_DLOGIC_CARD_TYPE); PROCESS_RSP(GET_DLOGIC_CARD_TYPE); *cardType = rspPacket[PAR0_BYTE]; return 0; } // ======================================================================================== // Needs beautifying const char * TypeDLogicToString(uint8_t type) { switch (type) { case 0x00: return "TAG_UNKNOWN"; break; case 0x01: return "DL_MIFARE_ULTRALIGHT"; break; case 0x02: return "DL_MIFARE_ULTRALIGHT_EV1_11"; break; case 0x03: return "DL_MIFARE_ULTRALIGHT_EV1_21"; break; case 0x04: return "DL_MIFARE_ULTRALIGHT_C"; break; case 0x05: return "DL_NTAG_203"; break; case 0x06: return "DL_NTAG_210"; break; case 0x07: return "DL_NTAG_212"; break; case 0x08: return "DL_NTAG_213"; break; case 0x09: return "DL_NTAG_215"; break; case 0x0A: return "DL_NTAG_216"; break; case 0x0B: return "DL_MIKRON_MIK640D"; break; case 0x0C: return "NFC_T2T_GENERIC"; break; case 0x20: return "DL_MIFARE_MINI"; break; case 0x21: return "DL_MIFARE_CLASSIC_1K"; break; case 0x22: return "DL_MIFARE_CLASSIC_4K"; break; case 0x23: return "DL_MIFARE_PLUS_S_2K"; break; case 0x24: return "DL_MIFARE_PLUS_S_4K"; break; case 0x25: return "DL_MIFARE_PLUS_X_2K"; break; case 0x26: return "DL_MIFARE_PLUS_X_4K"; break; case 0x27: return "DL_MIFARE_DESFIRE"; break; case 0x28: return "DL_MIFARE_DESFIRE_EV1_2K"; break; case 0x29: return "DL_MIFARE_DESFIRE_EV1_4K"; break; case 0x2A: return "DL_MIFARE_DESFIRE_EV1_8K"; break; case 0x2B: return "DL_MIFARE_DESFIRE_EV2_2K"; break; case 0x2C: return "DL_MIFARE_DESFIRE_EV2_4K"; break; case 0x2D: return "DL_MIFARE_DESFIRE_EV2_8K"; break; case 0x40: return "DL_GENERIC_ISO14443_4"; break; case 0x41: return "DL_GENERIC_ISO14443_TYPE_B"; break; case 0x80: return "DL_IMEI_UID"; break; default: return "TYPE_ERROR"; } }