浏览代码

[Improve][Modularization][Module_Payment]

2021.05.12 / Folus Wen

Actions:
1. Implement FELICA polling.
2. Disable module beep function.

Files:
1. As follow commit history

Image version: D0.03
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 3 年之前
父节点
当前提交
d2ee14288d
共有 2 个文件被更改,包括 313 次插入221 次删除
  1. 305 219
      EVSE/Modularization/Module_Payment.c
  2. 8 2
      EVSE/Modularization/Module_Payment.h

+ 305 - 219
EVSE/Modularization/Module_Payment.c

@@ -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'};					// Reader LED indicator
 unsigned char BLP_CMD_CA_PKEY[]			= {0x09, 0, 0x03, 'C', 'K', 0x01, 0x03};							// Enable user CA Key
 unsigned char BLP_CMD_SOFTCARD_DISABLE[]= {0x09, 0, 0x03, 'I', 'S', 'D', 'T'};								// Disable soft card wallet application
+unsigned char BLP_CMD_BEEP_DISABLE[] 	= {0x09, 0, 0x03, 'B', 'A', 'D', 'M'};								// Beep disable
 unsigned char BLP_CMD_ERR_BEEP_STYLE[] 	= {0x09, 0, 0x03, 'B', 'D', 0, 0x0c};								// Error beep style configure 2 beeps
 unsigned char BLP_CMD_ERR_BEEP[]		= {0x09, 0, 0x03, 'B', 'T', 'D', 'X'};								// Error beep give sound
 unsigned char BLP_CMD_LRC_ENABLE[]		= {0x09, 0, 0x03, 'L', 'C', 'E', '@'};								// Enable LRC character of track data
@@ -32,12 +33,13 @@ unsigned char USI_CMD_C8_POLL[]			= {0x01, 0x00, 0x00, 0x2b,											// STX, a
 	                         	   	   	   0x9c, 0x01, 0x00,												// Transaction Type, sample: 00
 										   0x9a, 0x03, 0x21, 0x03, 0x24,									// Transaction Date, sample: 2021/03/24
 										   0x9f, 0x21, 0x03, 0x13, 0x36, 0x10,								// Transaction Time, sample: 13:36:10
-										   0xff, 0xff, 0x82, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00,			// Command timeout unit is million second, sample: umlimit
+										   0xff, 0xff, 0x82, 0x05, 0x04, 0x00, 0x00, 0x01, 0x2c,			// Command timeout unit is million second, sample: 300ms
 										   0x00};															// Checksum
 unsigned char USI_CMD_HALT_CARD[]		= {0x01, 0x00, 0x00, 0x01, 'x', 0x78};								// Halt card
 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'};								// Enable NFC function
 unsigned char USI_CMD_NFC_POLL[]		= {0x01, 0, 0, 0x05, 'N', ' ', '3', 0x02, 0x01, 'Z'};				// Polling FELICA(NFC Type 3, 414kbps)
 
 
@@ -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));
 
+	//===============================================
+	// Disable beep (BLP Protocol)
+	//===============================================
+	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));
+
 	//===============================================
 	// Set error beep style (BLP Protocol)
 	//===============================================
@@ -825,206 +848,46 @@ int main(void)
 		}
 	}while((rx_Data[0] != ACK) || (rx_len < 0));
 
+	DEBUG_INFO("Payment module initialize completed.\n");
+
 	//===============================================
 	// Main loop
 	//===============================================
 	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)
-			{
-				//=============================================
-				// wait card to attach the reader and wait C9
-				//=============================================
-				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)); // read response if data count match 512 or timeout.
-					failCount++;
-				} while ((rx_len == 0) && (failCount < RETRY_LIMIT));
-
-				//=============================================
-				// Parse rx_Array to rx_Data
-				//=============================================
-				if((rx_len > 3)  && (failCount < RETRY_LIMIT))
-				{
-					// print this raw data before parse it.
-					//show_data(rx_Array, rx_len);
-
-					if((rx_len = USI2_Parse( rx_Array, rx_Data)) > 0)
-					{
-						// debug the input data message
-						//show_data(rx_Data, rx_len);
-
-						// Copy RAW data to structure
+						// FELICA
 						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]);
 
 						// Wait card removed
 						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))
 							{
 								//DEBUG_INFO("Card seated.\n");
 								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;
-						// Wait card removed
-						do
+						// MIFARE, IDO-15693, Credit Card, Apple Pay in query
+						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))
-							{
-								//DEBUG_INFO("Card seated.\n");
-								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))
+								{
+									//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[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(failCount > RETRY_LIMIT)
+							if(Wait_C9 == true)
 							{
-								C9_Result.isCardPreset = OFF;
-								DEBUG_ERROR("Module status read fail over retry limit.\n");
+								//=============================================
+								// wait card to attach the reader and wait C9
+								//=============================================
+								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)); // read response if data count match 512 or timeout.
+									failCount++;
+								} while ((rx_len == 0) && (failCount < RETRY_LIMIT));
+
+								//=============================================
+								// Parse rx_Array to rx_Data
+								//=============================================
+								if((rx_len > 3)  && (failCount < RETRY_LIMIT))
+								{
+									// print this raw data before parse it.
+									//show_data(rx_Array, rx_len);
+
+									if((rx_len = USI2_Parse( rx_Array, rx_Data)) > 0)
+									{
+										// debug the input data message
+										//show_data(rx_Data, rx_len);
+
+										// Copy RAW data to structure
+										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;
+
+										// Wait card removed
+										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))
+												{
+													//DEBUG_INFO("Card seated.\n");
+													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;
+										// Wait card removed
+										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))
+											{
+												//DEBUG_INFO("Card seated.\n");
+												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;

+ 8 - 2
EVSE/Modularization/Module_Payment.h

@@ -7,6 +7,7 @@
 
 #ifndef MODULE_PAYMENT_H_
 #define MODULE_PAYMENT_H_
+//#define	X86
 
 #include 	<sys/time.h>
 #include 	<sys/timeb.h>
@@ -39,9 +40,14 @@
 #include 	<math.h>
 #include	<limits.h>
 #include	<stdint.h>
-#include	"define.h"
+#ifndef X86
+	#include	"define.h"
+	#define TTY_PORT		"/dev/ttyS3"
+#else
+	#define ConsloePrintLog
+	#define TTY_PORT		"/dev/ttyUSB0"
+#endif
 
-//#define	X86
 
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)