123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- /*
- * Module_Payment_Ominixpay.c
- *
- * Created on: 2022/04/29
- * Author: Folus Wen
- */
- #include "Module_Payment_Bazel8.h"
- struct COMMAND commandRaw;
- struct timespec tmr[TIMER_CNT];
- //==========================================
- // Common routine
- //==========================================
- int StoreLogMsg(const char *fmt, ...)
- {
- char Buf[65536+256];
- char buffer[65536];
- //char Buf[4096+256];
- //char buffer[4096];
- time_t CurrentTime;
- struct tm *tm;
- struct timeval tv;
- 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);
- gettimeofday(&tv, NULL); // get microseconds, 10^-6
- sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]PaymentLog",
- tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
- buffer,
- tm->tm_year+1900,tm->tm_mon+1);
- system((const char*)Buf);
- #ifdef ConsloePrintLog
- printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
- #endif
- return rc;
- }
- /**
- * Execute shell command
- * @param cmd: shell command string
- * @return shell command execution result
- */
- int runShellCmd(const char*cmd)
- {
- int result = FAIL;
- char buf[256];
- FILE *fp;
- fp = popen(cmd, "r");
- if(fp != NULL)
- {
- while(fgets(buf, sizeof(buf), fp) != NULL)
- {
- DEBUG_INFO("%s\n", buf);
- }
- result = PASS;
- }
- pclose(fp);
- return result;
- }
- /**
- *
- * @param timer
- */
- void refreshStartTimer(struct timespec *timer)
- {
- clock_gettime(CLOCK_MONOTONIC, timer);
- }
- /**
- *
- * @param timer
- * @return
- */
- int getDiffSecNow(struct timespec timer)
- {
- struct timespec timerNow;
- clock_gettime(CLOCK_MONOTONIC, &timerNow);
- return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
- }
- /**
- *
- * @param ST
- */
- long long DiffTimebWithNow(struct timeb ST)
- {
- //return milli-second
- struct timeb ET;
- long long StartTime,StopTime;
- ftime(&ET);
- StartTime=(long long)ST.time;
- StopTime=(long long)ET.time;
- return ((StopTime-StartTime)*1000) + (ET.millitm-ST.millitm);
- }
- /**
- *
- * @return
- */
- int getTimePassSinceToday()
- {
- int result = -1;
- static time_t lastTime;
- time_t t;
- struct tm *tmStartToday;
- struct timeb tbStartToday;
- t=time(NULL);
- if(difftime(t, lastTime)>0)
- {
- tmStartToday=localtime(&t);
- tmStartToday->tm_hour = 0;
- tmStartToday->tm_min = 0;
- tmStartToday->tm_sec = 0;
- tbStartToday.time = mktime(tmStartToday);
- tbStartToday.millitm = 0;
- result = DiffTimebWithNow(tbStartToday)/1000;
- lastTime = t;
- }
- return result;
- }
- /**
- * Calculate time differential
- * @param ST: start time
- * @param ET: end time
- * @return time differential in million seconds
- */
- int DiffTimeb(struct timeb ST, struct timeb ET)
- {
- //return milli-second
- unsigned int StartTime,StopTime;
- StartTime=(unsigned int)ST.time;
- StopTime=(unsigned int)ET.time;
- return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
- }
- /**
- * Show communication raw data to debug info
- * @param data: raw data
- * @param len: data length
- * @param isRX: is receive data
- */
- void show_raw(uint8_t *data, uint16_t len, uint8_t isRX)
- {
- uint8_t output[512]={0};
- if(isRX)
- DEBUG_INFO("RX ---------------------------------------------\n");
- else
- DEBUG_INFO("TX ---------------------------------------------\n");
- DEBUG_INFO(" 0 1 2 3 4 5 6 7 8 9 A B C D E F \n");
- DEBUG_INFO("------------------------------------------------\n");
- memset(output, 0x00, ARRAY_SIZE(output));
- for(int idx=0;idx<len;idx++)
- {
- if(strlen((char*)output)<48)
- sprintf((char*)output, "%s%02X ", output, data[idx]);
- else
- {
- DEBUG_INFO("%s\n", output);
- memset(output, 0x00, ARRAY_SIZE(output));
- sprintf((char*)output, "%s%02X ", output, data[idx]);
- }
- }
- DEBUG_INFO("%s\n", output);
- }
- /**
- *
- * @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)
- {
- int result = 0;
- for(uint16_t idx=0;idx<(((data[1] << 8) | (data[1]))+3);idx++)
- {
- result ^= data[idx];
- }
- return (result&0xff);
- }
- //==========================================
- // Init share memory
- //==========================================
- /**
- * Share memory initialization
- * @return function result
- */
- int InitShareMemory()
- {
- int result = PASS;
- int MeterSMId;
- #ifndef X86
- //init ShmSysConfigAndInfo
- if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
- {
- DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
- result = FAIL;
- }
- else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
- result = FAIL;
- }
- else
- {}
- //init ShmStatusCodeData
- if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
- {
- DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
- result = FAIL;
- }
- else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
- result = FAIL;
- }
- else
- {}
- //init ShmOCPP16Data
- if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
- {
- DEBUG_ERROR("shmget ShmOCPP16Data NG\n");
- result = FAIL;
- }
- else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- DEBUG_ERROR("shmat ShmOCPP16Data NG\n");
- result = FAIL;
- }
- else
- {}
- #endif
- return result;
- }
- //==========================================
- // Init com port
- //==========================================
- /**
- * TTY port initialization
- * @return port initial result
- */
- int InitComPort()
- {
- int fd;
- struct termios tios;
- fd = open(TTY_PORT, O_RDWR);
- if(fd<=0)
- {
- return FAIL;
- }
- ioctl (fd, TCGETS, &tios);
- tios.c_cflag = B9600| CS8 | CLOCAL | CREAD;
- tios.c_lflag = 0;
- tios.c_iflag = 0;
- tios.c_oflag = 0;
- 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);
- return fd;
- }
- /**
- *
- * @param serial port handle
- * @param request message data
- * @param response message data
- * @return
- */
- int pollingRequest(int uart, unsigned char* cmd)
- {
- int result=FAIL;
- tcflush(uart,TCIOFLUSH);
- cmd[(cmd[1]<<8)|(cmd[2])] = calChksum(cmd);
- //show_raw(cmd, cmd_len, NO);
- if(write(uart, cmd, ARRAY_SIZE(cmd)) > 0)
- {
- result = PASS;
- }
- else
- {
- DEBUG_ERROR("pollingRequest fail.\n");
- }
- return result;
- }
- /**
- *
- * @param uart
- * @param rx
- * @return
- */
- int pollingResponse(int uart, unsigned char* rx)
- {
- int result=FAIL;
- read(uart, rx, RAW_DATA_LENGTH);
- //show_raw(rx, rx_len, YES);
- if(calChksum(&rx[0]) == rx[(((rx[1] << 8) | (rx[1]))+3)])
- {
- result = PASS;
- }
- return result;
- }
- /**
- *
- * @param uart
- * @return
- */
- int getInputBufferCount(int uart)
- {
- int bytes_avail;
- ioctl(uart, FIONREAD, &bytes_avail);
- return bytes_avail;
- }
- /**
- *
- * @param node
- * @param node_name
- * @return
- */
- xmlNode *find_node(xmlNode *node, char *node_name)
- {
- xmlNode *result;
- if (node == NULL) return NULL;
- while(node)
- {
- if((node->type == XML_ELEMENT_NODE) && (strcmp((char*)node->name, node_name) == 0)) return node;
- if((result = find_node(node->children, node_name))) return result;
- node = node->next;
- }
- return NULL;
- }
- //==========================================
- // Reader operation function
- //==========================================
- int preAuthRequest(int uart)
- {
- char xmlBody[512]={0};
- xmlBuffer * outputXmlPtr = xmlBufferCreate();
- xmlDocPtr doc = NULL;
- xmlNodePtr node_req = NULL;
- xmlNodePtr node_cmd = NULL;
- xmlNodePtr node_param = NULL;
- xmlNodePtr node_param_Txn = NULL;
- // Create xml message
- doc = xmlNewDoc(BAD_CAST "1.0");
- node_req = xmlNewNode(NULL, BAD_CAST "Req");
- xmlDocSetRootElement(doc, node_req);
- node_cmd = xmlNewNode(NULL, BAD_CAST "Cmd");
- xmlNewChild(node_cmd, NULL, BAD_CAST "CmdId", BAD_CAST "TxnStart");
- xmlNewChild(node_cmd, NULL, BAD_CAST "CmdTout", BAD_CAST "30");
- xmlAddChild(node_req, node_cmd);
- node_param = xmlNewNode(NULL, BAD_CAST "Param");
- node_param_Txn = xmlNewNode(NULL, BAD_CAST "Txn");
- xmlNewChild(node_param_Txn, NULL, BAD_CAST "TxnType", BAD_CAST "AuthOnly");
- xmlNewChild(node_param_Txn, NULL, BAD_CAST "CurrCode", BAD_CAST "840");
- xmlNewChild(node_param_Txn, NULL, BAD_CAST "TxnAmt", BAD_CAST "100");
- xmlAddChild(node_param, node_param_Txn);
- xmlAddChild(node_req, node_param);
- xmlNodeDump(outputXmlPtr, NULL, (xmlNode *)node_req, 0, 0);
- sprintf(xmlBody, "%s", (const char *)outputXmlPtr->content);
- xmlBufferFree(outputXmlPtr);
- xmlFreeDoc(doc);
- xmlCleanupParser();
- xmlMemoryDump();
- // Create protocol message
- memset(commandRaw.requestData, 0x00, ARRAY_SIZE(commandRaw.requestData));
- commandRaw.requestData[0] = STX;
- commandRaw.requestData[1] = (strlen(xmlBody)>>8)&0xff;
- commandRaw.requestData[2] = (strlen(xmlBody)>>0)&0xff;
- memcpy(&commandRaw.requestData[3], xmlBody, strlen(xmlBody));
- return pollingRequest(uart, commandRaw.requestData);
- }
- int preAuthResponse(int uart)
- {
- int result = pollingResponse(uart, commandRaw.responseData);
- //char *xmlTestBody = "<Event><MesgId>21</MesgId><MesgStr>PLEASE PRESENT CARD</MesgStr></Event>";
- //char *xmlTestBody = "<Event><MesgId>27</MesgId><MesgStr>AUTHORIZING. PLEASE WAIT...</MesgStr></Event>";
- //char *xmlTestBody = "<Resp><Cmd><CmdId>TxnStartResp</CmdId><StatusCode>001F</StatusCode><StatusText>TransactionDeferred</StatusText></Cmd><Data><Txn><TxnId>62</TxnId></Txn></Data></Resp>";
- char xmlTestBody[512] = {0};
- if(result == PASS)
- {
- memcpy(xmlTestBody, &commandRaw.responseData[3], ((commandRaw.responseData[1] << 8) | commandRaw.responseData[2]));
- xmlDocPtr doc = xmlParseDoc((const xmlChar *)xmlTestBody);
- xmlNode *root_element = xmlDocGetRootElement(doc);
- if(find_node(root_element, "Event") != NULL)
- {
- DEBUG_INFO("===== Get event =======================\n");
- ShmSysConfigAndInfo->SysInfo.bazel8.event.messageId = atoi((char*)xmlNodeGetContent(find_node(root_element, "MesgId")));
- sprintf(ShmSysConfigAndInfo->SysInfo.bazel8.event.messageString, "%s", xmlNodeGetContent(find_node(root_element, "MesgId")));
- ShmSysConfigAndInfo->SysInfo.bazel8.event.isGetOn = ON;
- DEBUG_INFO("Message id: %d\n", ShmSysConfigAndInfo->SysInfo.bazel8.event.messageId);
- DEBUG_INFO("%s: %s\n", root_element->children->next->name, xmlNodeGetContent(root_element->children->next));
- }
- else if((find_node(root_element, "Resp") != NULL) && (strstr((char*)xmlNodeGetContent(find_node(root_element, "CmdId")), "TxnStartResp") != NULL))
- {
- DEBUG_INFO("===== Get response =======================\n");
- sprintf(ShmSysConfigAndInfo->SysInfo.bazel8.txResp.statusCode, "%s", xmlNodeGetContent(find_node(root_element, "StatusCode")));
- sprintf(ShmSysConfigAndInfo->SysInfo.bazel8.txResp.statusText, "%s", xmlNodeGetContent(find_node(root_element, "StatusText")));
- sprintf(ShmSysConfigAndInfo->SysInfo.bazel8.txResp.txnId, "%s", xmlNodeGetContent(find_node(root_element, "TxnId")));
- ShmSysConfigAndInfo->SysInfo.bazel8.txResp.isGetOn = ON;
- DEBUG_INFO("Status code: %s\n", ShmSysConfigAndInfo->SysInfo.bazel8.txResp.statusCode);
- DEBUG_INFO("Status text: %s\n", ShmSysConfigAndInfo->SysInfo.bazel8.txResp.statusText);
- DEBUG_INFO("TxnId: %s\n", ShmSysConfigAndInfo->SysInfo.bazel8.txResp.txnId);
- }
- else
- {
- DEBUG_INFO("===== Get unknown node =======================\n");
- }
- xmlFreeDoc(doc);
- xmlCleanupParser();
- xmlMemoryDump();
- }
- return result;
- }
- //==========================================
- // Main loop
- //==========================================
- int main(void)
- {
- int UartFd;
- int preAuthRetry = 0;
- int cmdRepeatCount = 0;
- //===============================================
- // Initialization
- //===============================================
- #ifndef X86
- if(InitShareMemory() == FAIL)
- {
- DEBUG_ERROR("InitShareMemory NG\n");
- if(ShmStatusCodeData!=NULL)
- {
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
- }
- 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;
- }
- else
- {
- DEBUG_INFO("%s port open success.\n", TTY_PORT);
- }
- DEBUG_INFO("Payment module initialize completed.\n");
- //===============================================
- // Main loop
- //===============================================
- for(;;)
- {
- if(ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq)
- {
- // Pre auth request
- if(!ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isWaitRes)
- {
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isRes = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.event.isGetOn = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.txResp.isGetOn = false;
- if(preAuthRequest(UartFd))
- {
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isWaitRes = true;
- cmdRepeatCount = 0;
- refreshStartTimer(&tmr[TIMER_READ_RESPONSE]);
- }
- if(cmdRepeatCount > SPEC_REQUEST_RETRY)
- {
- DEBUG_WARN("preAuthRequest fail over count(%d).", cmdRepeatCount);
- cmdRepeatCount = 0;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isResultPass = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isRes = true;
- }
- else
- {
- cmdRepeatCount += 1;
- }
- }
- else
- {
- if((getInputBufferCount(UartFd) >= RAW_DATA_LENGTH))
- {
- if(preAuthResponse(UartFd))
- {
- if(ShmSysConfigAndInfo->SysInfo.bazel8.event.isGetOn)
- {
- /*
- * TODO:
- * 1. Announce CSU event content.
- */
- ShmSysConfigAndInfo->SysInfo.bazel8.event.isGetOn = false;
- }
- else if(ShmSysConfigAndInfo->SysInfo.bazel8.txResp.isGetOn)
- {
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isResultPass = ((strstr(ShmSysConfigAndInfo->SysInfo.bazel8.txResp.statusCode, "0000") != NULL)?true:false);
- if(ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isResultPass || (preAuthRetry++ >= 3))
- {
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isRes = true;
- preAuthRetry = 0;
- }
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isWaitRes = false;
- }
- }
- }
- if((getDiffSecNow(tmr[TIMER_READ_RESPONSE]) > TIMEOUT_REQUEST))
- {
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isWaitRes = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isResultPass = false;
- ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isRes = true;
- DEBUG_WARN("Wait pre auth response timeout(%d secs).", TIMEOUT_REQUEST);
- }
- }
- }
- sleep(3);
- }
- return FAIL;
- }
|