Module_OcppBackend20.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  1. #include "Module_OcppBackend20.h"
  2. typedef enum boolean { FALSE, TRUE } BOOL;
  3. struct lws *wsi_client;
  4. struct lws_context *context;
  5. static int req_SendQueue = 0;
  6. pthread_t tid_connectServer;
  7. pthread_t tid_ProcQueue;
  8. pthread_t tid_Watchdog;
  9. struct StartTime
  10. {
  11. struct timespec connect;
  12. struct timespec bootNotification;
  13. struct timespec reConnect;
  14. struct timespec disconnectServer;
  15. struct timespec startTimeQueue;
  16. struct timespec pingOn;
  17. }startTime;
  18. struct QueueOpInfo queueOpInfo;
  19. //==========================================
  20. // Function prototype
  21. //==========================================
  22. void ReceivedMessage(void *in, size_t len);
  23. int SendBufLen=0;//(1024*4);//(1024*3);
  24. unsigned char SendBuffer[WEBSOCKET_BUFFER_SIZE]={0};
  25. static int ConnectionEstablished=0;
  26. int defaultWaitingTime = 10; //10 second
  27. char OcppPath[384]={0};
  28. char OcppProtocol[10]={0},OcppHost[128]={0}, OcppTempPath[256]={0};
  29. int OcppPort=0;
  30. unsigned char StartTransactionIdTagTemp[20]={0};
  31. uint8_t isWebsocketSendable = 1;
  32. uint8_t isQueueSendable = 1;
  33. uint8_t counterQueueSent = 0;
  34. uint8_t counterConnect = 0;
  35. uint8_t counterPingSend = 0;
  36. //=================================
  37. // Common routine
  38. //=================================
  39. int GetTransactionQueueNum(void)
  40. {
  41. return queueOpInfo.TransactionQueueNum;
  42. }
  43. //==========================================
  44. // Web socket tranceive routine
  45. //==========================================
  46. int SendData(struct lws *wsi)
  47. {
  48. int n;
  49. int len;
  50. unsigned char out[LWS_SEND_BUFFER_PRE_PADDING + (1024*20) + LWS_SEND_BUFFER_POST_PADDING] = {0};
  51. len = strlen((char *)SendBuffer);
  52. if(len == 0)return 0;
  53. if((strstr((char*)SendBuffer, "\"MeterValues\"") != NULL)
  54. || (strstr((char*)SendBuffer, "\"TransactionEven\"") != NULL))
  55. {
  56. isQueueSendable = OFF;
  57. }
  58. memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, SendBuffer, len );
  59. DEBUG_OCPPMESSAGE_INFO("===========> %s\n", out + LWS_SEND_BUFFER_PRE_PADDING);
  60. n = lws_write(wsi, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
  61. memset(SendBuffer, 0, len);
  62. SendBufLen = 0;
  63. return n;
  64. }
  65. int SendPing(struct lws *wsi)
  66. {
  67. uint8_t ping[LWS_PRE + 125];
  68. DEBUG_OCPPMESSAGE_INFO("===========> Set PING packet.\n");
  69. return lws_write(wsi, ping + LWS_PRE, 0, LWS_WRITE_PING);
  70. }
  71. static int OCPP20Callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
  72. {
  73. char buf[256]={0}, hash[20]={0}, key_b64[40]={0}, tempin[WEBSOCKET_BUFFER_SIZE]={0}, sstr[WEBSOCKET_BUFFER_SIZE]={0};
  74. uint8_t auth_b64[256]={0}, boxId[128]={0}, password[64]={0};
  75. int c = 0;
  76. char *loc;
  77. switch (reason)
  78. {
  79. case LWS_CALLBACK_PROTOCOL_INIT:
  80. DEBUG_INFO("LWS_CALLBACK_PROTOCOL_INIT\n");
  81. break;
  82. case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
  83. DEBUG_INFO("LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH\n");
  84. DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request START -----\n");
  85. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_URI);
  86. DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
  87. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
  88. DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
  89. DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
  90. DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
  91. lws_b64_encode_string(hash, 16, key_b64, ARRAY_SIZE(key_b64));// Sec-WebSocket-Key
  92. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b64);
  93. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
  94. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
  95. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
  96. DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request END -----\n");
  97. DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response START -----\n");
  98. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_HTTP);
  99. DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf);
  100. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_UPGRADE);
  101. DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf);
  102. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_CONNECTION);
  103. DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf);
  104. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_ACCEPT);
  105. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf);
  106. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_PROTOCOL);
  107. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
  108. DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response END -----\n");
  109. break;
  110. case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
  111. DEBUG_INFO("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
  112. break;
  113. case LWS_CALLBACK_WSI_DESTROY:
  114. DEBUG_INFO("LWS_CALLBACK_WSI_DESTROY\n");
  115. pthread_detach(tid_connectServer);
  116. SetServerSign(FALSE);
  117. ConnectionEstablished = 0;
  118. context = NULL;
  119. break;
  120. case LWS_CALLBACK_LOCK_POLL:
  121. break;
  122. case LWS_CALLBACK_ADD_POLL_FD:
  123. DEBUG_INFO("LWS_CALLBACK_ADD_POLL_FD\n");
  124. break;
  125. case LWS_CALLBACK_DEL_POLL_FD:
  126. DEBUG_INFO("LWS_CALLBACK_DEL_POLL_FD\n");
  127. break;
  128. case LWS_CALLBACK_UNLOCK_POLL:
  129. break;
  130. case LWS_CALLBACK_CHANGE_MODE_POLL_FD:
  131. break;
  132. case LWS_CALLBACK_WSI_CREATE:
  133. DEBUG_INFO("LWS_CALLBACK_WSI_CREATE\n");
  134. break;
  135. case LWS_CALLBACK_GET_THREAD_ID:
  136. break;
  137. case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
  138. DEBUG_INFO("LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n");
  139. unsigned char** pos = (unsigned char**)in;
  140. unsigned char* end = (*pos) + len;
  141. switch(GetOcppSecurityProfile())
  142. {
  143. case 1:
  144. case 2:
  145. case 3:
  146. GetOcppChargerBoxId(boxId);
  147. GetOcppSecurityPassword(password);
  148. sprintf(buf, "%s:%s", boxId, password);
  149. lws_b64_encode_string(buf, strlen(buf), (char*)auth_b64, ARRAY_SIZE(auth_b64));
  150. sprintf(buf, "Basic %s", auth_b64);
  151. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_AUTHORIZATION, (uint8_t *)buf, strlen(buf), pos, end))
  152. {
  153. DEBUG_ERROR("lws_add_http_header_by_token : WSI_TOKEN_HTTP_AUTHORIZATION\n");
  154. return -1;
  155. }
  156. DEBUG_OCPPMESSAGE_INFO("SecurityProfile: %d\n", GetOcppSecurityProfile());
  157. DEBUG_OCPPMESSAGE_INFO("Authorization: %s\n", buf);
  158. break;
  159. case 0:
  160. default:
  161. break;
  162. }
  163. break;
  164. case LWS_CALLBACK_CLIENT_ESTABLISHED: //3
  165. DEBUG_INFO("LWS_CALLBACK_CLIENT_ESTABLISHED\n");
  166. //connected
  167. ConnectionEstablished=1;
  168. SetOcppConnStatus(TRUE);
  169. refreshStartTimer(&startTime.pingOn);
  170. counterPingSend = 0;
  171. queueOpInfo.PreTransactionMessageResend = 0;
  172. break;
  173. case LWS_CALLBACK_CLIENT_CONNECTION_ERROR://1
  174. DEBUG_ERROR("LWS_CALLBACK_CLIENT_CONNECTION_ERROR %s\n", (char *)in );
  175. //disconnected
  176. ConnectionEstablished=0;
  177. DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client START =====\n");
  178. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_URI);
  179. DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
  180. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
  181. DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
  182. DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
  183. DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
  184. lws_b64_encode_string(hash, 16, key_b64, ARRAY_SIZE(key_b64));// Sec-WebSocket-Key
  185. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b64);
  186. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
  187. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
  188. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
  189. DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client END =====\n");
  190. DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response START =====\n");
  191. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_HTTP);
  192. DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf);
  193. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_UPGRADE);
  194. DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf);
  195. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_CONNECTION);
  196. DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf);
  197. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_ACCEPT);
  198. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf);
  199. lws_hdr_copy(wsi, buf, ARRAY_SIZE(buf) - 1, WSI_TOKEN_PROTOCOL);
  200. DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
  201. DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response END =====\n");
  202. break;
  203. case LWS_CALLBACK_CLOSED://4
  204. DEBUG_INFO("LWS_CALLBACK_CLOSED\n");
  205. //disconnected
  206. ConnectionEstablished=0;
  207. break;
  208. case LWS_CALLBACK_CLIENT_WRITEABLE://10
  209. if(isWebsocketSendable && (0 < GetWebSocketPingInterval()) && (GetWebSocketPingInterval() <= getDiffSecNow(startTime.pingOn)) && (GetServerSign() == TRUE))
  210. SendPing(wsi);
  211. else
  212. SendData(wsi);
  213. break;
  214. case LWS_CALLBACK_CLIENT_RECEIVE://8
  215. ((char *)in)[len] = '\0';
  216. DEBUG_OCPPMESSAGE_INFO("<==== %s\n", (char *)in);
  217. //**********Receive Message**********/
  218. c = 0;
  219. loc = strstr((const char *)in, "][2,");
  220. if(loc == NULL)
  221. {
  222. loc = strstr((const char *)in, "][3,");
  223. if(loc == NULL)
  224. {
  225. loc = strstr((const char *)in, "][4,");
  226. }
  227. }
  228. memset(sstr, 0, ARRAY_SIZE(sstr) );
  229. if(loc != NULL)
  230. {
  231. DEBUG_INFO("There are continuous second packet []\n");
  232. while (loc[1+c] != '\0')
  233. {
  234. sstr[c] = loc[1+c];
  235. c++;
  236. }
  237. sstr[c] = '\0';
  238. strcpy(tempin, sstr);
  239. DEBUG_INFO("Final Receive: %s\n", tempin);
  240. }
  241. else
  242. {
  243. strcpy(tempin,(char *)in);
  244. }
  245. ReceivedMessage((void *)strtrim(tempin), strlen(tempin));
  246. isWebsocketSendable = 1;
  247. refreshStartTimer(&startTime.pingOn);
  248. break;
  249. case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
  250. DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
  251. DEBUG_OCPPMESSAGE_INFO("<==== Get PONG packet.\n");
  252. refreshStartTimer(&startTime.pingOn);
  253. isWebsocketSendable = ON;
  254. counterPingSend = 0;
  255. break;
  256. case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
  257. DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");
  258. break;
  259. case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
  260. DEBUG_INFO("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS\n");
  261. break;
  262. case LWS_CALLBACK_PROTOCOL_DESTROY:
  263. DEBUG_INFO("LWS_CALLBACK_PROTOCOL_DESTROY\n");
  264. break;
  265. case LWS_CALLBACK_RECEIVE_PONG:
  266. DEBUG_INFO("LWS_CALLBACK_RECEIVE_PONG\n");
  267. break;
  268. case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
  269. DEBUG_INFO("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE\n");
  270. break;
  271. case LWS_CALLBACK_CLOSED_CLIENT_HTTP:
  272. DEBUG_INFO("LWS_CALLBACK_CLOSED_CLIENT_HTTP\n");
  273. if(GetInternetConn() == 1)
  274. {
  275. DEBUG_INFO("Download new CA certification.\n", system("wget --no-check-certificate -O /root/cacert.pem http://curl.haxx.se/ca/cacert.pem &"));
  276. }
  277. break;
  278. default:
  279. DEBUG_INFO("Reason = %d\n", reason);
  280. break;
  281. }
  282. return 0;
  283. }
  284. static struct lws_protocols protocols[] =
  285. {
  286. {
  287. "ocpp2.0.1",
  288. OCPP20Callback,
  289. WEBSOCKET_BUFFER_SIZE,
  290. WEBSOCKET_BUFFER_SIZE,
  291. },
  292. {
  293. "ocpp2.0.1",
  294. OCPP20Callback,
  295. WEBSOCKET_BUFFER_SIZE,
  296. WEBSOCKET_BUFFER_SIZE,
  297. },
  298. {
  299. NULL, NULL, 0 /* End of list */
  300. }
  301. };
  302. void* ConnectWsServer(void* data) //int ConnectWsServer()
  303. {
  304. struct lws_context_creation_info ContextInfo;
  305. struct lws_client_connect_info ConnInfo;
  306. int use_ssl=0;
  307. counterConnect += 1;
  308. // If internet available synchronize datetime with ntp server
  309. if(GetInternetConn() == 1)
  310. {
  311. system("pkill ntpd");
  312. DEBUG_INFO("NTP synchronize with Microsoft\n", system("/usr/sbin/ntpd -nqp time.windows.com &"));
  313. DEBUG_INFO("NTP synchronize with China\n", system("/usr/sbin/ntpd -nqp cn.ntp.org.cn &"));
  314. DEBUG_INFO("NTP synchronize with Taiwan\n", system("/usr/sbin/ntpd -nqp tock.stdtime.gov.tw &"));
  315. DEBUG_INFO("NTP synchronize with Europe\n", system("/usr/sbin/ntpd -nqp 0.europe.pool.ntp.org &"));
  316. }
  317. if(context!=NULL)
  318. {
  319. pthread_detach(pthread_self());
  320. lws_context_destroy(context);
  321. ConnectionEstablished=0;
  322. context = NULL;
  323. }
  324. checkNetworkProfile();
  325. memset(&ContextInfo, 0, sizeof(struct lws_context_creation_info));
  326. if((GetOcppServerURL()==0) || (GetOcppPort() == 0) || (GetOcppPath()==0))
  327. {
  328. DEBUG_ERROR("OCPP URL is NULL or OCPP Port is zero or OCPP Path is NULL\n");
  329. goto end;
  330. }
  331. if((strcmp(OcppProtocol,"ws")==0)&&(strlen(OcppProtocol)== 2))
  332. {
  333. DEBUG_INFO("Web socket is non-security mode.\n");
  334. use_ssl=0;
  335. }
  336. else if((strcmp(OcppProtocol,"wss")==0)&&(strlen(OcppProtocol)== 3))
  337. {
  338. DEBUG_INFO("Web socket is security mode.\n");
  339. use_ssl=1;
  340. }
  341. ContextInfo.port = CONTEXT_PORT_NO_LISTEN;
  342. ContextInfo.iface = NULL;
  343. ContextInfo.ssl_private_key_password = NULL;
  344. ContextInfo.ssl_cert_filepath = ((GetOcppSecurityProfile()==3) && (access("/Storage/OCPP/certCP.pem",F_OK) != -1))?"/Storage/OCPP/certCP.pem":NULL;
  345. ContextInfo.ssl_private_key_filepath = ((GetOcppSecurityProfile()==3) && (access("/Storage/OCPP/certCP.key",F_OK) != -1))?"/Storage/OCPP/certCP.key":NULL;
  346. ContextInfo.ssl_ca_filepath = "/root/certCA.pem";
  347. ContextInfo.ssl_cipher_list = NULL; //use default one
  348. ContextInfo.gid = -1;
  349. ContextInfo.uid = -1;
  350. if(use_ssl)
  351. {
  352. ContextInfo.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
  353. }
  354. ContextInfo.protocols = protocols;
  355. ContextInfo.timeout_secs = GetBackendConnectionTimeout();
  356. //ContextInfo.ws_ping_pong_interval = GetWebSocketPingInterval();
  357. ContextInfo.ka_time = 20;
  358. ContextInfo.keepalive_timeout = 5;
  359. ContextInfo.ka_probes = 2;
  360. ContextInfo.ka_interval = 5;
  361. context = lws_create_context(&ContextInfo);
  362. if (context == NULL)
  363. {
  364. DEBUG_ERROR("lws_create_context NG");
  365. goto end;
  366. }
  367. memset(&ConnInfo,0,sizeof(struct lws_client_connect_info));
  368. // fill up below information
  369. ConnInfo.context = context;
  370. ConnInfo.address=(const char *)OcppHost;
  371. DEBUG_INFO("ConnInfo.address: %s\n", ConnInfo.address);
  372. ConnInfo.port = GetOcppPort();
  373. DEBUG_INFO("ConnInfo.port: %d\n", ConnInfo.port);
  374. ConnInfo.path=(const char *)OcppPath;
  375. DEBUG_INFO("ConnInfo.path: %s\n", ConnInfo.path);
  376. char addr_port[256] = { 0 };
  377. sprintf(addr_port, "%s:%u", ConnInfo.address, (ConnInfo.port & 65535) );
  378. ConnInfo.host= addr_port; // ConnInfo.address;//lws_canonical_hostname(context);
  379. //ConnInfo.origin="origin";
  380. ConnInfo.protocol = protocols[1].name;
  381. ConnInfo.ietf_version_or_minus_one = -1;
  382. if(use_ssl)
  383. {
  384. #ifdef TLS_VALID_CERT_EXPIRED
  385. ConnInfo.ssl_connection = LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
  386. DEBUG_INFO("TLS does not allow expired certification.\n");
  387. #else
  388. ConnInfo.ssl_connection = LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK | LCCSCF_ALLOW_EXPIRED;
  389. DEBUG_INFO("TLS allow expired certification.\n");
  390. #endif
  391. }
  392. wsi_client = lws_client_connect_via_info(&ConnInfo);
  393. if (!wsi_client)
  394. {
  395. DEBUG_ERROR("lws_client_connect_via_info NG\n");
  396. //goto end;
  397. }
  398. counterConnect=0;
  399. DEBUG_INFO("counterConnect: %d\n", counterConnect);
  400. end:
  401. pthread_exit(NULL/*(void *) fname*/);
  402. }
  403. int isQueueOverSize()
  404. {
  405. FILE *fp;
  406. uint32_t file_size;
  407. uint8_t result = FALSE;
  408. fp = fopen("/Storage/OCPP/TransactionRelatedQueue20" , "r");
  409. if(fp != NULL)
  410. {
  411. fseek(fp, 0L, SEEK_END);
  412. file_size = ftell(fp);
  413. if(file_size > (100*1024*1024))
  414. {
  415. result = TRUE;
  416. DEBUG_WARN("Queue file over size.\n");
  417. }
  418. fclose(fp);
  419. }
  420. return result;
  421. }
  422. int showfront(char *uuid, char *data)
  423. {
  424. FILE *fp;
  425. int result = FALSE; // 1: TRUE 0:FALSE
  426. char str[QUEUE_MESSAGE_LENGTH]={0};
  427. char sstr[50]={ 0 };//sstr[200]={ 0 };
  428. int c = 0;
  429. char *loc;
  430. char rmFileCmd[100]={0};
  431. struct stat stats;
  432. stat("/Storage/OCPP", &stats);
  433. // Check for directory existence
  434. if (S_ISDIR(stats.st_mode) == 1)
  435. {
  436. //DEBUG_INFO("\n OCPP directory exist \n");
  437. }
  438. else
  439. {
  440. DEBUG_INFO("\n OCPP directory not exist, create dir \n");
  441. sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
  442. system(rmFileCmd);
  443. }
  444. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  445. if((access("/Storage/OCPP/TransactionRelatedQueue20",F_OK))!=-1)
  446. {
  447. //DEBUG_INFO("TransactionRelatedQueue20 exist.\n");
  448. }
  449. else
  450. {
  451. //DEBUG_INFO("TransactionRelatedQueue20 not exist\n");
  452. FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue20", "w+");
  453. if(log == NULL)
  454. {
  455. DEBUG_INFO("Can't Create File TransactionRelatedQueue20 \n");
  456. return FALSE;
  457. }
  458. else
  459. {
  460. fclose(log);
  461. }
  462. }
  463. /* opening file for reading */
  464. fp = fopen("/Storage/OCPP/TransactionRelatedQueue20" , "r");
  465. if(fp == NULL) {
  466. DEBUG_INFO("Error opening TransactionRelatedQueue20 file");
  467. return FALSE;
  468. }
  469. if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL ) {
  470. /* writing content to stdout */
  471. //DEBUG_INFO("str=%s",str);
  472. if ((str[0] == '\n')||(strcmp(str,"")==0))
  473. {
  474. DEBUG_INFO("It is a blank line");
  475. fclose(fp);
  476. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  477. sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/TransactionRelatedQueue20");
  478. system(rmFileCmd);
  479. result = FALSE;
  480. return result;
  481. }
  482. else
  483. {
  484. //puts(str);
  485. //----------------uuid--------------//
  486. loc = strstr(str, "\"");
  487. memset(sstr ,0, ARRAY_SIZE(sstr) );
  488. c = 0;
  489. while (loc[1+c] != '\"')
  490. {
  491. sstr[c] = loc[1+c];
  492. c++;
  493. }
  494. sstr[c] = '\0';
  495. //DEBUG_INFO("\n uuid:%s", sstr);
  496. //DEBUG_INFO("\n data:%s", str);
  497. strcpy(uuid,sstr);
  498. strcpy(data,str);
  499. result = TRUE;
  500. }
  501. }
  502. else
  503. {
  504. //DEBUG_INFO("queue is null\n");
  505. strcpy(uuid,"");
  506. strcpy(data,"");
  507. result = FALSE;
  508. }
  509. fclose(fp);
  510. return result;
  511. }
  512. int addq(char *uuid, char *data)
  513. {
  514. FILE *outfile;
  515. char rmFileCmd[100]={0};
  516. struct stat stats;
  517. stat("/Storage/OCPP", &stats);
  518. DEBUG_INFO("addq\n");
  519. // Check for directory existence
  520. if (S_ISDIR(stats.st_mode) == 1)
  521. {
  522. //DEBUG_INFO("\n OCPP directory exist \n");
  523. }
  524. else
  525. {
  526. //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
  527. sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
  528. system(rmFileCmd);
  529. }
  530. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  531. if((access("/Storage/OCPP/TransactionRelatedQueue20",F_OK))!=-1)
  532. {
  533. //DEBUG_INFO("TransactionRelatedQueue20 exist.\n");
  534. }
  535. else
  536. {
  537. //DEBUG_INFO("TransactionRelatedQueue20 not exist\n");
  538. FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue20", "w+");
  539. if(log == NULL)
  540. {
  541. //DEBUG_INFO("Can't Create File TransactionRelatedQueue20 \n");
  542. return FALSE;
  543. }
  544. else
  545. {
  546. fclose(log);
  547. }
  548. }
  549. // open file for writing
  550. outfile = fopen ("/Storage/OCPP/TransactionRelatedQueue20", "a");
  551. DEBUG_INFO("data = %s\n",data);
  552. fputs(data, outfile);
  553. fputs("\n", outfile);
  554. fclose (outfile);
  555. queueOpInfo.TransactionQueueNum += 1;
  556. DEBUG_INFO("add queue end\n");
  557. system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
  558. return FALSE;
  559. }
  560. int delq()
  561. {
  562. char tempfile[] = "/Storage/OCPP/delqtemp.json";
  563. FILE *infile;
  564. FILE *outfile;
  565. int resultRename=0;
  566. char filename[60]={0};
  567. char rmFileCmd[100]={0};
  568. struct stat stats;
  569. stat("/Storage/OCPP", &stats);
  570. DEBUG_INFO("delq()\n");
  571. // Check for directory existence
  572. if (S_ISDIR(stats.st_mode) == 1)
  573. {
  574. //DEBUG_INFO("\n OCPP directory exist \n");
  575. }
  576. else
  577. {
  578. //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
  579. sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
  580. system(rmFileCmd);
  581. }
  582. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  583. if((access("/Storage/OCPP/TransactionRelatedQueue20",F_OK))!=-1)
  584. {
  585. //DEBUG_INFO("TransactionRelatedQueue20 exist.\n");
  586. }
  587. else
  588. {
  589. //DEBUG_INFO("TransactionRelatedQueue20 not exist\n");
  590. FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue20", "w+");
  591. if(log == NULL)
  592. {
  593. //DEBUG_INFO("log is NULL\n");
  594. return 0;
  595. }
  596. else
  597. {
  598. fclose(log);
  599. }
  600. }
  601. // open file for writing
  602. strcpy(filename, "/Storage/OCPP/TransactionRelatedQueue20");
  603. infile = fopen ("/Storage/OCPP/TransactionRelatedQueue20", "r");
  604. outfile = fopen (tempfile, "w");
  605. //DEBUG_INFO("feof(infile) =%d\n",feof(infile));
  606. int c;
  607. c = fgetc(infile);
  608. //printf("file c:%d\n",c);
  609. rewind(infile);
  610. if(c == EOF)
  611. {
  612. //DEBUG_INFO("TransactionRelatedQueue20 is NULL\n");
  613. fclose(infile);
  614. fclose(outfile);
  615. sprintf(rmFileCmd,"rm -f %s",tempfile);
  616. system(rmFileCmd);
  617. }
  618. else
  619. {
  620. char buf[QUEUE_MESSAGE_LENGTH]={0};
  621. int i = 0;
  622. //DEBUG_INFO("Orignal File is not NULL\n");
  623. while (fgets(buf, sizeof(buf), infile) != NULL)
  624. {
  625. //printf("Orignal File get strings \n");
  626. buf[strlen(buf) - 1] = '\0'; // eat the newline fgets() stores
  627. if(i==0)
  628. {
  629. queueOpInfo.TransactionQueueNum -= 1;
  630. queueOpInfo.TransactionMessageResend = 0;
  631. DEBUG_INFO("delete the item\n");
  632. }
  633. if(i != 0)
  634. {
  635. fprintf(outfile,"%s\n", buf);
  636. }
  637. i = i + 1;
  638. }
  639. fclose(infile);
  640. fclose(outfile);
  641. sprintf(rmFileCmd,"rm -f %s",filename);
  642. system(rmFileCmd);
  643. resultRename = rename(tempfile, filename);
  644. if(resultRename == 0)
  645. {
  646. //DEBUG_INFO("TransactionRelatedQueue20 file renamed successfully");
  647. }
  648. else
  649. {
  650. //DEBUG_INFO("Error: unable to rename the TransactionRelatedQueue20 file");
  651. }
  652. DEBUG_INFO("delq() end\n");
  653. }
  654. system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
  655. return 0;
  656. }
  657. int showqueue()
  658. {
  659. char rmFileCmd[100]={0};
  660. struct stat stats;
  661. stat("/Storage/OCPP", &stats);
  662. // Check for directory existence
  663. if (S_ISDIR(stats.st_mode) == 1)
  664. {
  665. //DEBUG_INFO("\n OCPP directory exist \n");
  666. }
  667. else
  668. {
  669. //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
  670. sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
  671. system(rmFileCmd);
  672. }
  673. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  674. if((access("/Storage/OCPP/TransactionRelatedQueue20",F_OK))!=-1)
  675. {
  676. //DEBUG_INFO("TransactionRelatedQueue20 exist.\n");
  677. }
  678. else
  679. {
  680. //DEBUG_INFO("TransactionRelatedQueue20 not exist\n");
  681. FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue20", "w+");
  682. if(log == NULL)
  683. {
  684. DEBUG_INFO("log is NULL\n");
  685. return FALSE;
  686. }
  687. else
  688. {
  689. fclose(log);
  690. }
  691. }
  692. FILE *fp = fopen("/Storage/OCPP/TransactionRelatedQueue20", "r");
  693. char line[QUEUE_MESSAGE_LENGTH]={0};
  694. // check if file exist (and you can open it) or not
  695. if (fp == NULL) {
  696. DEBUG_INFO("can open file TransactionRelatedQueue20!");
  697. return FALSE;
  698. }
  699. queueOpInfo.TransactionQueueNum = 0; // the number of packets in queue
  700. while(fgets(line, sizeof line, fp) != NULL) {
  701. //DEBUG_INFO("%s\n", line);
  702. queueOpInfo.TransactionQueueNum += 1; //the number of packets in queue
  703. }
  704. fclose(fp);
  705. return TRUE;
  706. }
  707. int sentqueue(){
  708. FILE *fp;
  709. int result = FALSE; // 1: TRUE 0:FALSE
  710. char str[QUEUE_MESSAGE_LENGTH]={0};
  711. char cmdBuf[100]={0};
  712. struct stat stats;
  713. json_object *queueJson;
  714. DEBUG_INFO("Sent queue.\n");
  715. stat("/Storage/OCPP", &stats);
  716. // Check for directory existence
  717. if (S_ISDIR(stats.st_mode) == 1)
  718. {
  719. //DEBUG_INFO("\n OCPP directory exist \n");
  720. }
  721. else
  722. {
  723. //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
  724. sprintf(cmdBuf,"mkdir -p %s","/Storage/OCPP");
  725. system(cmdBuf);
  726. }
  727. /* opening file for reading */
  728. fp = fopen("/Storage/OCPP/TransactionRelatedQueue20" , "r");
  729. if(fp == NULL)
  730. {
  731. DEBUG_ERROR("Error opening file");
  732. return FALSE;
  733. }
  734. if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL )
  735. {
  736. queueJson = json_tokener_parse(str);
  737. if(!is_error(queueJson))
  738. {
  739. LWS_Send(str);
  740. }
  741. json_object_put(queueJson);
  742. result = TRUE;
  743. }
  744. else
  745. {
  746. result = FALSE;
  747. }
  748. fclose(fp);
  749. return result;
  750. }
  751. void* processTransactionQueue(void* data)
  752. {
  753. char frontUUID[100] ={0};
  754. char frontData[QUEUE_MESSAGE_LENGTH] ={0};
  755. int queueNotEmpty = FALSE;
  756. while(1)
  757. {
  758. if(!req_SendQueue && ((getDiffSecNow(startTime.startTimeQueue) >= ((TransactionMessageRetryIntervalGet()>10?TransactionMessageRetryIntervalGet():10)*(queueOpInfo.TransactionMessageResend>1?2:1))) || (isWebsocketSendable && isQueueSendable && (getDiffSecNow(startTime.startTimeQueue) >= ((counterQueueSent>=20)?5:0)))))
  759. {
  760. if(FirstHeartBeatResponse() == 1)
  761. {
  762. memset(frontUUID, 0, ARRAY_SIZE(frontUUID));
  763. memset(frontData, 0, ARRAY_SIZE(frontData));
  764. queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);
  765. if((queueNotEmpty == TRUE) && (GetOcppConnStatus() == 1))
  766. {
  767. if(isWebsocketSendable)
  768. DEBUG_INFO("isWebsocketSendable on.\n");
  769. if(isQueueSendable)
  770. DEBUG_INFO("isQueueSendable on.\n");
  771. if(((getDiffSecNow(startTime.startTimeQueue) > (TransactionMessageRetryIntervalGet()>10?TransactionMessageRetryIntervalGet():10))))
  772. DEBUG_INFO("Queue timer(%d) over spec(%d).\n", getDiffSecNow(startTime.startTimeQueue), TransactionMessageRetryIntervalGet());
  773. if(queueOpInfo.TransactionMessageResend < TransactionMessageAttemptsGet())
  774. {
  775. DEBUG_INFO("Sent message from queue request.\n");
  776. DEBUG_INFO("TransactionMessageResend time: %d\n", queueOpInfo.TransactionMessageResend);
  777. req_SendQueue = 1;
  778. queueOpInfo.TransactionMessageResend += 1;
  779. }
  780. else
  781. {
  782. DEBUG_INFO("Transaction message resend(%d) over spec(%d) message abandon.\n", queueOpInfo.TransactionMessageResend, TransactionMessageAttemptsGet());
  783. queue_operation(QUEUE_OPERATION_DEL,"","");
  784. queueOpInfo.TransactionMessageResend = 0;
  785. req_SendQueue = 0;
  786. }
  787. }
  788. }
  789. // Refresh queue timer
  790. refreshStartTimer(&startTime.startTimeQueue);
  791. if((counterQueueSent >= 10) || (queueNotEmpty == FALSE))
  792. {
  793. counterQueueSent = 0;
  794. }
  795. else
  796. {
  797. counterQueueSent += 1;
  798. }
  799. }
  800. usleep(500000);
  801. }
  802. pthread_exit(NULL);
  803. return 0;
  804. }
  805. void* processWatchdog()
  806. {
  807. for(;;)
  808. {
  809. if((getDiffSecNow(startTime.disconnectServer) >= 7200))
  810. {
  811. DEBUG_INFO("OCPP server disconnect timer(%d) over 7200 seconds.\n", getDiffSecNow(startTime.disconnectServer));
  812. system("killall OcppBackend20");
  813. }
  814. if(counterConnect >= 3)
  815. {
  816. DEBUG_INFO("Connect OCPP server timeout over 3 count.\n");
  817. system("killall OcppBackend20");
  818. }
  819. if((0 < GetWebSocketPingInterval()) && (0 < counterPingSend) && ((GetWebSocketPingInterval()+5) <= getDiffSecNow(startTime.pingOn)) && (wsi_client != NULL) && (GetServerSign() == TRUE))
  820. {
  821. DEBUG_WARN("Pong packet receive timeout.\n");
  822. //system("killall OcppBackend20");
  823. lws_context_destroy(context);
  824. ConnectionEstablished = 0;
  825. context = NULL;
  826. }
  827. usleep(500000);
  828. }
  829. pthread_exit(NULL); //
  830. }
  831. void CheckTransactionPacket(char *uuid)
  832. {
  833. char frontUUID[100]={0};
  834. char frontData[QUEUE_MESSAGE_LENGTH]={0};
  835. int queueNotEmpty = FALSE;
  836. int cmpResult = 0;
  837. queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally
  838. if(queueNotEmpty == TRUE)
  839. {
  840. cmpResult = strcmp(frontUUID, uuid);
  841. if (cmpResult == 0)
  842. {
  843. DEBUG_INFO("Receive queue response match.\n");
  844. queue_operation(QUEUE_OPERATION_DEL,"","");//delq(); ---> remove temporally
  845. queueOpInfo.TransactionMessageResend = 0;
  846. }
  847. else
  848. DEBUG_INFO("Receive queue response mismatch.\n");
  849. }
  850. }
  851. int queue_operation(int type, char *frontUUID, char *frontData)
  852. {
  853. int result=0;
  854. while(1)
  855. {
  856. if (!queueOpInfo.IsUsing )
  857. {
  858. queueOpInfo.IsUsing = TRUE;
  859. if(type == QUEUE_OPERATION_SHOWQUEUE) // show items in queue
  860. {
  861. result = showqueue();
  862. }
  863. else if(type == QUEUE_OPERATION_SHOWFRONT) // show first item
  864. {
  865. result = showfront(frontUUID, frontData);
  866. }
  867. else if(type == QUEUE_OPERATION_DEL) // delete item
  868. {
  869. result = delq();
  870. }
  871. else if(type == QUEUE_OPERATION_SENT) // sent items in queue
  872. {
  873. result = sentqueue();
  874. }
  875. else if(type == QUEUE_OPERATION_ADD) // add items to the queue
  876. {
  877. // If queue file over size only add start * stop transaction message
  878. if(!isQueueOverSize() || (strstr(frontData, "MeterValues") == NULL))
  879. {
  880. result = addq(frontUUID, frontData);
  881. }
  882. }
  883. queueOpInfo.IsUsing = FALSE;
  884. break;
  885. }
  886. usleep(100000);
  887. }
  888. return result;
  889. }
  890. int removeMessageSentFile(void)
  891. {
  892. char rmFileCmd[100]={0};
  893. struct stat stats;
  894. stat("/Storage/OCPP", &stats);
  895. // Check for directory existence
  896. if(S_ISDIR(stats.st_mode) == 1)
  897. {
  898. //DEBUG_INFO("\n OCPP directory exist \n");
  899. }
  900. else
  901. {
  902. DEBUG_INFO("\n directory not exist, create dir \n");
  903. sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
  904. system(rmFileCmd);
  905. }
  906. stat("/Storage/OCPP/TransactionRelatedQueue20", &stats);
  907. if(stats.st_size < 10)
  908. {
  909. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  910. if((access("/Storage/OCPP/MessageSent",F_OK))!=-1)
  911. {
  912. DEBUG_INFO("MessageSent file exist.\n");
  913. sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/MessageSent");
  914. system(rmFileCmd);
  915. }
  916. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  917. }
  918. return 0;
  919. }
  920. //================================================
  921. // Main process
  922. //================================================
  923. int main(void)
  924. {
  925. char rmFileCmd[100]={0};
  926. struct stat stats;
  927. queueOpInfo.IsUsing = FALSE;
  928. queueOpInfo.TransactionMessageResend = 0;
  929. DEBUG_INFO("Module_OcppBackend20 task initialization...\n");
  930. //lws_set_log_level(LLL_PARSER | LLL_HEADER | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO | LLL_DEBUG | LLL_EXT | LLL_CLIENT | LLL_LATENCY , NULL);
  931. if(ProcessShareMemory()== FAIL)
  932. {
  933. return FAIL;
  934. }
  935. // Check & create OCPP dir
  936. stat("/Storage/OCPP", &stats);
  937. if(S_ISDIR(stats.st_mode) != 1)
  938. {
  939. DEBUG_INFO("OCPP directory not exist, create dir \n");
  940. sprintf(rmFileCmd,"mkdir -p /Storage/OCPP");
  941. system(rmFileCmd);
  942. }
  943. memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
  944. // Create Process: Resend Transaction
  945. refreshStartTimer(&startTime.disconnectServer);
  946. pthread_create(&tid_ProcQueue, NULL, processTransactionQueue, NULL);
  947. pthread_create(&tid_Watchdog, NULL, processWatchdog, NULL);
  948. // Sqlite3 initial
  949. if(DB_Initial() != PASS)
  950. {
  951. DEBUG_ERROR("OCPP 2.0 local database initial fail.\n");
  952. return 0;
  953. }
  954. initialConfigurationTable();
  955. removeMessageSentFile();
  956. for(;;)
  957. {
  958. // Connect server
  959. if(ConnectionEstablished==0) // Check InternetConn 0: disconnected, 1: connected
  960. {
  961. isWebsocketSendable = 1;
  962. isQueueSendable = 1;
  963. SetOcppConnStatus(FALSE);
  964. SetServerSign(FALSE);
  965. InitialSystemValue();
  966. if(getDiffSecNow(startTime.connect) >= 30)
  967. {
  968. DEBUG_INFO("Server connecting...\n");
  969. pthread_create(&tid_connectServer, NULL, ConnectWsServer, NULL);
  970. refreshStartTimer(&startTime.connect);
  971. }
  972. CheckSystemValue();
  973. }
  974. else
  975. {
  976. // Sign in
  977. if((GetServerSign() == FALSE) &&
  978. (isConnectorInitMode(0) != TRUE) &&
  979. ( (GetBootNotificationInterval()>0) ? (getDiffSecNow(startTime.bootNotification) >= GetBootNotificationInterval()) : (getDiffSecNow(startTime.bootNotification) >= 10) )
  980. )
  981. {
  982. sendBootNotificationRequest();
  983. refreshStartTimer(&startTime.bootNotification);
  984. }
  985. // Check System Value
  986. CheckSystemValue();
  987. // On line operation
  988. if(GetServerSign() == TRUE)
  989. {
  990. // Send message from queue
  991. if((req_SendQueue == 1) && (isWebsocketSendable || ((queueOpInfo.TransactionMessageResend > 1) && (queueOpInfo.PreTransactionMessageResend != queueOpInfo.TransactionMessageResend))))
  992. {
  993. queue_operation(QUEUE_OPERATION_SENT, "", "");
  994. req_SendQueue = 0;
  995. queueOpInfo.PreTransactionMessageResend = queueOpInfo.TransactionMessageResend;
  996. }
  997. // PING packet
  998. if(isWebsocketSendable && (0 < GetWebSocketPingInterval()) && ((GetWebSocketPingInterval()+counterPingSend) <= getDiffSecNow(startTime.pingOn)))
  999. {
  1000. lws_callback_on_writable(wsi_client);
  1001. counterPingSend++;
  1002. }
  1003. if(GetHeartBeatWithNOResponse() >= 30)
  1004. {
  1005. lws_context_destroy(context);
  1006. ConnectionEstablished = 0;
  1007. context = NULL;
  1008. SetHeartBeatWithNOResponse();
  1009. DEBUG_WARN("Heartbeat re-send over 30 count.\n");
  1010. }
  1011. if((GetOcppConnStatus() == 0))
  1012. {
  1013. if(getDiffSecNow(startTime.reConnect) >= 3)
  1014. {
  1015. DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
  1016. lws_context_destroy(context);
  1017. ConnectionEstablished = 0;
  1018. context = NULL;
  1019. }
  1020. }
  1021. else
  1022. {
  1023. refreshStartTimer(&startTime.reConnect);
  1024. }
  1025. refreshStartTimer(&startTime.disconnectServer);
  1026. }
  1027. }
  1028. do
  1029. {
  1030. lws_service(context, 0);//timeout_ms
  1031. }while((SendBufLen>0) && (context!=NULL) && GetOcppConnStatus());
  1032. refreshProcDogTimer();
  1033. usleep(100000);
  1034. }
  1035. pthread_join(tid_ProcQueue, NULL);
  1036. pthread_join(tid_Watchdog, NULL);
  1037. return FAIL;
  1038. }