Module_Payment_Enegate.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. /*
  2. * Module_Payment_Enegate.c
  3. *
  4. * Created on: 2022/5/4
  5. * Author: folus
  6. */
  7. #include "Module_Payment_Enegate.h"
  8. ParsingRatedCur modelnameInfo = {0};
  9. uint8_t gunType[4] = {0};
  10. struct timespec tmr[4][TIMER_CNT];
  11. Message rx;
  12. Message tx;
  13. //==========================================
  14. // Common routine
  15. //==========================================
  16. int StoreLogMsg(const char *fmt, ...)
  17. {
  18. char Buf[65536+256];
  19. char buffer[65536];
  20. //char Buf[4096+256];
  21. //char buffer[4096];
  22. time_t CurrentTime;
  23. struct tm *tm;
  24. struct timeval tv;
  25. va_list args;
  26. va_start(args, fmt);
  27. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  28. va_end(args);
  29. memset(Buf,0,sizeof(Buf));
  30. CurrentTime = time(NULL);
  31. tm=localtime(&CurrentTime);
  32. gettimeofday(&tv, NULL); // get microseconds, 10^-6
  33. sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%03ld]%s\" >> /Storage/SystemLog/[%04d.%02d]PaymentLog",
  34. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec/1000,
  35. buffer,
  36. tm->tm_year+1900,tm->tm_mon+1);
  37. system((const char*)Buf);
  38. #ifdef ConsloePrintLog
  39. printf("[%04d.%02d.%02d %02d:%02d:%02d.%03ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec/1000, buffer);
  40. #endif
  41. return rc;
  42. }
  43. /**
  44. * Execute shell command
  45. * @param cmd: shell command string
  46. * @return shell command execution result
  47. */
  48. int runShellCmd(const char*cmd)
  49. {
  50. int result = FAIL;
  51. char buf[256];
  52. FILE *fp;
  53. fp = popen(cmd, "r");
  54. if(fp != NULL)
  55. {
  56. while(fgets(buf, sizeof(buf), fp) != NULL)
  57. {
  58. DEBUG_INFO("%s\n", buf);
  59. }
  60. result = PASS;
  61. }
  62. pclose(fp);
  63. return result;
  64. }
  65. /**
  66. *
  67. * @param timer
  68. */
  69. void refreshStartTimer(struct timespec *timer)
  70. {
  71. clock_gettime(CLOCK_MONOTONIC, timer);
  72. }
  73. /**
  74. *
  75. * @param timer
  76. * @return
  77. */
  78. int getDiffSecNow(struct timespec timer)
  79. {
  80. struct timespec timerNow;
  81. clock_gettime(CLOCK_MONOTONIC, &timerNow);
  82. return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
  83. }
  84. /**
  85. *
  86. * @param ST
  87. */
  88. long long DiffTimebWithNow(struct timeb ST)
  89. {
  90. //return milli-second
  91. struct timeb ET;
  92. long long StartTime,StopTime;
  93. ftime(&ET);
  94. StartTime=(long long)ST.time;
  95. StopTime=(long long)ET.time;
  96. return ((StopTime-StartTime)*1000) + (ET.millitm-ST.millitm);
  97. }
  98. /**
  99. *
  100. * @return
  101. */
  102. int getTimePassSinceToday()
  103. {
  104. int result = -1;
  105. time_t t;
  106. struct tm *tmStartToday;
  107. struct timeb tbStartToday;
  108. t=time(NULL);
  109. tmStartToday=localtime(&t);
  110. tmStartToday->tm_hour = 0;
  111. tmStartToday->tm_min = 0;
  112. tmStartToday->tm_sec = 0;
  113. tbStartToday.time = mktime(tmStartToday);
  114. tbStartToday.millitm = 0;
  115. result = DiffTimebWithNow(tbStartToday)/1000;
  116. return result;
  117. }
  118. /**
  119. *
  120. * @param startTime
  121. * @param stopTime
  122. * @return
  123. */
  124. int isPausedService(uint8_t *startTime, uint8_t *stopTime)
  125. {
  126. int result = FALSE;
  127. if((strlen((char*)startTime) > 0) && (strlen((char*)stopTime) > 0))
  128. {
  129. int start, stop;
  130. if(sscanf((char*)startTime, "%d", &start) && sscanf((char*)stopTime, "%d", &stop))
  131. {
  132. if(((getTimePassSinceToday() < ((start/100)*3600)+((start%100)*60))) || ((((stop/100)*3600)+((stop%100)*60)) <= getTimePassSinceToday()))
  133. {
  134. result = TRUE;
  135. }
  136. }
  137. }
  138. return result;
  139. }
  140. /**
  141. * Show communication raw data to debug info
  142. * @param data: raw data
  143. * @param len: data length
  144. * @param isRX: is receive data
  145. */
  146. void show_raw(uint8_t *data, uint16_t len, uint8_t isRX)
  147. {
  148. uint8_t output[512]={0};
  149. if(isRX)
  150. DEBUG_INFO("RX ---------------------------------------------\n");
  151. else
  152. DEBUG_INFO("TX ---------------------------------------------\n");
  153. DEBUG_INFO(" 0 1 2 3 4 5 6 7 8 9 A B C D E F \n");
  154. DEBUG_INFO("------------------------------------------------\n");
  155. memset(output, 0x00, ARRAY_SIZE(output));
  156. for(int idx=0;idx<len;idx++)
  157. {
  158. if(strlen((char*)output)<48)
  159. sprintf((char*)output, "%s%02X ", output, data[idx]);
  160. else
  161. {
  162. DEBUG_INFO("%s\n", output);
  163. memset(output, 0x00, ARRAY_SIZE(output));
  164. sprintf((char*)output, "%s%02X ", output, data[idx]);
  165. }
  166. }
  167. DEBUG_INFO("%s\n", output);
  168. }
  169. /**
  170. *
  171. * @param dec: number in dec
  172. * @return number in bcd
  173. */
  174. int decTobcd(int dec)
  175. {
  176. return (dec/10 * 16)+ (dec%10);
  177. }
  178. /**
  179. *
  180. * @param data: message array
  181. * @param dataLen: command & data field length in array
  182. * @return check sum result
  183. */
  184. uint8_t calChksum(Message *data)
  185. {
  186. uint8_t result = 0;
  187. for(uint16_t idx=1;idx<(data->size-3);idx++)
  188. {
  189. result += data->buffer[idx];
  190. }
  191. //DEBUG_INFO("calChksum: %02X\n", (result&0xff));
  192. return result;
  193. }
  194. /**
  195. *
  196. * @param result
  197. */
  198. void getDateTimeString(char* result)
  199. {
  200. time_t CurrentTime;
  201. struct tm *tm;
  202. CurrentTime = time(NULL);
  203. tm=localtime(&CurrentTime);
  204. sprintf(result, "%04d%02d%02d%02d%02d%02d", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
  205. }
  206. //==========================================
  207. // Init share memory
  208. //==========================================
  209. /**
  210. * Share memory initialization
  211. * @return function result
  212. */
  213. int InitShareMemory()
  214. {
  215. int result = PASS;
  216. int MeterSMId;
  217. #ifndef X86
  218. //init ShmSysConfigAndInfo
  219. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  220. {
  221. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
  222. result = FAIL;
  223. }
  224. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  225. {
  226. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
  227. result = FAIL;
  228. }
  229. else
  230. {}
  231. //init ShmStatusCodeData
  232. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  233. {
  234. DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
  235. result = FAIL;
  236. }
  237. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  238. {
  239. DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
  240. result = FAIL;
  241. }
  242. else
  243. {}
  244. //init ShmOCPP16Data
  245. if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
  246. {
  247. DEBUG_ERROR("shmget ShmOCPP16Data NG\n");
  248. result = FAIL;
  249. }
  250. else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  251. {
  252. DEBUG_ERROR("shmat ShmOCPP16Data NG\n");
  253. result = FAIL;
  254. }
  255. else
  256. {}
  257. // Parsing model name to get related info about charger
  258. if(RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo) != -1)
  259. {
  260. DEBUG_INFO("Model name rated power: %d\n", modelnameInfo.ratedPower);
  261. if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
  262. ((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
  263. (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
  264. (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O'))
  265. ) // 'D' means DC
  266. {
  267. // DO series
  268. for(int gun_index=0; gun_index<GENERAL_GUN_QUANTITY ; gun_index++)
  269. {
  270. gunType[gun_index] = GUN_TYPE_DO;
  271. switch(modelnameInfo.ParsingInfo[gun_index].GunType)
  272. {
  273. case Gun_Type_Chademo:
  274. DEBUG_INFO("Gun-%02d type: Cabinet CHAdeMO\n", gun_index);
  275. break;
  276. case Gun_Type_CCS_2:
  277. DEBUG_INFO("Gun-%02d type: Cabinet CCS\n", gun_index);
  278. break;
  279. case Gun_Type_GB:
  280. DEBUG_INFO("Gun-%02d type: Cabinet GBT\n", gun_index);
  281. break;
  282. case Gun_Type_AC:
  283. DEBUG_INFO("Gun-%02d type: Cabinet AC\n", gun_index);
  284. break;
  285. default:
  286. DEBUG_WARN("Gun-%02d type: Cabinet unknown\n", gun_index);
  287. break;
  288. }
  289. }
  290. }
  291. else
  292. {
  293. for(int gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++)
  294. {
  295. switch(modelnameInfo.ParsingInfo[gun_index].GunType)
  296. {
  297. case Gun_Type_Chademo:
  298. gunType[gun_index] = GUN_TYPE_CHAdeMO;
  299. DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
  300. break;
  301. case Gun_Type_CCS_2:
  302. gunType[gun_index] = GUN_TYPE_CCS;
  303. DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
  304. break;
  305. case Gun_Type_GB:
  306. gunType[gun_index] = GUN_TYPE_GBT;
  307. DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
  308. break;
  309. case Gun_Type_AC:
  310. gunType[gun_index] = GUN_TYPE_AC;
  311. DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
  312. break;
  313. default:
  314. DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
  315. break;
  316. }
  317. }
  318. }
  319. }
  320. else
  321. {
  322. DEBUG_ERROR("Model name parsing fail.\n");
  323. result = FAIL;
  324. }
  325. #endif
  326. return result;
  327. }
  328. //==========================================
  329. // Init com port
  330. //==========================================
  331. /**
  332. * TTY port initialization
  333. * @return port initial result
  334. */
  335. int InitComPort()
  336. {
  337. int fd;
  338. struct termios tios;
  339. fd = open(TTY_PORT, O_RDWR);
  340. if(fd<=0)
  341. {
  342. return FAIL;
  343. }
  344. ioctl (fd, TCGETS, &tios);
  345. tios.c_cflag = B9600| CS8 | CLOCAL | CREAD;
  346. tios.c_lflag = 0;
  347. tios.c_iflag = 0;
  348. tios.c_oflag = 0;
  349. tios.c_cc[VMIN]=0; // data length threshold, 0 bytes
  350. tios.c_cc[VTIME]=(unsigned char)5; // timeout threshold, 0.5 seconds
  351. tios.c_lflag=0;
  352. ioctl (fd, TCSETS, &tios);
  353. tcflush(fd, TCIFLUSH);
  354. read(fd, NULL, 512);
  355. return fd;
  356. }
  357. /**
  358. *
  359. * @param uart
  360. * @return
  361. */
  362. int getInputBufferCount(int uart)
  363. {
  364. int bytes_avail = 0;
  365. if(ioctl(uart, FIONREAD, &bytes_avail) < 0)
  366. {
  367. DEBUG_INFO("FIONREAD ioctl failed\n");
  368. }
  369. else
  370. {
  371. //DEBUG_INFO("bytes_avail: %d\n", bytes_avail);
  372. }
  373. return bytes_avail;
  374. }
  375. /**
  376. *
  377. * @param uart
  378. * @param rx
  379. * @return
  380. */
  381. int pollingRequest(int uart, Message* rx)
  382. {
  383. int result=FAIL;
  384. rx->size = read(uart, rx->buffer, ARRAY_SIZE(rx->buffer));
  385. #ifdef DEBUG
  386. show_raw(rx->buffer, rx->size, YES);
  387. #endif
  388. if(calChksum(rx))
  389. {
  390. result = PASS;
  391. }
  392. return result;
  393. }
  394. /**
  395. *
  396. * @param uart
  397. * @param tx
  398. * @return
  399. */
  400. int pollingResponse(int uart, Message* tx)
  401. {
  402. int result=FAIL;
  403. tcflush(uart,TCIOFLUSH);
  404. tx->buffer[tx->size-3] = calChksum(tx);
  405. #ifdef DEBUG
  406. show_raw(tx->buffer, tx->size, NO);
  407. #endif
  408. if(write(uart, tx->buffer, tx->size) > 0)
  409. {
  410. result = PASS;
  411. }
  412. else
  413. {
  414. DEBUG_ERROR("pollingResponse fail.\n");
  415. }
  416. return result;
  417. }
  418. /**
  419. *
  420. * @param gun_index
  421. */
  422. void getResponseState(uint8_t gun_index, uint8_t *charger_state, uint8_t *energy)
  423. {
  424. struct ChargingInfoData *targetChargingInfoData = NULL;
  425. // Get target gun data
  426. if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
  427. {
  428. for (int index = 0; index < CHAdeMO_QUANTITY; index++)
  429. {
  430. if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == gun_index))
  431. {
  432. targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
  433. break;
  434. }
  435. }
  436. }
  437. else if(gunType[gun_index] == GUN_TYPE_CCS)
  438. {
  439. for (int index = 0; index < CCS_QUANTITY; index++)
  440. {
  441. if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == gun_index))
  442. {
  443. targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
  444. break;
  445. }
  446. }
  447. }
  448. else if(gunType[gun_index] == GUN_TYPE_GBT)
  449. {
  450. for (int index = 0; index < GB_QUANTITY; index++)
  451. {
  452. if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == gun_index))
  453. {
  454. targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
  455. break;
  456. }
  457. }
  458. }
  459. else if(gunType[gun_index] == GUN_TYPE_DO)
  460. {
  461. for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
  462. {
  463. if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == gun_index))
  464. {
  465. targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData;
  466. break;
  467. }
  468. }
  469. }
  470. else if(gunType[gun_index] == GUN_TYPE_AC)
  471. {
  472. for (int index = 0; index < AC_QUANTITY; index++)
  473. {
  474. if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == gun_index))
  475. {
  476. targetChargingInfoData = &ShmSysConfigAndInfo->SysInfo.AcChargingData[index];
  477. break;
  478. }
  479. }
  480. }
  481. // 1. Check gun status and cover to Enegate state code
  482. if(targetChargingInfoData != NULL)
  483. {
  484. if(targetChargingInfoData->SystemStatus == SYS_MODE_BOOTING)//S_IDLE
  485. {
  486. sprintf((char*)charger_state, "%05d", 0);
  487. memcpy(&tx.buffer[3], &charger_state[0], 5);
  488. }
  489. else if((targetChargingInfoData->SystemStatus == SYS_MODE_IDLE) || (targetChargingInfoData->SystemStatus == SYS_MODE_AUTHORIZING))//S_IDLE
  490. {
  491. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isConnectTimeout)
  492. {
  493. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  494. {
  495. sprintf((char*)charger_state, "%05d", 1000);
  496. memcpy(&tx.buffer[3], &charger_state[0], 5);
  497. }
  498. else
  499. {
  500. sprintf((char*)charger_state, "%05d", 41000);
  501. memcpy(&tx.buffer[3], &charger_state[0], 5);
  502. }
  503. }
  504. else
  505. {
  506. sprintf((char*)charger_state, "%05d", 2010);
  507. memcpy(&tx.buffer[3], &charger_state[0], 5);
  508. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isConnectTimeout = OFF;
  509. }
  510. }
  511. else if ( ((targetChargingInfoData->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK)&&(targetChargingInfoData->SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
  512. ((targetChargingInfoData->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && (targetChargingInfoData->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
  513. ) //S_PRECHARGE
  514. {
  515. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isConnectTimeout)
  516. {
  517. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  518. {
  519. sprintf((char*)charger_state, "%05d", 2000);
  520. memcpy(&tx.buffer[3], &charger_state[0], 5);
  521. }
  522. else
  523. {
  524. sprintf((char*)charger_state, "%05d", 42000);
  525. memcpy(&tx.buffer[3], &charger_state[0], 5);
  526. }
  527. }
  528. else
  529. {
  530. sprintf((char*)charger_state, "%05d", 2010);
  531. memcpy(&tx.buffer[3], &charger_state[0], 5);
  532. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isConnectTimeout = OFF;
  533. }
  534. }
  535. else if (targetChargingInfoData->SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
  536. {
  537. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  538. {
  539. sprintf((char*)charger_state, "%05d", 3000);
  540. memcpy(&tx.buffer[3], &charger_state[0], 5);
  541. sprintf((char*)energy, "%08d", (int)(targetChargingInfoData->PresentChargedEnergy*100));
  542. memcpy(&tx.buffer[22], &energy[0], 8);
  543. memcpy(&tx.buffer[30], &energy[0], 8);
  544. }
  545. else
  546. {
  547. sprintf((char*)charger_state, "%05d", 43000);
  548. memcpy(&tx.buffer[3], &charger_state[0], 5);
  549. sprintf((char*)energy, "%08d", (int)(targetChargingInfoData->PresentChargedEnergy*100));
  550. memcpy(&tx.buffer[22], &energy[0], 8);
  551. memcpy(&tx.buffer[30], &energy[0], 8);
  552. }
  553. }
  554. else if ((targetChargingInfoData->SystemStatus == SYS_MODE_TERMINATING) || (targetChargingInfoData->SystemStatus == SYS_MODE_COMPLETE))
  555. {
  556. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  557. {
  558. /*
  559. * TODO:
  560. * 1. Stop reason transfer
  561. */
  562. sprintf((char*)charger_state, "%05d", 5020);
  563. memcpy(&tx.buffer[3], &charger_state[0], 5);
  564. sprintf((char*)energy, "%08d", (int)(targetChargingInfoData->PresentChargedEnergy*100));
  565. memcpy(&tx.buffer[22], &energy[0], 8);
  566. memcpy(&tx.buffer[30], &energy[0], 8);
  567. }
  568. else
  569. {
  570. /*
  571. * TODO:
  572. * 1. Stop reason transfer
  573. */
  574. sprintf((char*)charger_state, "%05d", 45020);
  575. memcpy(&tx.buffer[3], &charger_state[0], 5);
  576. sprintf((char*)energy, "%08d", (int)(targetChargingInfoData->PresentChargedEnergy*100));
  577. memcpy(&tx.buffer[22], &energy[0], 8);
  578. memcpy(&tx.buffer[30], &energy[0], 8);
  579. }
  580. }
  581. else if ((targetChargingInfoData->SystemStatus == SYS_MODE_MAINTAIN) || (targetChargingInfoData->SystemStatus == SYS_MODE_DEBUG) || (targetChargingInfoData->SystemStatus == SYS_MODE_UPDATE)) // ---> Unavailable
  582. {
  583. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  584. {
  585. sprintf((char*)charger_state, "%05d", 100);
  586. memcpy(&tx.buffer[3], &charger_state[0], 5);
  587. }
  588. else
  589. {
  590. sprintf((char*)charger_state, "%05d", 40100);
  591. memcpy(&tx.buffer[3], &charger_state[0], 5);
  592. }
  593. }
  594. else if ((targetChargingInfoData->SystemStatus == SYS_MODE_FAULT) || (targetChargingInfoData->SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT ---> Faulted
  595. {
  596. if(!ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable)
  597. {
  598. if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip)
  599. {
  600. sprintf((char*)charger_state, "%05d", 5108);
  601. }
  602. else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip ||
  603. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip ||
  604. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip ||
  605. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail)
  606. {
  607. sprintf((char*)charger_state, "%05d", 5109);
  608. }
  609. else if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoConnectorLockFail ||
  610. ShmStatusCodeData->FaultCode.FaultEvents.bits.GbConnectorLockFail ||
  611. ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail)
  612. {
  613. sprintf((char*)charger_state, "%05d", 5104);
  614. }
  615. else if(ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoIsolationResultFail ||
  616. ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ISOLATION_RESULT_FAIL)
  617. {
  618. sprintf((char*)charger_state, "%05d", 5102);
  619. }
  620. else
  621. {
  622. sprintf((char*)charger_state, "%05d", 5107);
  623. }
  624. memcpy(&tx.buffer[3], &charger_state[0], 5);
  625. }
  626. else
  627. {
  628. if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip)
  629. {
  630. sprintf((char*)charger_state, "%05d", 45108);
  631. }
  632. else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip ||
  633. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip ||
  634. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip ||
  635. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail)
  636. {
  637. sprintf((char*)charger_state, "%05d", 45109);
  638. }
  639. else if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoConnectorLockFail ||
  640. ShmStatusCodeData->FaultCode.FaultEvents.bits.GbConnectorLockFail ||
  641. ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail)
  642. {
  643. sprintf((char*)charger_state, "%05d", 45104);
  644. }
  645. else if(ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoIsolationResultFail ||
  646. ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ISOLATION_RESULT_FAIL)
  647. {
  648. sprintf((char*)charger_state, "%05d", 45102);
  649. }
  650. else
  651. {
  652. sprintf((char*)charger_state, "%05d", 45107);
  653. }
  654. memcpy(&tx.buffer[3], &charger_state[0], 5);
  655. }
  656. }
  657. }
  658. }
  659. //==========================================
  660. // Main loop
  661. //==========================================
  662. int main(void)
  663. {
  664. int UartFd;
  665. //===============================================
  666. // Initialization
  667. //===============================================
  668. if(InitShareMemory() == FAIL)
  669. {
  670. DEBUG_ERROR("InitShareMemory NG\n");
  671. if(ShmStatusCodeData!=NULL)
  672. {
  673. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
  674. }
  675. sleep(5);
  676. return FAIL;
  677. }
  678. UartFd=InitComPort();
  679. if(UartFd<0)
  680. {
  681. DEBUG_ERROR("InitComPort NG\n");
  682. if(ShmStatusCodeData!=NULL)
  683. {
  684. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
  685. }
  686. sleep(5);
  687. return FAIL;
  688. }
  689. else
  690. {
  691. DEBUG_INFO("%s port open success.\n", TTY_PORT);
  692. }
  693. refreshStartTimer(&tmr[0][TIMER_COMM_TIMEOUT]);
  694. DEBUG_INFO("Payment module initialize completed...%s\n", FIRMWARE_VERSION);
  695. for(;;)
  696. {
  697. if(ShmSysConfigAndInfo->SysInfo.enegate.isEnable)
  698. {
  699. // Communication timeout
  700. if(getDiffSecNow(tmr[0][TIMER_COMM_TIMEOUT]) >= 10)
  701. {
  702. if(!ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PaymentCommTimeout)
  703. {
  704. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PaymentCommTimeout = ON;
  705. DEBUG_WARN("Payment system communication timeout.\n");
  706. }
  707. }
  708. else
  709. {
  710. if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PaymentCommTimeout)
  711. {
  712. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PaymentCommTimeout = OFF;
  713. DEBUG_WARN("Payment system communication recover.\n");
  714. }
  715. }
  716. if((getInputBufferCount(UartFd) >= 24))
  717. {
  718. if(pollingRequest(UartFd, &rx))
  719. {
  720. refreshStartTimer(&tmr[0][TIMER_COMM_TIMEOUT]);
  721. uint8_t charger_state[6] = {0};
  722. uint8_t energy[9] = {0};
  723. static uint8_t charger_state_previous[6] = {0};
  724. static uint8_t energy_previous[9] = {0};
  725. uint16_t cmd = ((rx.buffer[3]-0x30)*1000) + ((rx.buffer[4]-0x30)*100) + ((rx.buffer[5]-0x30)*10) + ((rx.buffer[6]-0x30)*1);
  726. uint8_t id = rx.buffer[1];
  727. uint8_t gun_index = (id-0x30-ID_OFFSET);
  728. tx.size = 41;
  729. tx.buffer[0] = STX;
  730. tx.buffer[1] = id;
  731. tx.buffer[2] = ACK;
  732. sprintf((char*)&tx.buffer[3], "%05d", 0);
  733. getDateTimeString((char*)&tx.buffer[8]);
  734. sprintf((char*)energy, "00000000");
  735. sprintf((char*)&tx.buffer[22], "00000000");
  736. sprintf((char*)&tx.buffer[30], "00000000");
  737. tx.buffer[39] = CR;
  738. tx.buffer[40] = LF;
  739. // 1. Check ID in command message
  740. if(((0<=gun_index) && (gun_index<(ShmSysConfigAndInfo->SysConfig.TotalConnectorCount+1))))
  741. {
  742. switch(cmd)
  743. {
  744. case HOST_CMD_GET_STATUS:
  745. getResponseState(gun_index, charger_state, energy);
  746. if((strstr((char*)charger_state_previous, (char*)charger_state) == NULL) || (strstr((char*)energy_previous, (char*)energy) == NULL))
  747. {
  748. DEBUG_INFO("id(%c)=> HOST_CMD_GET_STATUS(1000): %s, Energy: %s\n", id, charger_state, energy);
  749. memcpy(charger_state_previous, charger_state, ARRAY_SIZE(charger_state));
  750. memcpy(energy_previous, energy, ARRAY_SIZE(energy));
  751. }
  752. break;
  753. case HOST_CMD_AUTH_CHECKING:
  754. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizing = ON;
  755. getResponseState(gun_index, charger_state, energy);
  756. DEBUG_INFO("id(%c)=> HOST_CMD_AUTH_CHECKING(9000): %s, Energy: %s\n", id, charger_state, energy);
  757. break;
  758. case HOST_CMD_AUTH_CANCEL:
  759. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizing = OFF;
  760. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorized = ON;
  761. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizedPass = OFF;
  762. getResponseState(gun_index, charger_state, energy);
  763. DEBUG_INFO("id(%c)=> HOST_CMD_AUTH_CANCEL(9001): %s, Energy: %s\n", id, charger_state, energy);
  764. break;
  765. case HOST_CMD_AUTH_PASS:
  766. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizing = OFF;
  767. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorized = ON;
  768. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizedPass = ON;
  769. getResponseState(gun_index, charger_state, energy);
  770. DEBUG_INFO("id(%c)=> HOST_CMD_AUTH_PASS(3000): %s, Energy: %s\n", id, charger_state, energy);
  771. break;
  772. case HOST_CMD_AUTH_FAIL:
  773. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizing = OFF;
  774. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorized = ON;
  775. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAuthorizedPass = OFF;
  776. getResponseState(gun_index, charger_state, energy);
  777. DEBUG_INFO("id(%c)=> HOST_CMD_AUTH_FAIL(3001): %s, Energy: %s\n", id, charger_state, energy);
  778. break;
  779. case HOST_CMD_AUTO_START_ENABLE:
  780. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable = ON;
  781. ShmSysConfigAndInfo->SysConfig.AuthorisationMode = 1;
  782. getResponseState(gun_index, charger_state, energy);
  783. DEBUG_INFO("id(%c)=> HOST_CMD_AUTO_START_ENABLE(0200): %s, Energy: %s\n", id, charger_state, energy);
  784. break;
  785. case HOST_CMD_AUTOSTART_DIABLE:
  786. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isAutoStartEnable = OFF;
  787. ShmSysConfigAndInfo->SysConfig.AuthorisationMode = 0;
  788. getResponseState(gun_index, charger_state, energy);
  789. DEBUG_INFO("id(%c)=> HOST_CMD_AUTOSTART_DIABLE(0222): %s, Energy: %s\n", id, charger_state, energy);
  790. break;
  791. case HOST_CMD_SESSION_STOP:
  792. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isSessionStopReq = ON;
  793. getResponseState(gun_index, charger_state, energy);
  794. DEBUG_INFO("id(%c)=> HOST_CMD_SESSION_STOP(4000): %s, Energy: %s\n", id, charger_state, energy);
  795. break;
  796. case HOST_CMD_PAUSE_ENABLE:
  797. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isStopService = ON;
  798. getResponseState(gun_index, charger_state, energy);
  799. DEBUG_INFO("id(%c)=> HOST_CMD_PAUSE_ENABLE(100): %s, Energy: %s\n", id, charger_state, energy);
  800. break;
  801. case HOST_CMD_PAUSE_DISABLE:
  802. ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isStopService = OFF;
  803. getResponseState(gun_index, charger_state, energy);
  804. DEBUG_INFO("id(%c)=> HOST_CMD_PAUSE_DISABLE(111): %s, Energy: %s\n", id, charger_state, energy);
  805. break;
  806. default:
  807. getResponseState(gun_index, charger_state, energy);
  808. DEBUG_WARN("id(%c)=> Unknown host command(%d): %s, Energy: %s.\n", id, cmd, charger_state, energy);
  809. tx.buffer[2] = NAK;
  810. break;
  811. }
  812. // Synchronize date time every 10 minutes
  813. if(getDiffSecNow(tmr[gun_index][TIMER_UPDATE_RTC]) >= 600)
  814. {
  815. struct tm tmOrg;
  816. struct tm *tmTarget;
  817. struct timeb tbTarget;
  818. char buf[64]={0};
  819. tmOrg.tm_year = (((rx.buffer[7]-0x30)*1000)+((rx.buffer[8]-0x30)*100)+((rx.buffer[9]-0x30)*10)+((rx.buffer[10]-0x30)*1)) - 1900;
  820. tmOrg.tm_mon = (((rx.buffer[11]-0x30)*10)+((rx.buffer[12]-0x30)*1)) - 1;
  821. tmOrg.tm_mday = (((rx.buffer[13]-0x30)*10)+((rx.buffer[14]-0x30)*1));
  822. tmOrg.tm_hour = (((rx.buffer[15]-0x30)*10)+((rx.buffer[16]-0x30)*1));
  823. tmOrg.tm_min = (((rx.buffer[17]-0x30)*10)+((rx.buffer[18]-0x30)*1));
  824. tmOrg.tm_sec = (((rx.buffer[19]-0x30)*10)+((rx.buffer[20]-0x30)*1));
  825. tmOrg.tm_gmtoff = 0;
  826. tbTarget.time = mktime(&tmOrg);
  827. tbTarget.timezone = 0;
  828. tbTarget.time -= (9*3600); // Japan always in UTC+9
  829. tmTarget = gmtime(&tbTarget.time);
  830. sprintf(buf, "date -s '%04d-%02d-%02d %02d:%02d:%02d'", (tmTarget->tm_year+1900), (tmTarget->tm_mon+1), tmTarget->tm_mday, tmTarget->tm_hour, tmTarget->tm_min, tmTarget->tm_sec);
  831. system(buf);
  832. system("/sbin/hwclock -w --systohc");
  833. refreshStartTimer(&tmr[gun_index][TIMER_UPDATE_RTC]);
  834. }
  835. }
  836. else if(id == 'a')
  837. {
  838. if(cmd == HOST_CMD_GET_SELECTED_ID)
  839. {
  840. static int previousId = -1;
  841. tx.buffer[1] = (0x30 + ShmSysConfigAndInfo->SysInfo.CurGunSelected + ID_OFFSET);
  842. sprintf((char*)&tx.buffer[3], "%05d", 9302);
  843. if(previousId != tx.buffer[1])
  844. {
  845. DEBUG_INFO("id(%c)=> HOST_CMD_GET_SELECTED_ID(9301): %c\n", id, tx.buffer[1]);
  846. previousId = tx.buffer[1];
  847. }
  848. }
  849. else if(cmd == HOST_CMD_SET_SERVICE_TIME)
  850. {
  851. memset(ShmSysConfigAndInfo->SysInfo.enegate.serviceStartTimestamp, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.enegate.serviceStartTimestamp));
  852. memset(ShmSysConfigAndInfo->SysInfo.enegate.serviceStopTimestamp, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.enegate.serviceStopTimestamp));
  853. sprintf((char*)&tx.buffer[3], "%05d", 9200);
  854. memcpy(ShmSysConfigAndInfo->SysInfo.enegate.serviceStartTimestamp, &rx.buffer[7], 4);
  855. memcpy(ShmSysConfigAndInfo->SysInfo.enegate.serviceStopTimestamp, &rx.buffer[11], 4);
  856. DEBUG_INFO("id(%c)=> HOST_CMD_SET_SERVICE_TIME(9200): %s - %s with UTC+9\n", id, ShmSysConfigAndInfo->SysInfo.enegate.serviceStartTimestamp, ShmSysConfigAndInfo->SysInfo.enegate.serviceStopTimestamp);
  857. }
  858. else
  859. {
  860. DEBUG_WARN("Wrong id(%c) with get selected id command(%d).\n", id, cmd);
  861. tx.buffer[2] = NAK;
  862. }
  863. }
  864. else
  865. {
  866. DEBUG_WARN("Wrong id(%c) with command(%d).\n", id, cmd);
  867. tx.buffer[2] = NAK;
  868. }
  869. /*
  870. * TODO:
  871. * 1. Service time check locally.
  872. * 2. Usually server will send enable / disable command.
  873. */
  874. //ShmSysConfigAndInfo->SysInfo.enegate.Operation.bits[gun_index].isStopService = isPausedService(ShmSysConfigAndInfo->SysInfo.enegate.serviceStartTimestamp, ShmSysConfigAndInfo->SysInfo.enegate.serviceStopTimestamp);
  875. }
  876. else
  877. {
  878. // Command with wron check sum.
  879. tx.size = 41;
  880. tx.buffer[0] = STX;
  881. tx.buffer[1] = rx.buffer[1];
  882. tx.buffer[2] = NAK;
  883. getDateTimeString((char*)&tx.buffer[8]);
  884. sprintf((char*)&tx.buffer[22], "00000000");
  885. sprintf((char*)&tx.buffer[30], "00000000");
  886. tx.buffer[39] = CR;
  887. tx.buffer[40] = LF;
  888. }
  889. pollingResponse(UartFd, &tx);
  890. }
  891. }
  892. usleep(100000);
  893. }
  894. }