/* * Module_RFID.h * * Created on: 2019-10-24 * Update: 2020-07-29 * Author: Eason Yang * Version: D0.01 */ #include "Module_RFID.h" //================================== // PRINT OUT LOG FORMAT //================================== #define SystemLogMessage #define DEBUG_INFO_1(format, args...) StoreLogMessage("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN_1(format, args...) StoreLogMessage("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR_1(format, args...) StoreLogMessage("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) //================================== // SYSTEM CONSTANT //================================== #define Debug #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 //================================== // RFID CMD CONSTANT //================================== unsigned int RFID_CMD_ISO1443A_REQUEST = 0x20; unsigned int RFID_CMD_ISO1443B_REQUEST = 0x60; unsigned int RFID_CMD_FELICA_POLLING_REQUEST = 0x2F; unsigned int RFID_CMD_HALT_14443A = 0x28; unsigned int RFID_CMD_BLOCK_READ = 0x21; unsigned int RFID_CMD_BLOCK_WRITE = 0x22; unsigned int RFID_CMD_BUZZER_SET = 0x14; unsigned int RFID_CMD_RF_OUTPUT_LEVEL_SET = 0x02; unsigned int RFID_CMD_DEFAULT_AUTO_DETECTING_CARD = 0x1D; //================================== // RFID MODE CONSTANT //================================== unsigned char WUPA = 0; unsigned char REQA = 1; unsigned char AFI = 0; //================================== // MIFARE CARD LENGTH //================================== unsigned int LENGTH_0 = 0; unsigned int LENGTH_4 = 4; unsigned int LENGTH_6 = 6; unsigned int LENGTH_7 = 7; unsigned int LENGTH_10 = 10; //================================== // RF output Level constant //================================== unsigned int RF_STRONGEST = 0x00; unsigned int RF_STRONGER = 0x01; unsigned int RF_WEAK = 0x02; unsigned int RF_WEAKEST = 0x03; //================================== // Default of Automatic Detecting constant //================================== unsigned int TURN_OFF = 0x00; unsigned int TURN_ON = 0X01; unsigned int TURN_TEMPORARILY = 0x11; //================================== // MIFARE SECTOR SPACE //================================== #define ROW 6 #define COLUMN 16 unsigned char sectorKeyA[COLUMN][ROW] = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} }; unsigned char serialNumber[32]; unsigned int cardLength; //================================== // SystemLog message //================================== #ifdef SystemLogMessage int StoreLogMessage(const char *fmt, ...) { char Buf[4096 + 256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); sprintf(Buf, "echo -n \"[%04d.%02d.%02d %02d:%02d:%02d] - %s\" >> /Storage/SystemLog/[%04d.%02d]RFID_SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, buffer, tm->tm_year + 1900, tm->tm_mon + 1); system(Buf); #ifdef Debug printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, buffer); #endif return rc; } #endif //========================================== // Module's command send/receive //========================================== int system_command(int uart, unsigned char* cmd,int length, unsigned char* rx) { int len; //sleep(2); //required to make flush work, for some reason tcflush(uart,TCIOFLUSH); if(write(uart, cmd, length) >= 0) { usleep(100000); len = read(uart, rx, 256); } else { #ifdef SystemLogMessage DEBUG_ERROR_1("system command %s response fail.\n", cmd); #endif } return len; } //========================================== // Calculation checksum function //========================================== char ClaCheckSum(unsigned char *buffer, int len) { int idx; char chksum = 0; for(idx = 0 ; idx < len-1 ; idx++) { chksum ^= *(buffer+idx); } return chksum; } bool getRequestCardSN(int Fd, int moduleType, RFID* rfid) { bool isSuccess = false; if(ISO14443A_REQUEST_SN(Fd,moduleType,serialNumber) == true) { rfid->cardType = ISO14443A; if(cardLength == LENGTH_4) { rfid->snType = RFID_SN_TYPE_4BYTE; memcpy(rfid->currentCard, &serialNumber, 32); } else if(cardLength == LENGTH_7) { rfid->snType = RFID_SN_TYPE_7BYTE; memcpy(rfid->currentCard, &serialNumber, 32); } isSuccess = true; } else if(ISO14443B_REQUEST_SN(Fd,moduleType,serialNumber) == true) { rfid->cardType = IS014443B; rfid->snType = RFID_SN_TYPE_4BYTE; memcpy(rfid->currentCard, &serialNumber, 32); sleep(2); isSuccess = true; } else if(FELICA_REQUEST_SN(Fd,moduleType,serialNumber) == true) { rfid->cardType = FELICA; rfid->snType = RFID_SN_TYPE_6BYTE; memcpy(rfid->currentCard, &serialNumber, 32); sleep(2); isSuccess = true; } else {} return isSuccess; } //========================================== // ISO14443A Request SN function //========================================== bool ISO14443A_REQUEST_SN(int Fd, int moduleType, unsigned char *data) { bool isSuccess = false; int tx_len = 4; unsigned char txByte[tx_len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = tx_len-1; txByte[1] = RFID_CMD_ISO1443A_REQUEST; txByte[2] = REQA; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); if(system_command(Fd, txByte, tx_len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[1] == RFID_CMD_ISO1443A_REQUEST) { if(tmp[0] == 0x09) { #ifdef SystemLogMessage DEBUG_INFO_1("MIFARE CLASSIC.\n"); #endif cardLength = LENGTH_4; memcpy(data, rxByte+2, cardLength); isSuccess = true; } else if(tmp[0] == 0x0C) { #ifdef SystemLogMessage DEBUG_INFO_1("MIFARE PLUS.\n"); #endif cardLength = LENGTH_7; memcpy(data, rxByte+2, cardLength); isSuccess = true; } else {} } else if (tmp[1] == 0xDF) { cardLength = LENGTH_0; isSuccess = false; } } else {} } else {} break; } return isSuccess; } //========================================== // ISO14443B Request SN function //========================================== bool ISO14443B_REQUEST_SN(int Fd, int moduleType, unsigned char *data) { bool isSuccess = false; int cardLength; int tx_len = 5; unsigned char txByte[tx_len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = tx_len-1; txByte[1] = RFID_CMD_ISO1443B_REQUEST; txByte[2] = WUPA; txByte[3] = AFI; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); if(system_command(Fd, txByte, tx_len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[1] == RFID_CMD_ISO1443B_REQUEST) { #ifdef SystemLogMessage DEBUG_INFO_1("ISO14443 TYPE B.\n"); #endif cardLength = LENGTH_4; memcpy(data, rxByte+3, cardLength); isSuccess = true; } else if(tmp[1] == 0x9F) { cardLength = LENGTH_0; isSuccess = false; } } else {} } else {} break; } return isSuccess; } //========================================== // FELICA Request SN function //========================================== bool FELICA_REQUEST_SN(int Fd, int moduleType, unsigned char *data) { bool isSuccess = false; int cardLength; int tx_len = 9; unsigned char txByte[tx_len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = tx_len-1; txByte[1] = RFID_CMD_FELICA_POLLING_REQUEST; txByte[2] = 0x06; txByte[3] = 0x00; txByte[4] = 0xFF; txByte[5] = 0xFF; txByte[6] = 0x01; txByte[7] = 0x00; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); if(system_command(Fd, txByte, tx_len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[1] == RFID_CMD_FELICA_POLLING_REQUEST) { #ifdef SystemLogMessage DEBUG_INFO_1("FELICA.\n"); #endif cardLength = LENGTH_6; memcpy(data, rxByte+6, cardLength); isSuccess = true; } else if(tmp[1] == 0xD0) { cardLength = LENGTH_0; isSuccess = false; } } else {} } else {} break; } return isSuccess; } //========================================== // Read block data from RFID card //========================================== bool getBlockRead(int Fd, int moduleType, int block, unsigned char keyId, unsigned char *data) { bool isSuccess = false; int i; int j = 0; int len = 11; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x0A; txByte[1] = RFID_CMD_BLOCK_READ; txByte[2] = keyId; txByte[3] = block; for(i = 4; i < 10; i++) { if( j < sizeof (sectorKeyA[0])) { txByte[i] = sectorKeyA[(int)(block/4)][j]; j++; } } txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if((tmp[1] == RFID_CMD_BLOCK_READ)) { #ifdef SystemLogMessage DEBUG_INFO_1("Read block ok.\n"); #endif memcpy(data, rxByte+2, 16); isSuccess = true; } else if (tmp[1] == 0xDE) { #ifdef SystemLogMessage DEBUG_INFO_1("Read block failed.\n"); #endif } else {} } else {} } else {} break; } return isSuccess; } //========================================== // Write data into RFID card block //========================================== bool setBlockWrite(int Fd, int moduleType, int block, unsigned char keyid, unsigned char *data) { bool isSuccess = false; int i; int j = 0; int len = 27; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x1A; txByte[1] = RFID_CMD_BLOCK_WRITE; txByte[2] = keyid; txByte[3] = block; for(i = 4; i < 10; i++) { if( j < sizeof (sectorKeyA[0])) { txByte[i] = sectorKeyA[(int)(block/4)][j]; j++; } } memcpy(txByte+10, data, 16); txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,(ARRAY_SIZE(txByte))); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if(tmp[1] == RFID_CMD_BLOCK_WRITE) { #ifdef SystemLogMessage DEBUG_INFO_1("Write block ok.\n"); #endif isSuccess = true; } else if(tmp[1] == 0xDD) { #ifdef SystemLogMessage DEBUG_INFO_1("Write block failed.\n"); #endif isSuccess = false; } } else {} } else {} break; } return isSuccess; } //========================================== // Buzzer set (EWT Module) //========================================== void setBuzzer(int Fd, int moduleType, unsigned char time) { int len = 4; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x03; txByte[1] = RFID_CMD_BUZZER_SET; if(time > 0x0A) { time = 0x05; txByte[2] = time; #ifdef SystemLogMessage DEBUG_WARN_1("Value is out of range.\n"); #endif } else { txByte[2] = time; } txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if(tmp[1] == 0x14) { #ifdef SystemLogMessage DEBUG_INFO_1("Set Buzzer ok.\n"); DEBUG_INFO_1("Set Buzzer %d ms.\n",time); #endif } else if(tmp[1] == 0xEC) { #ifdef SystemLogMessage DEBUG_INFO_1("Set Buzzer fail.\n"); #endif } } else {} } else {} break; } } //========================================== // Halt RFID card (EWT) //========================================== void sethaltCard(int Fd, int moduleType) { int len = 3; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x02; txByte[1] = RFID_CMD_HALT_14443A; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if(tmp[1] == 0x28) { #ifdef SystemLogMessage DEBUG_INFO_1("Halt card pass.\n"); #endif } else if(tmp[1] == 0xD7) { #ifdef SystemLogMessage DEBUG_INFO_1("Halt card fail.\n"); #endif } else {} } else {} } else {} break; } } //========================================== // Set the RF Output Level //========================================== bool setRfOutputLevel(int Fd, int moduleType, int Value) { bool isSuccess = false; int len = 4; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x03; txByte[1] = RFID_CMD_RF_OUTPUT_LEVEL_SET; txByte[2] = Value; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if(tmp[1] == RFID_CMD_RF_OUTPUT_LEVEL_SET) { #ifdef SystemLogMessage DEBUG_INFO_1("Set the RF Output Level : Pass...\r\n"); #endif if(Value == RF_STRONGEST) { #ifdef SystemLogMessage DEBUG_INFO_1("Strongest...\r\n"); #endif } else if(Value == RF_STRONGER) { #ifdef SystemLogMessage DEBUG_INFO_1("Strong...\r\n"); #endif } else if(Value == RF_WEAK) { #ifdef SystemLogMessage DEBUG_INFO_1("Weak...\r\n"); #endif } else if(Value == RF_WEAKEST) { #ifdef SystemLogMessage DEBUG_INFO_1("Weakest...\r\n"); #endif } isSuccess = true; } else if(tmp[1] == 0xFD) { #ifdef SystemLogMessage DEBUG_INFO_1("Set the RF Output Level : Fail...\r\n"); DEBUG_INFO_1("Unknow value !!! \r\n"); DEBUG_INFO_1("Strongest : SET_RF_STRONGEST...\r\n"); DEBUG_INFO_1("Strong : SET_RF_STRONGER...\r\n"); DEBUG_INFO_1("Weak : SET_RF_WEAK...\r\n"); DEBUG_INFO_1("Weakest : SET_RF_WEAKEST...\r\n"); #endif isSuccess = false; } } else {} } else {} break; } return isSuccess; } //========================================== // Set the Default of Automatic Detecting Card //========================================== bool setDefaultOfAutomaticDetectingCard(int Fd, int moduleType, int Value) { bool isSuccess = false; int len = 4; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; switch(moduleType) { case MODULE_EWT: default: //=============================== // Command //=============================== txByte[0] = 0x03; txByte[1] = RFID_CMD_DEFAULT_AUTO_DETECTING_CARD; txByte[2] = Value; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof (rxByte)); if(tmp[1] == RFID_CMD_DEFAULT_AUTO_DETECTING_CARD) { if(Value == TURN_OFF) { #ifdef SystemLogMessage DEBUG_INFO_1("Default of Automatic Detecting Card : OFF...\r\n"); #endif } else if (Value == TURN_ON) { #ifdef SystemLogMessage DEBUG_INFO_1("Default of Automatic Detecting Card : ON...\r\n"); #endif } else if (Value == TURN_TEMPORARILY) { #ifdef SystemLogMessage DEBUG_INFO_1("Default of Automatic Detecting Card : Temporarily open and close automatically detect card...\r\n"); #endif } isSuccess = true; } else if(tmp[1] == 0xE2) { #ifdef SystemLogMessage DEBUG_INFO_1("Value : SET_DETECTING_OFF = OFF...\r\n"); DEBUG_INFO_1("Value : SET_DETECTING_ON = ON...\r\n"); DEBUG_INFO_1("Value : SET_DETECTING_TEMPORARILY = Temporarily open and close...\r\n"); #endif isSuccess = false; } } else {} } else {} break; } return isSuccess; }