NFCcreate-web/ufr-lib/arduino_ufr/uFR.cpp
2025-09-25 19:04:00 +08:00

348 lines
9.4 KiB
C++

#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";
}
}