|
@@ -6,28 +6,54 @@
|
|
|
*/
|
|
|
|
|
|
#include "Module_Payment.h"
|
|
|
-unsigned char version[] = {'D', '0', '.', '0', '1'};
|
|
|
-unsigned char CMD_C8[30] = {0xc8,0x01, // Activate the reader
|
|
|
- 0x9f,0x02,0x06,0x00,0x00,0x00,0x01,0x00,0x00, // Amount, Authorized, sample: 100.00 dollar
|
|
|
- 0x5f,0x2a,0x02,0x08,0x40, // Transaction Currency Code follow ISO-4217, sample: 0840(USD)
|
|
|
- 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
|
|
|
-unsigned char CMD_CARD_DETECT[11] = {0x09, 0, 0x07, 'M','F','1','4','1','2','1', 0x32}; // Enable payment, MIFARE, 15693 card; Detect Payment Card First; Enable ApplePay VAS
|
|
|
-unsigned char CMD_USI2[7] = {0x09, 0, 0x03, 'P', 'C', '0', 0x29}; // Configure protocol to USI2
|
|
|
-unsigned char CMD_SET_BAUD[7] = {0x09, 0, 0x03, 'B', 'R', '7', 0x2d}; // Configure module baud rate to 115200
|
|
|
-unsigned char CMD_RESTORE_DEFAULT[7] = {0x09, 0, 0x03, 'D', 'F', 0, 0x08 }; // Restore module configuration to default setting
|
|
|
+unsigned char version[] = {'D', '0', '.', '0', '3'};
|
|
|
+unsigned char BLP_CMD_CARD_DETECT[] = {0x09, 0, 0x07, 'M','F','1','4','1','2','1', 0x32}; // Enable payment, MIFARE, 15693 card; Detect Payment Card First; Enable ApplePay VAS
|
|
|
+unsigned char BLP_CMD_USI2[] = {0x09, 0, 0x03, 'P', 'C', '0', 0x29}; // Configure protocol to USI2
|
|
|
+unsigned char BLP_CMD_SET_BAUD[] = {0x09, 0, 0x03, 'B', 'R', '7', 0x2d}; // Configure module baud rate to 115200
|
|
|
+unsigned char BLP_CMD_RESTORE_DEFAULT[] = {0x09, 0, 0x03, 'D', 'F', 0, 0x08 }; // Restore module configuration to default setting
|
|
|
+unsigned char BLP_CMD_TLV_ENABLE[] = {0x09, 0, 0x03, 'A', 'A', 'E', 'O'}; // Enable TLV command to support EMV transaction
|
|
|
+unsigned char BLP_CMD_SET_AID[] = {0x09, 0, 0x04, 'A', 'D', '0', 0, 0x38}; // Set AID type, 0x00: user defined AID 0x01: Default AID
|
|
|
+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_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
|
|
|
+unsigned char BLP_CMD_TX_TRACK[] = {0x09, 0, 0x03, 'T', 'K', '3', '&'}; // Configure output track data 1&2
|
|
|
+
|
|
|
+unsigned char USI_CMD_WARM_RESET[] = {0x01, 0x00, 0x00, 0x01, 0x7f, 0x7f}; // Payment module warm reset
|
|
|
+unsigned char USI_CMD_MODULE_STATUS[] = {0x01, 0x00, 0x00, 0x01, 0x24, 0x24}; // Deactivate reader
|
|
|
+unsigned char USI_CMD_C8_DEACTIVAVE[] = {0x01, 0x00, 0x00, 0x02, 0xc8, 0x00, 0x00}; // Deactivate reader
|
|
|
+unsigned char USI_CMD_C8_POLL[] = {0x01, 0x00, 0x00, 0x2b, // STX, address, command length high byte, command length low byte
|
|
|
+ 0xc8, 0x01, // Activate the reader
|
|
|
+ 0x9f, 0x02, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // Amount, Authorized, sample: 100.00 dollar
|
|
|
+ 0x5f, 0x2a, 0x02, 0x08, 0x40, // Transaction Currency Code follow ISO-4217, sample: 0840(USD)
|
|
|
+ 0x5f, 0x36, 0x01, 0x02, // Transaction Currency Exponent, Identifies the decimal point position from the right of the transaction amount according to ISO 4217
|
|
|
+ 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
|
|
|
+ 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_POLL[] = {0x01, 0, 0, 0x05, 'N', ' ', '3', 0x02, 0x01, 'Z'}; // Polling FELICA(NFC Type 3, 414kbps)
|
|
|
+
|
|
|
+
|
|
|
int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx);
|
|
|
int USI2_Parse(unsigned char* rx, unsigned char* rx_data);
|
|
|
|
|
|
struct C9_RESULT
|
|
|
{
|
|
|
- unsigned char result_data[512];
|
|
|
+ unsigned char result_data[512]; // C9 response data without header & checksum
|
|
|
|
|
|
- unsigned char status;
|
|
|
- unsigned char pos_entry;
|
|
|
- unsigned char u_id[20];
|
|
|
- unsigned char tkData[4][128];
|
|
|
+ unsigned char status; // C9 response status
|
|
|
+ unsigned char pos_entry; // C9 response pos entry
|
|
|
+ unsigned char u_id[20]; // Card SN
|
|
|
+ unsigned char tkData[4][128]; // Card TK data for credit card
|
|
|
+ unsigned char isCardPreset:1; // Card is presented on module, 0: removed 1: presented
|
|
|
+ unsigned char isCommandError:1; // Polling command result, 0: normal 1: error
|
|
|
} C9_Result;
|
|
|
|
|
|
//==========================================
|
|
@@ -195,6 +221,34 @@ int getSentinelPosition(unsigned char *data, unsigned int dataLen, unsigned char
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param dec: number in dec
|
|
|
+ * @return number in bcd
|
|
|
+ */
|
|
|
+int decTobcd(int dec)
|
|
|
+{
|
|
|
+ return (dec/10 * 16)+ (dec%10);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param data: message array
|
|
|
+ * @param dataLen: command & data field length in array
|
|
|
+ * @return check sum result
|
|
|
+ */
|
|
|
+int calChksum(unsigned char *data, unsigned int dataLen)
|
|
|
+{
|
|
|
+ int result = 0;
|
|
|
+
|
|
|
+ for(uint16_t idx=0;idx<dataLen-1;idx++)
|
|
|
+ {
|
|
|
+ result ^= data[idx];
|
|
|
+ }
|
|
|
+
|
|
|
+ return (result&0xff);
|
|
|
+}
|
|
|
+
|
|
|
//==========================================
|
|
|
// Init share memory
|
|
|
//==========================================
|
|
@@ -207,6 +261,7 @@ int InitShareMemory()
|
|
|
int result = PASS;
|
|
|
int MeterSMId;
|
|
|
|
|
|
+#ifndef X86
|
|
|
//init ShmSysConfigAndInfo
|
|
|
if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
|
|
|
{
|
|
@@ -234,6 +289,7 @@ int InitShareMemory()
|
|
|
}
|
|
|
else
|
|
|
{}
|
|
|
+#endif
|
|
|
|
|
|
return result;
|
|
|
}
|
|
@@ -249,8 +305,11 @@ int InitComPort()
|
|
|
{
|
|
|
int fd;
|
|
|
struct termios tios;
|
|
|
-
|
|
|
+#ifndef X86
|
|
|
fd = open("/dev/ttyS3", O_RDWR);
|
|
|
+#else
|
|
|
+ fd = open("/dev/ttyUSB3", O_RDWR);
|
|
|
+#endif
|
|
|
if(fd<=0)
|
|
|
{
|
|
|
return FAIL;
|
|
@@ -260,8 +319,8 @@ int InitComPort()
|
|
|
tios.c_lflag = 0;
|
|
|
tios.c_iflag = 0;
|
|
|
tios.c_oflag = 0;
|
|
|
- tios.c_cc[VMIN]=0;
|
|
|
- tios.c_cc[VTIME]=(unsigned char)5; // timeout 0.5 seconds
|
|
|
+ tios.c_cc[VMIN]=0; // data length threshold, 0 bytes
|
|
|
+ tios.c_cc[VTIME]=(unsigned char)5; // timeout threshold, 0.5 seconds
|
|
|
tios.c_lflag=0;
|
|
|
tcflush(fd, TCIFLUSH);
|
|
|
ioctl (fd, TCSETS, &tios);
|
|
@@ -282,16 +341,13 @@ int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx)
|
|
|
int rx_len = 0;
|
|
|
|
|
|
tcflush(uart,TCIOFLUSH);
|
|
|
- show_raw(cmd, cmd_len, NO);
|
|
|
+ //show_raw(cmd, cmd_len, NO);
|
|
|
if(write(uart, cmd, cmd_len) > 0)
|
|
|
{
|
|
|
- /*
|
|
|
- * TODO: Improve sleep time.
|
|
|
- */
|
|
|
- usleep(1000000);
|
|
|
+ usleep(100000);
|
|
|
rx_len = read(uart, rx, 512);
|
|
|
|
|
|
- show_raw(rx, rx_len, YES);
|
|
|
+ //show_raw(rx, rx_len, YES);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -328,6 +384,8 @@ int USI2_Parse(unsigned char* rx, unsigned char* rx_data)
|
|
|
memcpy(rx_data, &rx[4], data_len);
|
|
|
result = data_len;
|
|
|
}
|
|
|
+ else
|
|
|
+ DEBUG_WARN("USI2 message checksum error.\n");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -349,11 +407,14 @@ int main(void)
|
|
|
char Wait_C9 = false;
|
|
|
int rx_len = 0;
|
|
|
int data_len = 0;
|
|
|
+ time_t CurrentTime;
|
|
|
+ struct tm *tm;
|
|
|
|
|
|
DEBUG_INFO("Task version: %s\n", version);
|
|
|
//===============================================
|
|
|
// Initialization
|
|
|
//===============================================
|
|
|
+#ifndef X86
|
|
|
if(InitShareMemory() == FAIL)
|
|
|
{
|
|
|
DEBUG_ERROR("InitShareMemory NG\n");
|
|
@@ -365,14 +426,16 @@ int main(void)
|
|
|
sleep(5);
|
|
|
return FAIL;
|
|
|
}
|
|
|
-
|
|
|
+#endif
|
|
|
UartFd=InitComPort();
|
|
|
if(UartFd<0)
|
|
|
{
|
|
|
DEBUG_ERROR("InitComPort NG\n");
|
|
|
if(ShmStatusCodeData!=NULL)
|
|
|
{
|
|
|
+#ifndef X86
|
|
|
ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
|
|
|
+#endif
|
|
|
}
|
|
|
sleep(5);
|
|
|
return FAIL;
|
|
@@ -383,12 +446,11 @@ int main(void)
|
|
|
}
|
|
|
|
|
|
//===============================================
|
|
|
- // Payment module configuration set to default.
|
|
|
+ // Payment module configuration set to default (BLP Protocol)
|
|
|
//===============================================
|
|
|
do
|
|
|
{
|
|
|
- rx_len = system_command(UartFd, CMD_RESTORE_DEFAULT, ARRAY_SIZE(CMD_RESTORE_DEFAULT), rx_Array);
|
|
|
-
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_RESTORE_DEFAULT, ARRAY_SIZE(BLP_CMD_RESTORE_DEFAULT), rx_Array);
|
|
|
if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
{
|
|
|
DEBUG_INFO("Set to the default success.\n");
|
|
@@ -405,15 +467,162 @@ int main(void)
|
|
|
DEBUG_ERROR("Set to the default fail over retry limit.\n");
|
|
|
return FAIL;
|
|
|
}
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len != 1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // set to protocol_2 (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len =system_command(UartFd, BLP_CMD_USI2, ARRAY_SIZE(BLP_CMD_USI2), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set protocol to USI2 success.\n");
|
|
|
+ DEBUG_INFO("Wait for payment module warm-reset.\n");
|
|
|
+ sleep(10);
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set protocol to USI2 fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set protocol to USI2 fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
}while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
-
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Disable self-arm mode (USI2 Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ USI_CMD_ARM_DISABLE[ARRAY_SIZE(USI_CMD_ARM_DISABLE)-1] = calChksum(USI_CMD_ARM_DISABLE, ARRAY_SIZE(USI_CMD_ARM_DISABLE));
|
|
|
+ system_command(UartFd, USI_CMD_ARM_DISABLE, ARRAY_SIZE(USI_CMD_ARM_DISABLE), rx_Array);
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set disable self-arm mode success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set disable self-arm mode fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set disable self-arm mode fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Data[0] != ACK) || (rx_len < 0));
|
|
|
+
|
|
|
//===============================================
|
|
|
- // set payment card detect type.
|
|
|
+ // Enable TLV command (BLP Protocol)
|
|
|
//===============================================
|
|
|
do
|
|
|
{
|
|
|
- rx_len = system_command(UartFd, CMD_CARD_DETECT, ARRAY_SIZE(CMD_CARD_DETECT), rx_Array);
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_TLV_ENABLE, ARRAY_SIZE(BLP_CMD_TLV_ENABLE), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set enable TLV command success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set enable TLV command fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set enable TLV command fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len != 1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set AID type (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_SET_AID, ARRAY_SIZE(BLP_CMD_SET_AID), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set AID type success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set AID type fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set AID type fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len != 1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set LED indicator (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_LED_IND, ARRAY_SIZE(BLP_CMD_LED_IND), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set LED indicator success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set LED indicator fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set LED indicator over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len != 1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set CA public key type (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_CA_PKEY, ARRAY_SIZE(BLP_CMD_CA_PKEY), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set CA public key type success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set CA public key type fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set CA public key type over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len != 1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set payment card detect type (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_CARD_DETECT, ARRAY_SIZE(BLP_CMD_CARD_DETECT), rx_Array);
|
|
|
if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
{
|
|
|
DEBUG_INFO("Set payment card type success.\n");
|
|
@@ -433,30 +642,189 @@ int main(void)
|
|
|
}while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
|
|
|
//===============================================
|
|
|
- // set to protocol_2
|
|
|
+ // Disable soft card wallet application (BLP Protocol)
|
|
|
//===============================================
|
|
|
do
|
|
|
{
|
|
|
- rx_len =system_command(UartFd, CMD_USI2, ARRAY_SIZE(CMD_USI2), rx_Array);
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_SOFTCARD_DISABLE, ARRAY_SIZE(BLP_CMD_SOFTCARD_DISABLE), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set disable soft card success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set disable soft card fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set disable soft card fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set error beep style (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_ERR_BEEP_STYLE, ARRAY_SIZE(BLP_CMD_ERR_BEEP_STYLE), rx_Array);
|
|
|
if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
{
|
|
|
- DEBUG_INFO("Set protocol to USI2 success.\n");
|
|
|
+ DEBUG_INFO("Set error beep style success.\n");
|
|
|
failCount = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- DEBUG_WARN("Set protocol to USI2 fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ DEBUG_WARN("Set error beep style fail (<%02x>).\n", rx_Array[0]);
|
|
|
failCount++;
|
|
|
}
|
|
|
|
|
|
if(failCount > RETRY_LIMIT)
|
|
|
{
|
|
|
- DEBUG_ERROR("Set protocol to USI2 fail over retry limit.\n");
|
|
|
+ DEBUG_ERROR("Set error beep style fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set error beep (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_ERR_BEEP, ARRAY_SIZE(BLP_CMD_ERR_BEEP), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set error beep success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set error beep fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set error beep fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set enable LRC (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_LRC_ENABLE, ARRAY_SIZE(BLP_CMD_LRC_ENABLE), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set enable LRC success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set enable LRC fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set enable LRC fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set TX data tracks (BLP Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ rx_len = system_command(UartFd, BLP_CMD_TX_TRACK, ARRAY_SIZE(BLP_CMD_TX_TRACK), rx_Array);
|
|
|
+ if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set TX data tracks success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set TX data tracks fail (<%02x>).\n", rx_Array[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set TX data tracks over retry limit.\n");
|
|
|
return FAIL;
|
|
|
}
|
|
|
}while((rx_Array[0] != ACK) || (rx_len !=1));
|
|
|
|
|
|
+ //===============================================
|
|
|
+ // Set module RTC date (USI2 Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ CurrentTime = time(NULL);
|
|
|
+ tm=localtime(&CurrentTime);
|
|
|
+ USI_CMD_SET_DATE[6] = ((tm->tm_year+1900)/100);
|
|
|
+ USI_CMD_SET_DATE[7] = ((tm->tm_year+1900)%100);
|
|
|
+ USI_CMD_SET_DATE[8] = (tm->tm_mon+1);
|
|
|
+ USI_CMD_SET_DATE[9] = tm->tm_mday;
|
|
|
+ USI_CMD_SET_DATE[10] = tm->tm_wday==0?0x07:tm->tm_wday;
|
|
|
+ USI_CMD_SET_DATE[ARRAY_SIZE(USI_CMD_SET_DATE)-1] = calChksum(USI_CMD_SET_DATE, ARRAY_SIZE(USI_CMD_SET_DATE));
|
|
|
+ system_command(UartFd, USI_CMD_SET_DATE, ARRAY_SIZE(USI_CMD_SET_DATE), rx_Array);
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set module RTC date success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set module RTC date fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set module RTC date fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Data[0] != ACK) || (rx_len < 0));
|
|
|
+
|
|
|
+ //===============================================
|
|
|
+ // Set module RTC time (USI2 Protocol)
|
|
|
+ //===============================================
|
|
|
+ do
|
|
|
+ {
|
|
|
+ CurrentTime = time(NULL);
|
|
|
+ tm=localtime(&CurrentTime);
|
|
|
+ USI_CMD_SET_TIME[6] = tm->tm_hour;
|
|
|
+ USI_CMD_SET_TIME[7] = tm->tm_min;
|
|
|
+ USI_CMD_SET_TIME[8] = tm->tm_sec;
|
|
|
+ USI_CMD_SET_TIME[ARRAY_SIZE(USI_CMD_SET_TIME)-1] = calChksum(USI_CMD_SET_TIME, ARRAY_SIZE(USI_CMD_SET_TIME));
|
|
|
+ system_command(UartFd, USI_CMD_SET_TIME, ARRAY_SIZE(USI_CMD_SET_TIME), rx_Array);
|
|
|
+ rx_len = USI2_Parse(rx_Array, rx_Data);
|
|
|
+ if((rx_Data[0] == ACK) && (rx_len >= 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Set module RTC time success.\n");
|
|
|
+ failCount = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Set module RTC time fail (<%02x>).\n", rx_Data[0]);
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(failCount > RETRY_LIMIT)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("Set module RTC time fail over retry limit.\n");
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+ }while((rx_Data[0] != ACK) || (rx_len < 0));
|
|
|
+
|
|
|
//===============================================
|
|
|
// Main loop
|
|
|
//===============================================
|
|
@@ -465,19 +833,58 @@ int main(void)
|
|
|
if(C8_Polling == true)
|
|
|
{
|
|
|
Wait_C9 = false;
|
|
|
-
|
|
|
- /*
|
|
|
- * TODO:
|
|
|
- * 1. C8 parameter configure
|
|
|
- */
|
|
|
- rx_len =system_command(UartFd, CMD_C8, sizeof(CMD_C8), rx_Array);
|
|
|
- if((rx_Array[0] == ACK) && (rx_len ==1))
|
|
|
+ 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_INFO("Polling C8 command get response.\n");
|
|
|
- Wait_C9 = true;
|
|
|
- failCount = 0;
|
|
|
+ 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(Wait_C9 == true)
|
|
|
{
|
|
|
//=============================================
|
|
@@ -486,33 +893,33 @@ int main(void)
|
|
|
tcflush(UartFd,TCIOFLUSH);
|
|
|
memset(rx_Array, 0x00, ARRAY_SIZE(rx_Array));
|
|
|
rx_len = 0;
|
|
|
-
|
|
|
+
|
|
|
do
|
|
|
{
|
|
|
- sleep(1);
|
|
|
+ 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);
|
|
|
-
|
|
|
- rx_len = USI2_Parse( rx_Array, rx_Data);
|
|
|
- if(rx_len > 0)
|
|
|
+ //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
|
|
|
+ // 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:
|
|
@@ -522,11 +929,10 @@ int main(void)
|
|
|
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[4], 16);
|
|
|
+ memcpy(C9_Result.u_id, &C9_Result.result_data[5], 16);
|
|
|
DEBUG_INFO("Credit card SN:\n");
|
|
|
show_data(C9_Result.u_id, 16);
|
|
|
|
|
|
- DEBUG_INFO("Payment card\n");
|
|
|
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]));
|
|
@@ -594,17 +1000,84 @@ int main(void)
|
|
|
}
|
|
|
break;
|
|
|
case No_Data:
|
|
|
- DEBUG_INFO("--> No any data.\n");
|
|
|
+ DEBUG_INFO("No any data.\n");
|
|
|
break;
|
|
|
default:
|
|
|
- DEBUG_INFO("--> Unknown pos entry.\n");
|
|
|
+ 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
|
|
|
+ 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
|
|
|
+ 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
|
|
@@ -614,7 +1087,7 @@ int main(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- usleep(500000);
|
|
|
+ usleep(1000000);
|
|
|
}
|
|
|
|
|
|
return FAIL;
|