|
@@ -16,6 +16,7 @@ unsigned char BLP_CMD_SET_AID[] = {0x09, 0, 0x04, 'A', 'D', '0', 0, 0x38};
|
|
|
unsigned char BLP_CMD_LED_IND[] = {0x09, 0, 0x05, 'R', 'I', 'E', 0x01, 0x01, 'R'};
|
|
|
unsigned char BLP_CMD_CA_PKEY[] = {0x09, 0, 0x03, 'C', 'K', 0x01, 0x03};
|
|
|
unsigned char BLP_CMD_SOFTCARD_DISABLE[]= {0x09, 0, 0x03, 'I', 'S', 'D', 'T'};
|
|
|
+unsigned char BLP_CMD_BEEP_DISABLE[] = {0x09, 0, 0x03, 'B', 'A', 'D', 'M'};
|
|
|
unsigned char BLP_CMD_ERR_BEEP_STYLE[] = {0x09, 0, 0x03, 'B', 'D', 0, 0x0c};
|
|
|
unsigned char BLP_CMD_ERR_BEEP[] = {0x09, 0, 0x03, 'B', 'T', 'D', 'X'};
|
|
|
unsigned char BLP_CMD_LRC_ENABLE[] = {0x09, 0, 0x03, 'L', 'C', 'E', '@'};
|
|
@@ -32,12 +33,13 @@ unsigned char USI_CMD_C8_POLL[] = {0x01, 0x00, 0x00, 0x2b,
|
|
|
0x9c, 0x01, 0x00,
|
|
|
0x9a, 0x03, 0x21, 0x03, 0x24,
|
|
|
0x9f, 0x21, 0x03, 0x13, 0x36, 0x10,
|
|
|
- 0xff, 0xff, 0x82, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0xff, 0xff, 0x82, 0x05, 0x04, 0x00, 0x00, 0x01, 0x2c,
|
|
|
0x00};
|
|
|
unsigned char USI_CMD_HALT_CARD[] = {0x01, 0x00, 0x00, 0x01, 'x', 0x78};
|
|
|
unsigned char USI_CMD_SET_DATE[] = {0x01, 0, 0, 0x07, '5', '4', 0x14, 0x15, 0x05, 0x02, 0x01, 0x18};
|
|
|
unsigned char USI_CMD_SET_TIME[] = {0x01, 0, 0, 0x07, '5', '5', 0x0f, 0x1e, 0x20, 0, 0, 0x37};
|
|
|
unsigned char USI_CMD_ARM_DISABLE[] = {0x01, 0, 0, 0x02, 'H', '0', '{'};
|
|
|
+unsigned char USI_CMD_NFC_ACTIVE[] = {0x01, 0, 0, 0x02, 'N', 0x00, 'M'};
|
|
|
unsigned char USI_CMD_NFC_POLL[] = {0x01, 0, 0, 0x05, 'N', ' ', '3', 0x02, 0x01, 'Z'};
|
|
|
|
|
|
|
|
@@ -305,11 +307,8 @@ int InitComPort()
|
|
|
{
|
|
|
int fd;
|
|
|
struct termios tios;
|
|
|
-#ifndef X86
|
|
|
- fd = open("/dev/ttyS3", O_RDWR);
|
|
|
-#else
|
|
|
- fd = open("/dev/ttyUSB3", O_RDWR);
|
|
|
-#endif
|
|
|
+
|
|
|
+ fd = open(TTY_PORT, O_RDWR);
|
|
|
if(fd<=0)
|
|
|
{
|
|
|
return FAIL;
|
|
@@ -665,6 +664,30 @@ int main(void)
|
|
|
}
|
|
|
}while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_BEEP_DISABLE, ARRAY_SIZE(BLP_CMD_BEEP_DISABLE), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set beep disable success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set beep disable fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set beep disable fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -825,206 +848,46 @@ int main(void)
|
|
|
}
|
|
|
}while((rx_Data[0] != ACK) || (rx_len < 0));
|
|
|
|
|
|
+ DEBUG_INFO("Payment module initialize completed.\n");
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
for(;;)
|
|
|
{
|
|
|
- if(C8_Polling == true)
|
|
|
+ USI_CMD_NFC_ACTIVE[ARRAY_SIZE(USI_CMD_NFC_ACTIVE)-1] = calChksum(USI_CMD_NFC_ACTIVE, ARRAY_SIZE(USI_CMD_NFC_ACTIVE));
|
|
|
+ if(system_command(UartFd, USI_CMD_NFC_ACTIVE, ARRAY_SIZE(USI_CMD_NFC_ACTIVE), rx_Array) > 0)
|
|
|
{
|
|
|
- Wait_C9 = false;
|
|
|
- CurrentTime = time(NULL);
|
|
|
- tm=localtime(&CurrentTime);
|
|
|
-
|
|
|
- USI_CMD_C8_DEACTIVAVE[ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE)-1] = calChksum(USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE));
|
|
|
- if(system_command(UartFd, USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE), rx_Array) > 0)
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[2] == 0x00) && (rx_len >= 0))
|
|
|
{
|
|
|
- rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
- if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ USI_CMD_NFC_POLL[ARRAY_SIZE(USI_CMD_NFC_POLL)-1] = calChksum(USI_CMD_NFC_POLL, ARRAY_SIZE(USI_CMD_NFC_POLL));
|
|
|
+ if(system_command(UartFd, USI_CMD_NFC_POLL, ARRAY_SIZE(USI_CMD_NFC_POLL), rx_Array) > 0)
|
|
|
{
|
|
|
- DEBUG_INFO("C8 deactivate command success.\n");
|
|
|
- failCount = 0;
|
|
|
-
|
|
|
- USI_CMD_C8_POLL[9] = decTobcd((1000/10000000000)%100);
|
|
|
- USI_CMD_C8_POLL[10] = decTobcd((1000/100000000)%100);
|
|
|
- USI_CMD_C8_POLL[11] = decTobcd((1000/1000000)%100);
|
|
|
- USI_CMD_C8_POLL[12] = decTobcd((1000/10000)%100);
|
|
|
- USI_CMD_C8_POLL[13] = decTobcd((1000/100)%100);
|
|
|
- USI_CMD_C8_POLL[14] = decTobcd((1000/1)%100);
|
|
|
- USI_CMD_C8_POLL[18] = (CURRENCY_USD>>0x08)&0xff;
|
|
|
- USI_CMD_C8_POLL[19] = (CURRENCY_USD>>0x00)&0xff;
|
|
|
- USI_CMD_C8_POLL[29] = decTobcd((tm->tm_year+1900)-2000);
|
|
|
- USI_CMD_C8_POLL[30] = decTobcd(tm->tm_mon+1);
|
|
|
- USI_CMD_C8_POLL[31] = decTobcd(tm->tm_mday);
|
|
|
- USI_CMD_C8_POLL[35] = decTobcd(tm->tm_hour);
|
|
|
- USI_CMD_C8_POLL[36] = decTobcd(tm->tm_min);
|
|
|
- USI_CMD_C8_POLL[37] = decTobcd(tm->tm_sec);
|
|
|
- USI_CMD_C8_POLL[ARRAY_SIZE(USI_CMD_C8_POLL)-1] = calChksum(USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL));
|
|
|
-
|
|
|
- if(system_command(UartFd, USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL), rx_Array) > 0)
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[2] == 0x00) && (rx_len >= 0))
|
|
|
{
|
|
|
- rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
- if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
- {
|
|
|
- DEBUG_INFO("C8 polling command success.\n");
|
|
|
- Wait_C9 = true;
|
|
|
- failCount = 0;
|
|
|
- C9_Result.isCommandError = OFF;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO("C8 polling command fail (<%02x>).\n", rx_Data[0]);
|
|
|
- C9_Result.isCommandError = ON;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO("C8 deactivate command fail.\n");
|
|
|
- C9_Result.isCommandError = ON;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(Wait_C9 == true)
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- tcflush(UartFd,TCIOFLUSH);
|
|
|
- memset(rx_Array, 0x00, ARRAY_SIZE(rx_Array));
|
|
|
- rx_len = 0;
|
|
|
-
|
|
|
- do
|
|
|
- {
|
|
|
- DEBUG_INFO("C9 response reading...\n");
|
|
|
- usleep(2000000);
|
|
|
- rx_len = read(UartFd, rx_Array, ARRAY_SIZE(rx_Array));
|
|
|
- failCount++;
|
|
|
- } while ((rx_len == 0) && (failCount < RETRY_LIMIT));
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- if((rx_len > 3) && (failCount < RETRY_LIMIT))
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- if((rx_len = USI2_Parse( rx_Array, rx_Data)) > 0)
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
memcpy(&C9_Result.result_data, rx_Data, rx_len);
|
|
|
- C9_Result.status = C9_Result.result_data[1];
|
|
|
- C9_Result.pos_entry = C9_Result.result_data[2];
|
|
|
-
|
|
|
- switch(C9_Result.pos_entry)
|
|
|
- {
|
|
|
- case VISA_qVSDC:
|
|
|
- case VISA_MSD:
|
|
|
- case MASTER_MChip:
|
|
|
- case Master_MagStripe:
|
|
|
- case AMEX_EMV:
|
|
|
- case AMEX_MSD:
|
|
|
- memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
- memcpy(C9_Result.u_id, &C9_Result.result_data[5], 16);
|
|
|
- DEBUG_INFO("Credit card SN:\n");
|
|
|
- show_data(C9_Result.u_id, 16);
|
|
|
-
|
|
|
- for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
|
|
|
- {
|
|
|
- memset(C9_Result.tkData[idx], 0x00, ARRAY_SIZE(C9_Result.tkData[idx]));
|
|
|
- memcpy(C9_Result.tkData[idx],
|
|
|
- &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
|
|
|
- (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
|
|
|
-
|
|
|
- DEBUG_INFO("TK[%d]: \n", idx);
|
|
|
- show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
|
|
|
- }
|
|
|
- break;
|
|
|
- case Mifare:
|
|
|
- data_len = C9_Result.result_data[6];
|
|
|
- memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
- memcpy(C9_Result.u_id, &C9_Result.result_data[7], data_len);
|
|
|
-
|
|
|
- switch(C9_Result.result_data[3])
|
|
|
- {
|
|
|
- case MIFARE_ULTRALIGHT:
|
|
|
- DEBUG_INFO("MIFARE Ultralight, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
- break;
|
|
|
- case MIFARE_CLASSIC_1K:
|
|
|
- DEBUG_INFO("MIFARE Classic 1K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
- break;
|
|
|
- case MIFARE_CLASSIC_4K:
|
|
|
- DEBUG_INFO("MIFARE Classic 4K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
- break;
|
|
|
- case MIFARE_DESFIRE:
|
|
|
- DEBUG_INFO("MIFARE DESFire, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
- break;
|
|
|
- case MIFARE_PLUS_2K:
|
|
|
- DEBUG_INFO("MIFARE Plus 2k, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
- break;
|
|
|
- case MIFARE_MINI:
|
|
|
- DEBUG_INFO("MIFARE Mini, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
- break;
|
|
|
- case MIFARE_RESERVE:
|
|
|
- DEBUG_INFO("MIFARE Reserve, UID: \n");
|
|
|
- break;
|
|
|
- case MIFARE_JEWEL:
|
|
|
- DEBUG_INFO("MIFARE Jewel, UID: \n");
|
|
|
- break;
|
|
|
- case MIFARE_JCOP31:
|
|
|
- DEBUG_INFO("MIFARE JCOP31, UID: \n");
|
|
|
- break;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ISO_15693:
|
|
|
- data_len =(C9_Result.result_data[5]<<8) | C9_Result.result_data[6];
|
|
|
- memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
- memcpy(C9_Result.u_id, &C9_Result.result_data[4+data_len-8], 8);
|
|
|
-
|
|
|
- DEBUG_INFO("ISO_15693, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6], C9_Result.u_id[7]);
|
|
|
- break;
|
|
|
- case Apple_Pay:
|
|
|
- DEBUG_INFO("Apple_Pay VAS only.\n");
|
|
|
- for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
|
|
|
- {
|
|
|
- memcpy(C9_Result.tkData[idx],
|
|
|
- &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
|
|
|
- (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
|
|
|
-
|
|
|
- DEBUG_INFO("TK[%d]: \n", idx);
|
|
|
- show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
|
|
|
- }
|
|
|
- break;
|
|
|
- case No_Data:
|
|
|
- DEBUG_INFO("No any data.\n");
|
|
|
- break;
|
|
|
- default:
|
|
|
- DEBUG_WARN("Unknown pos entry.\n");
|
|
|
- if(C9_Result.status == C9_RES_C8_CMD_TIMEOUT)
|
|
|
- DEBUG_WARN("C8 command timeout.\n");
|
|
|
- else if(C9_Result.status == C9_RES_CMD_EXECUTING)
|
|
|
- DEBUG_WARN("Command executing or Wait Card to be Removed.\n");
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
- failCount = 0;
|
|
|
+ C9_Result.status = C9_Result.result_data[2];
|
|
|
+ C9_Result.pos_entry = Felica;
|
|
|
+ memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
+ memcpy(C9_Result.u_id, &C9_Result.result_data[6], 6);
|
|
|
+ DEBUG_INFO("FELICA, UID: %02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5]);
|
|
|
|
|
|
|
|
|
do
|
|
|
{
|
|
|
- system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
|
|
|
+ USI_CMD_NFC_POLL[ARRAY_SIZE(USI_CMD_NFC_POLL)-1] = calChksum(USI_CMD_NFC_POLL, ARRAY_SIZE(USI_CMD_NFC_POLL));
|
|
|
+ system_command(UartFd, USI_CMD_NFC_POLL, ARRAY_SIZE(USI_CMD_NFC_POLL), rx_Array);
|
|
|
rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
- if(!(rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ if((rx_Data[2] != 0x00) && (rx_len >= 0))
|
|
|
{
|
|
|
DEBUG_INFO("Card removed.\n");
|
|
|
C9_Result.isCardPreset = OFF;
|
|
|
failCount = 0;
|
|
|
}
|
|
|
- else if((rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ else if((rx_Data[0] == 0x00) && (rx_len >= 0))
|
|
|
{
|
|
|
|
|
|
C9_Result.isCardPreset = ON;
|
|
@@ -1041,53 +904,276 @@ int main(void)
|
|
|
C9_Result.isCardPreset = OFF;
|
|
|
DEBUG_ERROR("Module status read fail over retry limit.\n");
|
|
|
}
|
|
|
- }while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
|
|
|
+ }while(((rx_Data[2] == 0x00) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- DEBUG_INFO("C9 Parsing result fail.\n");
|
|
|
- C9_Result.isCommandError = ON;
|
|
|
-
|
|
|
- do
|
|
|
+
|
|
|
+ if(C8_Polling == true)
|
|
|
{
|
|
|
- usleep(500000);
|
|
|
- system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
|
|
|
- rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
- if(!(rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
- {
|
|
|
- DEBUG_INFO("Card removed.\n");
|
|
|
- C9_Result.isCardPreset = OFF;
|
|
|
- C9_Result.isCommandError = OFF;
|
|
|
- failCount = 0;
|
|
|
- }
|
|
|
- else if((rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
- {
|
|
|
-
|
|
|
- C9_Result.isCardPreset = ON;
|
|
|
- failCount = 0;
|
|
|
- }
|
|
|
- else
|
|
|
+ Wait_C9 = false;
|
|
|
+ CurrentTime = time(NULL);
|
|
|
+ tm=localtime(&CurrentTime);
|
|
|
+
|
|
|
+ USI_CMD_C8_DEACTIVAVE[ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE)-1] = calChksum(USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE));
|
|
|
+ if(system_command(UartFd, USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE), rx_Array) > 0)
|
|
|
{
|
|
|
- DEBUG_WARN("Module status read fail (<%02x>).\n", rx_Data[0]);
|
|
|
- failCount++;
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ failCount = 0;
|
|
|
+
|
|
|
+ USI_CMD_C8_POLL[9] = decTobcd((1000/10000000000)%100);
|
|
|
+ USI_CMD_C8_POLL[10] = decTobcd((1000/100000000)%100);
|
|
|
+ USI_CMD_C8_POLL[11] = decTobcd((1000/1000000)%100);
|
|
|
+ USI_CMD_C8_POLL[12] = decTobcd((1000/10000)%100);
|
|
|
+ USI_CMD_C8_POLL[13] = decTobcd((1000/100)%100);
|
|
|
+ USI_CMD_C8_POLL[14] = decTobcd((1000/1)%100);
|
|
|
+ USI_CMD_C8_POLL[18] = (CURRENCY_USD>>0x08)&0xff;
|
|
|
+ USI_CMD_C8_POLL[19] = (CURRENCY_USD>>0x00)&0xff;
|
|
|
+ USI_CMD_C8_POLL[29] = decTobcd((tm->tm_year+1900)-2000);
|
|
|
+ USI_CMD_C8_POLL[30] = decTobcd(tm->tm_mon+1);
|
|
|
+ USI_CMD_C8_POLL[31] = decTobcd(tm->tm_mday);
|
|
|
+ USI_CMD_C8_POLL[35] = decTobcd(tm->tm_hour);
|
|
|
+ USI_CMD_C8_POLL[36] = decTobcd(tm->tm_min);
|
|
|
+ USI_CMD_C8_POLL[37] = decTobcd(tm->tm_sec);
|
|
|
+ USI_CMD_C8_POLL[ARRAY_SIZE(USI_CMD_C8_POLL)-1] = calChksum(USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL));
|
|
|
+
|
|
|
+ if(system_command(UartFd, USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL), rx_Array) > 0)
|
|
|
+ {
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ Wait_C9 = true;
|
|
|
+ failCount = 0;
|
|
|
+ C9_Result.isCommandError = OFF;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO("C8 polling command fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ C9_Result.isCommandError = ON;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO("C8 deactivate command fail.\n");
|
|
|
+ C9_Result.isCommandError = ON;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if(failCount > RETRY_LIMIT)
|
|
|
+ if(Wait_C9 == true)
|
|
|
{
|
|
|
- C9_Result.isCardPreset = OFF;
|
|
|
- DEBUG_ERROR("Module status read fail over retry limit.\n");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ tcflush(UartFd,TCIOFLUSH);
|
|
|
+ memset(rx_Array, 0x00, ARRAY_SIZE(rx_Array));
|
|
|
+ rx_len = 0;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+
|
|
|
+ usleep(2000000);
|
|
|
+ rx_len = read(UartFd, rx_Array, ARRAY_SIZE(rx_Array));
|
|
|
+ failCount++;
|
|
|
+ } while ((rx_len == 0) && (failCount < RETRY_LIMIT));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if((rx_len > 3) && (failCount < RETRY_LIMIT))
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if((rx_len = USI2_Parse( rx_Array, rx_Data)) > 0)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ memcpy(&C9_Result.result_data, rx_Data, rx_len);
|
|
|
+ C9_Result.status = C9_Result.result_data[1];
|
|
|
+ C9_Result.pos_entry = C9_Result.result_data[2];
|
|
|
+
|
|
|
+ switch(C9_Result.pos_entry)
|
|
|
+ {
|
|
|
+ case VISA_qVSDC:
|
|
|
+ case VISA_MSD:
|
|
|
+ case MASTER_MChip:
|
|
|
+ case Master_MagStripe:
|
|
|
+ case AMEX_EMV:
|
|
|
+ case AMEX_MSD:
|
|
|
+ memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
+ memcpy(C9_Result.u_id, &C9_Result.result_data[5], 16);
|
|
|
+ DEBUG_INFO("Credit card SN:\n");
|
|
|
+ show_data(C9_Result.u_id, 16);
|
|
|
+
|
|
|
+ for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
|
|
|
+ {
|
|
|
+ memset(C9_Result.tkData[idx], 0x00, ARRAY_SIZE(C9_Result.tkData[idx]));
|
|
|
+ memcpy(C9_Result.tkData[idx],
|
|
|
+ &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
|
|
|
+ (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
|
|
|
+
|
|
|
+ DEBUG_INFO("TK[%d]: \n", idx);
|
|
|
+ show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Mifare:
|
|
|
+ data_len = C9_Result.result_data[6];
|
|
|
+ memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
+ memcpy(C9_Result.u_id, &C9_Result.result_data[7], data_len);
|
|
|
+
|
|
|
+ switch(C9_Result.result_data[3])
|
|
|
+ {
|
|
|
+ case MIFARE_ULTRALIGHT:
|
|
|
+ DEBUG_INFO("MIFARE Ultralight, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
+ break;
|
|
|
+ case MIFARE_CLASSIC_1K:
|
|
|
+ DEBUG_INFO("MIFARE Classic 1K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
+ break;
|
|
|
+ case MIFARE_CLASSIC_4K:
|
|
|
+ DEBUG_INFO("MIFARE Classic 4K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
+ break;
|
|
|
+ case MIFARE_DESFIRE:
|
|
|
+ DEBUG_INFO("MIFARE DESFire, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
+ break;
|
|
|
+ case MIFARE_PLUS_2K:
|
|
|
+ DEBUG_INFO("MIFARE Plus 2k, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
|
|
|
+ break;
|
|
|
+ case MIFARE_MINI:
|
|
|
+ DEBUG_INFO("MIFARE Mini, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
|
|
|
+ break;
|
|
|
+ case MIFARE_RESERVE:
|
|
|
+ DEBUG_INFO("MIFARE Reserve, UID: \n");
|
|
|
+ break;
|
|
|
+ case MIFARE_JEWEL:
|
|
|
+ DEBUG_INFO("MIFARE Jewel, UID: \n");
|
|
|
+ break;
|
|
|
+ case MIFARE_JCOP31:
|
|
|
+ DEBUG_INFO("MIFARE JCOP31, UID: \n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ISO_15693:
|
|
|
+ data_len =(C9_Result.result_data[5]<<8) | C9_Result.result_data[6];
|
|
|
+ memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
|
|
|
+ memcpy(C9_Result.u_id, &C9_Result.result_data[4+data_len-8], 8);
|
|
|
+
|
|
|
+ DEBUG_INFO("ISO_15693, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6], C9_Result.u_id[7]);
|
|
|
+ break;
|
|
|
+ case Apple_Pay:
|
|
|
+ DEBUG_INFO("Apple_Pay VAS only.\n");
|
|
|
+ for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
|
|
|
+ {
|
|
|
+ memcpy(C9_Result.tkData[idx],
|
|
|
+ &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
|
|
|
+ (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
|
|
|
+
|
|
|
+ DEBUG_INFO("TK[%d]: \n", idx);
|
|
|
+ show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case No_Data:
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ DEBUG_WARN("Unknown pos entry.\n");
|
|
|
+ if(C9_Result.status == C9_RES_C8_CMD_TIMEOUT)
|
|
|
+ DEBUG_WARN("C8 command timeout.\n");
|
|
|
+ else if(C9_Result.status == C9_RES_CMD_EXECUTING)
|
|
|
+ DEBUG_WARN("Command executing or Wait Card to be Removed.\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ failCount = 0;
|
|
|
+
|
|
|
+
|
|
|
+ if(C9_Result.pos_entry != No_Data)
|
|
|
+ {
|
|
|
+ do
|
|
|
+ {
|
|
|
+ system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if(!(rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Card removed.\n");
|
|
|
+ C9_Result.isCardPreset = OFF;
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else if((rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ C9_Result.isCardPreset = ON;
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Module status read fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ C9_Result.isCardPreset = OFF;
|
|
|
+ DEBUG_ERROR("Module status read fail over retry limit.\n");
|
|
|
+ }
|
|
|
+ }while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO("C9 Parsing result fail.\n");
|
|
|
+ C9_Result.isCommandError = ON;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ usleep(500000);
|
|
|
+ system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if(!(rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Card removed.\n");
|
|
|
+ C9_Result.isCardPreset = OFF;
|
|
|
+ C9_Result.isCommandError = OFF;
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else if((rx_Data[0]&0x02) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ C9_Result.isCardPreset = ON;
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Module status read fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ C9_Result.isCardPreset = OFF;
|
|
|
+ DEBUG_ERROR("Module status read fail over retry limit.\n");
|
|
|
+ }
|
|
|
+ }while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("C9 Response timeout: %d \n", failCount);
|
|
|
+ }
|
|
|
}
|
|
|
- }while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_WARN("C9 Response timeout: %d \n", failCount);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- usleep(1000000);
|
|
|
+ usleep(500000);
|
|
|
}
|
|
|
|
|
|
return FAIL;
|