#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 //================================== // MODULE CONSTANT //================================== #define NO_MODULE -1 #define MODULE_EWT 0 #define MODULE_ELATEC 1 //================================== // ACTION CONSTANT //================================== #define SEARCH 1 #define READ 2 #define WRITE 3 //================================== // RFID MODE CONSTANT //================================== unsigned char WUPA = 0; unsigned char REQA = 1; unsigned int STATUS = 0; //================================== // 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} }; //================================== // RFID CMD CONSTANT //================================== unsigned int RFID_CMD_REQUEST_SN = 0x20; 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; //================================== // 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 \"[%04d.%02d.%02d %02d:%02d:%02d] - %s\" >> /Storage/SystemLog/[%04d.%02d]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 //================================= // Common routine //================================= char* getTimeString(void) { char *result=malloc(21); time_t timep; struct tm *p; time(&timep); p=gmtime(&timep); sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec); return result; } //========================================== // 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(500000); 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; } //========================================== // Read RFID card's serial number //========================================== bool getRequestCardSN(int Fd, int moduleType, unsigned char *serialNumber) { bool isSuccess = false; int cardLength; 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_REQUEST_SN; txByte[2] = REQA; txByte[ARRAY_SIZE(txByte)-1] = ClaCheckSum(txByte,ARRAY_SIZE(txByte)); if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); // Send commands if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[1] == RFID_CMD_REQUEST_SN) { if(tmp[0] == 0x09) { #ifdef SystemLogMessage DEBUG_INFO_1("Card type : MIFARE classic.\n"); #endif cardLength = 4; *(serialNumber) = cardLength; memcpy(serialNumber+1, rxByte+2, cardLength); isSuccess = true; } else if(tmp[0] == 0x0C) { #ifdef SystemLogMessage DEBUG_INFO_1("Card type : Plus, UltraLight or DESFire.\n"); #endif cardLength = 7; *(serialNumber) = cardLength; memcpy(serialNumber+1, rxByte+2, cardLength); isSuccess = true; } else { #ifdef SystemLogMessage DEBUG_INFO_1("Please try again.\n"); #endif isSuccess = false; } } else if (tmp[1] == 0xDF) { cardLength = 0; isSuccess = false; } } else {} } else {} break; case MODULE_ELATEC: 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[19]; unsigned char tmp[19]; 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)); // Send commands 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; case MODULE_ELATEC: 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[3]; unsigned char tmp[3]; 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)); // Send commands 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; case MODULE_ELATEC: 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[3]; unsigned char tmp[3]; 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)); // Send commands 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; case MODULE_ELATEC: break; } } //========================================== // Halt RFID card (EWT) //========================================== void sethaltCard(int Fd, int moduleType) { int len = 3; unsigned char txByte[len]; unsigned char rxByte[3]; unsigned char tmp[3]; 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)); // Send commands 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; case MODULE_ELATEC: break; } } //========================================== // Searchtag function (ELATEC Module) //========================================== bool searchTag(int Fd, int moduleType, unsigned char *serialNumber, int status) { bool isSuccess = false; int cardLength; int len = 5; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; // Command txByte[0] = 0x03; txByte[1] = 0x00; txByte[2] = 0x05; txByte[3] = 0x00; txByte[4] = 0x10; // Open port if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); // Send commands if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[3] == 0x01) { if(tmp[6] == 0x04) { if(status == SEARCH) { cardLength = 4; *(serialNumber) = cardLength; memcpy(serialNumber+1, rxByte+7, cardLength); } #ifdef SystemLogMessage DEBUG_INFO_1("Card type: MIFARE classic.\n"); #endif } else if (tmp[6] == 0x07) { cardLength = 7; *(serialNumber) = cardLength; memcpy(serialNumber+1, rxByte+7, cardLength); #ifdef SystemLogMessage DEBUG_INFO_1("Card type: Plus, UltraLight or DESFire.\n"); #endif } isSuccess = true; } else if(tmp[3] == 0x00) { cardLength = 0; isSuccess = false; } } else {} } else {} return isSuccess; } //========================================== // MifareClassic_Login function (ELATEC Module) //========================================== bool MifareClassic_Login(int Fd, int moduleType, int block, unsigned char keyid) { bool isSuccess = false; int i; int j = 0; int len = 12; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; // Command txByte[0] = 0x0A; txByte[1] = 0x00; txByte[2] = 0x0B; txByte[3] = 0x00; for(i = 4; i < 10; i++) { if( j < sizeof (sectorKeyA[0])) { txByte[i] = sectorKeyA[(int)(block/4)][j]; j++; } } txByte[10] = keyid; txByte[11] = block/4; if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); // Send commands if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[3] == 0x01) { #ifdef SystemLogMessage DEBUG_INFO_1("MIFARE classic login pass.\n"); #endif isSuccess = true; } else if(tmp[3] == 0x00) { #ifdef SystemLogMessage DEBUG_INFO_1("MIFARE classic login fail.\n"); #endif isSuccess = false; } else { #ifdef SystemLogMessage DEBUG_WARN_1("Please try again.\n"); #endif isSuccess = false; } } else {} } else {} return isSuccess; } //========================================== // MifareClassic_ReadBlock (ELATEC Module) //========================================== bool MifareClassic_ReadBlock(int Fd, int moduleType, int block,unsigned char *data) { bool isSuccess = false; int len = 5; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; // Command txByte[0] = 0x03; txByte[1] = 0x00; txByte[2] = 0x0B; txByte[3] = 0x01; txByte[4] = block; if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); // Send commands if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[3] == 0x01) { #ifdef SystemLogMessage DEBUG_INFO_1("Read block successfully.\n"); #endif memcpy(data, rxByte+4, 16); isSuccess = true; } else if(tmp[3] == 0x00) { #ifdef SystemLogMessage DEBUG_INFO_1("Unsuccessful to read block.\n"); #endif isSuccess = false; } else { #ifdef SystemLogMessage DEBUG_WARN_1("Please try again.\n"); #endif isSuccess = false; } } else {} } else {} return isSuccess; } //========================================== // MifareClassic_WriteBlock (ELATEC Module) //========================================== bool MifareClassic_WriteBlock(int Fd, int moduleType, int block, unsigned char *data) { bool isSuccess = false; int len = 21; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; // Command txByte[0] = 0x13; txByte[1] = 0x00; txByte[2] = 0x0B; txByte[3] = 0x02; txByte[4] = block; memcpy(txByte+5, data, 16); if(Fd > 0) { memset(rxByte, 0, sizeof (rxByte)); // Send command if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); if(tmp[3] == 0x01) { #ifdef SystemLogMessage DEBUG_INFO_1("Write block successfully.\n"); #endif memcpy(data, rxByte+4, 16); isSuccess = true; } else if(tmp[3] == 0x00) { #ifdef SystemLogMessage DEBUG_INFO_1("Unsuccessful to Write block.\n"); #endif isSuccess = false; } else { #ifdef SystemLogMessage DEBUG_WARN_1("Please try again.\n"); #endif isSuccess = false; } } else {} } else {} return isSuccess; } //========================================== // Beep (ELATEC Module) //========================================== bool SetBeep(int Fd, int moduleType, unsigned char sound) { bool isSuccess = false; int len = 11; unsigned char txByte[len]; unsigned char rxByte[254]; unsigned char tmp[254]; // Command txByte[0] = 0x09; txByte[1] = 0x00; txByte[2] = 0x04; txByte[3] = 0x07; txByte[4] = sound; txByte[5] = 0x60; txByte[6] = 0x09; txByte[7] = 0xF4; txByte[8] = 0x01; txByte[9] = 0xF4; txByte[10] = 0x01; if(Fd > 0) { memset(rxByte, 0, sizeof(rxByte)); // Send command if(system_command(Fd, txByte, len, rxByte) > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rxByte, sizeof(rxByte)); isSuccess = true; } else { isSuccess = true; } } else {} return isSuccess; }