|
@@ -1,1499 +1,1499 @@
|
|
|
-#include "Module_OcppBackend.h"
|
|
|
-
|
|
|
-typedef enum boolean { FALSE, TRUE } BOOL;
|
|
|
-
|
|
|
-struct lws *wsi_client;
|
|
|
-struct lws_context *context;
|
|
|
-static int sendbuffer = 0;
|
|
|
-pthread_t pid;
|
|
|
-
|
|
|
-pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
|
|
|
-pthread_mutex_t lock_sentData = PTHREAD_MUTEX_INITIALIZER;
|
|
|
-pthread_mutex_t receiveData = PTHREAD_MUTEX_INITIALIZER;
|
|
|
-
|
|
|
-//==========================================
|
|
|
-// Function prototype
|
|
|
-//==========================================
|
|
|
-void ReceivedMessage(void *in, size_t len);
|
|
|
-
|
|
|
-struct StartTime
|
|
|
-{
|
|
|
- unsigned int connect;
|
|
|
- unsigned int bootNotification;
|
|
|
-}startTime;
|
|
|
-
|
|
|
-int SendBufLen=(1024*4);//(1024*3);
|
|
|
-unsigned char SendBuffer[1024*4]={0};
|
|
|
-static int ConnectionEstablished=0;
|
|
|
-static int TransactionMessageResend = 1; // the number of retry to submit a transaction-related message when the Central System fails to process it.
|
|
|
-static int TransactionQueueInterval = 10;//3;
|
|
|
-static int TransactionQueueNum = 0;
|
|
|
-static int OfflineTransactionQueueNum = 0; // Number of offline transactions
|
|
|
-static int OfflineTransaction = 0;
|
|
|
-static int IsUsing = FALSE;
|
|
|
-int defaultWaitingTime = 10; //10 second
|
|
|
-
|
|
|
-char OcppPath[160]={0};
|
|
|
-char OcppProtocol[10]={0},OcppHost[50]={0}, OcppTempPath[50]={0};
|
|
|
-int OcppPort=0;
|
|
|
-unsigned char StartTransactionIdTagTemp[20]={0};
|
|
|
-
|
|
|
-sqlite3 *db;
|
|
|
-char *errMsg = NULL;
|
|
|
-static char *createsql = "CREATE TABLE IF NOT EXISTS log_buffer("
|
|
|
- "idx integer primary key,"
|
|
|
- "user_id text,"
|
|
|
- "cmd_sn text,"
|
|
|
- "charger_id text,"
|
|
|
- "gun_type text,"
|
|
|
- "gun_no text,"
|
|
|
- "rfid_no text,"
|
|
|
- "stime text,"
|
|
|
- "etime text,"
|
|
|
- "time_len text,"
|
|
|
- "s_soc text,"
|
|
|
- "e_soc text,"
|
|
|
- "stop_reason text,"
|
|
|
- "power text,"
|
|
|
- "meter_before text,"
|
|
|
- "meter_after text,"
|
|
|
- "charge_price text,"
|
|
|
- "reserve text,"
|
|
|
- "surplus_before text,"
|
|
|
- "surplus_after text,"
|
|
|
- "service_price text,"
|
|
|
- "is_pay text,"
|
|
|
- "charge_strategy text,"
|
|
|
- "charge_parameter text,"
|
|
|
- "vin text,"
|
|
|
- "vehicle_no text,"
|
|
|
- "start_method text,"
|
|
|
- "card_type text,"
|
|
|
- "is_upload text,"
|
|
|
- "guid text UNIQUE,"
|
|
|
- "is_buf2OK text);";
|
|
|
-
|
|
|
-static char *sqlOcppAuthCache = "create table if not exists ocpp_auth_cache (idx integer primary key,"
|
|
|
- "idtag text UNIQUE,"
|
|
|
- "parent_idtag text,"
|
|
|
- "expir_date text,"
|
|
|
- "status text);";
|
|
|
-
|
|
|
-static char *sqlOcppAuthLocal = "create table if not exists ocpp_auth_local (idx integer primary key,"
|
|
|
- "idtag text UNIQUE,"
|
|
|
- "parent_idtag text,"
|
|
|
- "expir_date text,"
|
|
|
- "status text,"
|
|
|
- "version text);";
|
|
|
-//=================================
|
|
|
-// Common routine
|
|
|
-//=================================
|
|
|
-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;
|
|
|
-}
|
|
|
-
|
|
|
-void trim(char *s)
|
|
|
-{
|
|
|
- int i=0, j, k, l=0;
|
|
|
-
|
|
|
- while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
|
|
|
- i++;
|
|
|
-
|
|
|
- j = strlen(s)-1;
|
|
|
- while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
|
|
|
- j--;
|
|
|
-
|
|
|
- if(i==0 && j==strlen(s)-1) { }
|
|
|
- else if(i==0) s[j+1] = '\0';
|
|
|
- else {
|
|
|
- for(k=i; k<=j; k++) s[l++] = s[k];
|
|
|
- s[l] = '\0';
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int mystrcmp(char *p1,char *p2)
|
|
|
-{
|
|
|
- while(*p1==*p2)
|
|
|
- {
|
|
|
- if(*p1=='\0' || *p2=='\0')
|
|
|
- break;
|
|
|
- p1++;
|
|
|
- p2++;
|
|
|
- }
|
|
|
- if(*p1=='\0' && *p2=='\0')
|
|
|
- return(PASS);
|
|
|
- else
|
|
|
- return(FAIL);
|
|
|
-}
|
|
|
-
|
|
|
-void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
|
|
|
-{
|
|
|
- strncpy(dest, src + start, cnt);
|
|
|
- dest[cnt] = 0;
|
|
|
-}
|
|
|
-
|
|
|
-int strposs(char *source, char *substr, int idx)
|
|
|
-{
|
|
|
- char stack[strlen(source)];
|
|
|
- int result=0;
|
|
|
- int count=0;
|
|
|
-
|
|
|
- while(count<=idx)
|
|
|
- {
|
|
|
- memset(stack,0,sizeof stack);
|
|
|
- strncpy(stack, source+result, strlen(source)-result);
|
|
|
-
|
|
|
- int loc = strcspn(stack, substr);
|
|
|
-
|
|
|
- if(loc>0)
|
|
|
- result += (loc+1);
|
|
|
- else
|
|
|
- result = -1;
|
|
|
-
|
|
|
- count++;
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-void getSubStr(char *dest, char* src, char *split, int idx)
|
|
|
-{
|
|
|
-
|
|
|
- int start = (strposs(src,",",idx)+1);
|
|
|
- int cnt = (strposs(src,",",idx+1)-2)-(strposs(src,",",idx)+1);
|
|
|
-
|
|
|
- strncpy(dest, src + start, cnt);
|
|
|
- dest[cnt] = 0;
|
|
|
-}
|
|
|
-
|
|
|
-void split(char **arr, char *str, const char *del)
|
|
|
-{
|
|
|
- char *s = strtok(str, del);
|
|
|
-
|
|
|
- while(s != NULL)
|
|
|
- {
|
|
|
- *arr++ = s;
|
|
|
- s = strtok(NULL, del);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int strpos(char *source, char *substr, int skip)
|
|
|
-{
|
|
|
- char stack[strlen(source)];
|
|
|
- strncpy(stack, source+skip, strlen(source)-skip);
|
|
|
- char *p = strstr(stack, substr);
|
|
|
- if (p)
|
|
|
- return p - stack+skip;
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-char * strtrim( char * s )
|
|
|
-{
|
|
|
- char * p1 = s;
|
|
|
- char * p2 = s;
|
|
|
- while(*p1 != '\0')
|
|
|
- {
|
|
|
- while(*p1 == '\t' || *p1 == '\n' || *p1 == '\r') //while(*p1 == ' ' || *p1 == '\t' || *p1 == '\n' || *p1 == '\r')
|
|
|
- {
|
|
|
- p1 ++;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- * p2 ++ = *p1 ++;
|
|
|
- //printf("p2=%s\n",p2);
|
|
|
- }
|
|
|
- *p2 = '\0';
|
|
|
- return (s);
|
|
|
-}
|
|
|
-
|
|
|
-char *random_uuid(char* buf)
|
|
|
-{
|
|
|
- uuid_t uuid;
|
|
|
-
|
|
|
- uuid_generate(uuid);
|
|
|
- uuid_unparse(uuid, buf);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int GetTransactionQueueNum(void)
|
|
|
-{
|
|
|
- return TransactionQueueNum;
|
|
|
-}
|
|
|
-
|
|
|
-//==========================================
|
|
|
-// Web socket tranceive routine
|
|
|
-//==========================================
|
|
|
-int SendData(struct lws *wsi)
|
|
|
-{
|
|
|
- int n;
|
|
|
- int len;
|
|
|
- unsigned char out[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING] = {0};
|
|
|
-
|
|
|
- len = strlen((char *)SendBuffer);
|
|
|
-
|
|
|
- if(len == 0)
|
|
|
- return 0;
|
|
|
-
|
|
|
- memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, SendBuffer, len );
|
|
|
- DEBUG_OCPPMESSAGE_INFO("===========> %s\n", out + LWS_SEND_BUFFER_PRE_PADDING);
|
|
|
-
|
|
|
- n = lws_write(wsi, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
|
|
|
- memset(SendBuffer, 0, len);
|
|
|
-
|
|
|
- return n;
|
|
|
-}
|
|
|
-
|
|
|
-static int OCPP16Callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
|
|
-{
|
|
|
- switch (reason)
|
|
|
- {
|
|
|
- case LWS_CALLBACK_PROTOCOL_INIT:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_PROTOCOL_INIT\n");
|
|
|
-
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH\n");
|
|
|
-
|
|
|
- char buf[64];
|
|
|
- char hash[20], key_b64[40];
|
|
|
-
|
|
|
- lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64));// Sec-WebSocket-Key
|
|
|
-
|
|
|
- DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request START -----\n");
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_URI);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
|
|
|
-
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b64);
|
|
|
-
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request END -----\n");
|
|
|
-
|
|
|
- DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response START -----\n");
|
|
|
-
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_HTTP);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_UPGRADE);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_CONNECTION);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_ACCEPT);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_PROTOCOL);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response END -----\n");
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
|
|
|
- break;
|
|
|
-
|
|
|
- case LWS_CALLBACK_WSI_DESTROY:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_WSI_DESTROY\n");
|
|
|
- pthread_detach(pid);
|
|
|
- SetServerSign(FALSE);
|
|
|
- ConnectionEstablished = 0;
|
|
|
- context = NULL;
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_LOCK_POLL:
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_ADD_POLL_FD:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_ADD_POLL_FD\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_DEL_POLL_FD:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_DEL_POLL_FD\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_UNLOCK_POLL:
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CHANGE_MODE_POLL_FD:
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_WSI_CREATE:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_WSI_CREATE\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_GET_THREAD_ID:
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_ESTABLISHED: //3
|
|
|
- DEBUG_INFO("LWS_CALLBACK_CLIENT_ESTABLISHED\n");
|
|
|
-
|
|
|
- char frontUUID[100] ={0};
|
|
|
- char frontData[1200] ={0};
|
|
|
- int queueNotEmpty = FALSE;
|
|
|
-
|
|
|
- //connected
|
|
|
- ConnectionEstablished=1;
|
|
|
-
|
|
|
- queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);
|
|
|
-
|
|
|
- if(queueNotEmpty == TRUE)
|
|
|
- {
|
|
|
- OfflineTransaction = 1; // 0: no packets in queue. 1: There are packets in queue.
|
|
|
- }
|
|
|
-
|
|
|
- TransactionQueueInterval = 0;
|
|
|
- TransactionMessageResend = 1;
|
|
|
-
|
|
|
- //get offline number
|
|
|
- queue_operation(QUEUE_OPERATION_SHOWQUEUE,"","");
|
|
|
- OfflineTransactionQueueNum =TransactionQueueNum ;
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_CONNECTION_ERROR://1
|
|
|
- DEBUG_ERROR("LWS_CALLBACK_CLIENT_CONNECTION_ERROR %s\n", (char *)in );
|
|
|
- //disconnected
|
|
|
- ConnectionEstablished=0;
|
|
|
-
|
|
|
- char buf1[64];
|
|
|
- char hash1[20]={0}, key_b641[40]={0};
|
|
|
-
|
|
|
- lws_b64_encode_string(hash1, 16, key_b641, sizeof(key_b641));// Sec-WebSocket-Key
|
|
|
-
|
|
|
- DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client START =====\n");
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_URI);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b641);
|
|
|
- lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client END =====\n");
|
|
|
-
|
|
|
- DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response START =====\n");
|
|
|
- lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_HTTP);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf1);
|
|
|
- lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_UPGRADE);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf1);
|
|
|
- lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_CONNECTION);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf1);
|
|
|
- lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_ACCEPT);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf1);
|
|
|
- lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_PROTOCOL);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf1);
|
|
|
- DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response END =====\n");
|
|
|
-
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLOSED://4
|
|
|
- DEBUG_INFO("LWS_CALLBACK_CLOSED\n");
|
|
|
- //disconnected
|
|
|
- ConnectionEstablished=0;
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_WRITEABLE://10
|
|
|
- //if(need to send message and its relevant data already store into SendBuffer)
|
|
|
- SendData(wsi);
|
|
|
- //lws_rx_flow_control( wsi, 1 );
|
|
|
- break;
|
|
|
-
|
|
|
- case LWS_CALLBACK_CLIENT_RECEIVE://8
|
|
|
- ((char *)in)[len] = '\0';
|
|
|
- DEBUG_OCPPMESSAGE_INFO("<===== %s\n", (char *)in);
|
|
|
-
|
|
|
- char tempin[65536]={0};
|
|
|
-
|
|
|
- int c = 0;
|
|
|
- char *loc;
|
|
|
- char sstr[65536]={ 0 };
|
|
|
-
|
|
|
- //**********Receive Message**********/
|
|
|
- c = 0;
|
|
|
- loc = strstr((const char *)in, "][2,");
|
|
|
- if(loc == NULL)
|
|
|
- {
|
|
|
- loc = strstr((const char *)in, "][3,");
|
|
|
-
|
|
|
- if(loc == NULL)
|
|
|
- {
|
|
|
- loc = strstr((const char *)in, "][4,");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
-
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- DEBUG_INFO("there are continuous second packet []\n");
|
|
|
- while (loc[1+c] != '\0')
|
|
|
- {
|
|
|
- sstr[c] = loc[1+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
-
|
|
|
- sstr[c] = '\0';
|
|
|
- strcpy(tempin, sstr);
|
|
|
- DEBUG_INFO("Final Receive: %s\n", tempin);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- strcpy(tempin,(char *)in);
|
|
|
- }
|
|
|
-
|
|
|
- ReceivedMessage((void *)strtrim(tempin), len);
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS\n");
|
|
|
- break;
|
|
|
- case LWS_CALLBACK_PROTOCOL_DESTROY:
|
|
|
- DEBUG_INFO("LWS_CALLBACK_PROTOCOL_DESTROY\n");
|
|
|
- break;
|
|
|
- default:
|
|
|
- DEBUG_INFO("Reason = %d\n", reason);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static struct lws_protocols protocols[] =
|
|
|
-{
|
|
|
- {
|
|
|
- "ocpp1.6",
|
|
|
- OCPP16Callback,
|
|
|
- 10240,//65536,//10240,
|
|
|
- 10240,//65536,//10240,
|
|
|
- },
|
|
|
- {
|
|
|
- "ocpp1.6",
|
|
|
- OCPP16Callback,
|
|
|
- 10240,//65536,//10240,
|
|
|
- 10240,//65536,//10240,
|
|
|
- },
|
|
|
- {
|
|
|
- NULL, NULL, 0 /* End of list */
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-void* ConnectWsServer(void* data) //int ConnectWsServer()
|
|
|
-{
|
|
|
-
|
|
|
- struct lws_context_creation_info ContextInfo;
|
|
|
- struct lws_client_connect_info ConnInfo;
|
|
|
- int use_ssl=0;
|
|
|
-
|
|
|
- if(context!=NULL)
|
|
|
- {
|
|
|
- pthread_detach(pthread_self());
|
|
|
- lws_context_destroy(context);
|
|
|
- ConnectionEstablished=0;
|
|
|
- context = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- memset(&ContextInfo, 0, sizeof(struct lws_context_creation_info));
|
|
|
- if((GetOcppServerURL()==0) || (GetOcppPort() == 0) || (GetOcppPath()==0))
|
|
|
- {
|
|
|
- DEBUG_ERROR("OCPP URL is NULL or OCPP Port is zero or OCPP Path is NULL\n");
|
|
|
- goto end;
|
|
|
- }
|
|
|
-
|
|
|
- if((strcmp(OcppProtocol,"ws")==0)&&(strlen(OcppProtocol)== 2))
|
|
|
- {
|
|
|
- DEBUG_INFO("Web socket is non-security mode.\n");
|
|
|
- use_ssl=0;
|
|
|
- }
|
|
|
- else if((strcmp(OcppProtocol,"wss")==0)&&(strlen(OcppProtocol)== 3))
|
|
|
- {
|
|
|
- DEBUG_INFO("Web socket is security mode.\n");
|
|
|
- use_ssl=1;
|
|
|
- }
|
|
|
-
|
|
|
- ContextInfo.port = CONTEXT_PORT_NO_LISTEN;
|
|
|
- ContextInfo.iface = NULL;
|
|
|
- ContextInfo.ssl_private_key_password = NULL;
|
|
|
- ContextInfo.ssl_cert_filepath = NULL;//"./ssl_key/client_cert.pem";
|
|
|
- ContextInfo.ssl_private_key_filepath = NULL;//"./ssl_key/client_key.pem";
|
|
|
- ContextInfo.ssl_ca_filepath = "/root/cacert.pem";//"./cacert.pem";
|
|
|
- ContextInfo.ssl_cipher_list = NULL; //use default one
|
|
|
- ContextInfo.gid = -1;
|
|
|
- ContextInfo.uid = -1;
|
|
|
- if(use_ssl)
|
|
|
- {
|
|
|
- ContextInfo.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT ;
|
|
|
- }
|
|
|
-
|
|
|
- ContextInfo.protocols = protocols;
|
|
|
- ContextInfo.timeout_secs = GetWebSocketPingInterval();//WebSocketPingInterval;//30;//9999;//30;
|
|
|
- ContextInfo.ws_ping_pong_interval = GetWebSocketPingInterval();//WebSocketPingInterval;//30;//0 for none, else interval in seconds
|
|
|
- context = lws_create_context(&ContextInfo);
|
|
|
- if (context == NULL)
|
|
|
- {
|
|
|
- DEBUG_ERROR("lws_create_context NG");
|
|
|
-
|
|
|
- goto end;
|
|
|
- }
|
|
|
-
|
|
|
- memset(&ConnInfo,0,sizeof(struct lws_client_connect_info));
|
|
|
- // fill up below information
|
|
|
- ConnInfo.context = context;
|
|
|
-
|
|
|
- ConnInfo.address=(const char *)OcppHost;
|
|
|
- DEBUG_INFO("ConnInfo.address: %s\n", ConnInfo.address);
|
|
|
-
|
|
|
- ConnInfo.port = GetOcppPort();
|
|
|
- DEBUG_INFO("ConnInfo.port: %d\n", ConnInfo.port);
|
|
|
-
|
|
|
- ConnInfo.path=(const char *)OcppPath;
|
|
|
- DEBUG_INFO("ConnInfo.path: %s\n", ConnInfo.path);
|
|
|
-
|
|
|
- char addr_port[256] = { 0 };
|
|
|
- sprintf(addr_port, "%s:%u", ConnInfo.address, (ConnInfo.port & 65535) );
|
|
|
-
|
|
|
- ConnInfo.host= addr_port; // ConnInfo.address;//lws_canonical_hostname(context);
|
|
|
- ConnInfo.origin="origin";
|
|
|
- ConnInfo.protocol = protocols[1].name;
|
|
|
- ConnInfo.ietf_version_or_minus_one = -1;
|
|
|
-
|
|
|
- if(use_ssl)
|
|
|
- ConnInfo.ssl_connection = LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
|
|
|
-
|
|
|
- wsi_client = lws_client_connect_via_info(&ConnInfo);
|
|
|
- if (!wsi_client)
|
|
|
- {
|
|
|
- DEBUG_ERROR("lws_client_connect_via_info NG");
|
|
|
- goto end;
|
|
|
- }
|
|
|
-
|
|
|
-end:
|
|
|
- pthread_exit(NULL/*(void *) fname*/);
|
|
|
-}
|
|
|
-
|
|
|
-int showfront(char *uuid, char *data)
|
|
|
-{
|
|
|
- FILE *fp;
|
|
|
- int result = FALSE; // 1: TRUE 0:FALSE
|
|
|
- char str[1200]={0};
|
|
|
- char sstr[50]={ 0 };//sstr[200]={ 0 };
|
|
|
- int c = 0;
|
|
|
- char *loc;
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
-
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
-
|
|
|
- // Check for directory existence
|
|
|
- if (S_ISDIR(stats.st_mode) == 1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
-
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
- FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
-
|
|
|
- if(log == NULL)
|
|
|
- {
|
|
|
- DEBUG_INFO("Can't Create File TransactionRelatedQueue \n");
|
|
|
- return FALSE;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- fclose(log);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /* opening file for reading */
|
|
|
- fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
|
|
|
- if(fp == NULL) {
|
|
|
- DEBUG_INFO("Error opening TransactionRelatedQueue file");
|
|
|
- return FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- if( fgets (str, 1200, fp)!=NULL ) {
|
|
|
- /* writing content to stdout */
|
|
|
- //DEBUG_INFO("str=%s",str);
|
|
|
- if ((str[0] == '\n')||(strcmp(str,"")==0))
|
|
|
- {
|
|
|
- DEBUG_INFO("It is a blank line");
|
|
|
- fclose(fp);
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
- sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/TransactionRelatedQueue");
|
|
|
- system(rmFileCmd);
|
|
|
- result = FALSE;
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //puts(str);
|
|
|
- //----------------uuid--------------//
|
|
|
- loc = strstr(str, "\"");
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- c = 0;
|
|
|
- while (loc[1+c] != '\"')
|
|
|
- {
|
|
|
- sstr[c] = loc[1+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
-
|
|
|
- //DEBUG_INFO("\n uuid:%s", sstr);
|
|
|
- //DEBUG_INFO("\n data:%s", str);
|
|
|
- strcpy(uuid,sstr);
|
|
|
- strcpy(data,str);
|
|
|
- result = TRUE;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("queue is null\n");
|
|
|
- strcpy(uuid,"");
|
|
|
- strcpy(data,"");
|
|
|
- result = FALSE;
|
|
|
- }
|
|
|
- fclose(fp);
|
|
|
- return result;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-//---------------- addq(): add the item to the end of queue ----------------//
|
|
|
-int addq(char *uuid, char *data)
|
|
|
- {
|
|
|
- FILE *outfile;
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
- DEBUG_INFO("addq ");
|
|
|
- // Check for directory existence
|
|
|
- if (S_ISDIR(stats.st_mode) == 1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
-
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
- FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
-
|
|
|
- if(log == NULL)
|
|
|
- {
|
|
|
- //DEBUG_INFO("Can't Create File TransactionRelatedQueue \n");
|
|
|
- return FALSE;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- fclose(log);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // open file for writing
|
|
|
- outfile = fopen ("/Storage/OCPP/TransactionRelatedQueue", "a");
|
|
|
- DEBUG_INFO("data = %s\n",data);
|
|
|
- fputs(data, outfile);
|
|
|
- fputs("\n", outfile);
|
|
|
- fclose (outfile);
|
|
|
- TransactionQueueNum = TransactionQueueNum + 1;
|
|
|
- if(OfflineTransaction == 1) // 0: no offline Transaction 1: offline Transaction
|
|
|
- {
|
|
|
- OfflineTransactionQueueNum = OfflineTransactionQueueNum + 1;
|
|
|
- }
|
|
|
- DEBUG_INFO("add queue end\n");
|
|
|
- return FALSE;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-//---------------- delq(): delete the top item --------------//
|
|
|
-int delq()
|
|
|
-{
|
|
|
- char tempfile[] = "/Storage/OCPP/delqtemp.json";
|
|
|
- FILE *infile;
|
|
|
- FILE *outfile;
|
|
|
- int resultRename=0;
|
|
|
- char filename[60]={0};
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
-
|
|
|
- DEBUG_INFO("delq()\n");
|
|
|
- // Check for directory existence
|
|
|
- if (S_ISDIR(stats.st_mode) == 1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
-
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
- FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
-
|
|
|
- if(log == NULL)
|
|
|
- {
|
|
|
- //DEBUG_INFO("log is NULL\n");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- fclose(log);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // open file for writing
|
|
|
- strcpy(filename, "/Storage/OCPP/TransactionRelatedQueue");
|
|
|
- infile = fopen ("/Storage/OCPP/TransactionRelatedQueue", "r");
|
|
|
- outfile = fopen (tempfile, "w");
|
|
|
-
|
|
|
- /*检测到文件结束标识返回1,否则返回0。*/
|
|
|
- //DEBUG_INFO("feof(infile) =%d\n",feof(infile));
|
|
|
- int c;
|
|
|
- c = fgetc(infile);
|
|
|
- //printf("file c:%d\n",c);
|
|
|
- rewind(infile);
|
|
|
-
|
|
|
- if(c == EOF)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue is NULL\n");
|
|
|
-
|
|
|
- fclose(infile);
|
|
|
- fclose(outfile);
|
|
|
-
|
|
|
- sprintf(rmFileCmd,"rm -f %s",tempfile);
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- char buf[1200]={0};
|
|
|
-
|
|
|
- int i = 0;
|
|
|
- //DEBUG_INFO("Orignal File is not NULL\n");
|
|
|
- while (fgets(buf, sizeof(buf), infile) != NULL)
|
|
|
- {
|
|
|
- //printf("Orignal File get strings \n");
|
|
|
- buf[strlen(buf) - 1] = '\0'; // eat the newline fgets() stores
|
|
|
-
|
|
|
- if(i==0)
|
|
|
- {
|
|
|
- TransactionQueueNum = TransactionQueueNum - 1;
|
|
|
- TransactionQueueInterval = 0;
|
|
|
- TransactionMessageResend = 1;
|
|
|
- DEBUG_INFO("delete the item\n");
|
|
|
- }
|
|
|
-
|
|
|
- if(i != 0)
|
|
|
- {
|
|
|
- fprintf(outfile,"%s\n", buf);
|
|
|
- }
|
|
|
-
|
|
|
- i = i + 1;
|
|
|
- }
|
|
|
-
|
|
|
- fclose(infile);
|
|
|
- fclose(outfile);
|
|
|
-
|
|
|
- sprintf(rmFileCmd,"rm -f %s",filename);
|
|
|
- system(rmFileCmd);
|
|
|
-
|
|
|
- resultRename = rename(tempfile, filename);
|
|
|
-
|
|
|
-
|
|
|
- if(resultRename == 0)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue file renamed successfully");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("Error: unable to rename the TransactionRelatedQueue file");
|
|
|
- }
|
|
|
-
|
|
|
- DEBUG_INFO("delq() end\n");
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int showqueue()
|
|
|
-{
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
-
|
|
|
- // Check for directory existence
|
|
|
- if (S_ISDIR(stats.st_mode) == 1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
-
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
- FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
-
|
|
|
- if(log == NULL)
|
|
|
- {
|
|
|
- DEBUG_INFO("log is NULL\n");
|
|
|
- return FALSE;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- fclose(log);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- FILE *fp = fopen("/Storage/OCPP/TransactionRelatedQueue", "r");
|
|
|
- char line[1200]={0};
|
|
|
- // check if file exist (and you can open it) or not
|
|
|
- if (fp == NULL) {
|
|
|
- DEBUG_INFO("can open file TransactionRelatedQueue!");
|
|
|
- return FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- TransactionQueueNum = 0; // the number of packets in queue
|
|
|
-
|
|
|
- while(fgets(line, sizeof line, fp) != NULL) {
|
|
|
- //DEBUG_INFO("%s\n", line);
|
|
|
- TransactionQueueNum = TransactionQueueNum + 1; //the number of packets in queue
|
|
|
- }
|
|
|
-
|
|
|
- fclose(fp);
|
|
|
- return TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-int sentqueue(){
|
|
|
-FILE *fp;
|
|
|
-int result = FALSE; // 1: TRUE 0:FALSE
|
|
|
-int temptransactionId = 0, gettransactionId = 0;
|
|
|
-int tempconnectorId = 0;
|
|
|
-//int gunIndex = 0;
|
|
|
-char guid[37]={0};
|
|
|
-char tempdata[65]={0};
|
|
|
-char key_value[65]={0};
|
|
|
-int IsStopTransaction = FALSE;
|
|
|
-//int IsconnectorIdNULL = FALSE;
|
|
|
-//int IsIdtagNULL = FALSE;
|
|
|
-char str[1200]={0};
|
|
|
-char strcomposite[1200]={0};
|
|
|
-char rmFileCmd[100]={0};
|
|
|
-char connectorStr[2]={0};
|
|
|
-struct stat stats;
|
|
|
-char sstr[28]={0};
|
|
|
-unsigned char IdtagStr[20]={0};
|
|
|
-unsigned char timestampStr[30]={0};
|
|
|
-int tempmeterStart = 0;
|
|
|
-int tempreservationId = 0;
|
|
|
-int c = 0;
|
|
|
-char *loc;
|
|
|
-
|
|
|
-DEBUG_INFO("sentqueue\n");
|
|
|
-stat("/Storage/OCPP", &stats);
|
|
|
-
|
|
|
-// Check for directory existence
|
|
|
-if (S_ISDIR(stats.st_mode) == 1)
|
|
|
-{
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
-}
|
|
|
-else
|
|
|
-{
|
|
|
- //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
-}
|
|
|
-
|
|
|
-memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
-/* opening file for reading */
|
|
|
-fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
|
|
|
-if(fp == NULL) {
|
|
|
- DEBUG_INFO("Error opening file");
|
|
|
- return FALSE;
|
|
|
-}
|
|
|
-
|
|
|
-if( fgets (str, 1200, fp)!=NULL ) {
|
|
|
-
|
|
|
- //---- writing content to stdout ---//
|
|
|
-
|
|
|
- //*********************Start: StopTransaction***************************/
|
|
|
- loc = strstr(str, "StopTransaction");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- IsStopTransaction = TRUE;
|
|
|
- }
|
|
|
-
|
|
|
- memset(connectorStr,0,sizeof(connectorStr));
|
|
|
- strncpy(connectorStr, str, 1);
|
|
|
- tempconnectorId = atoi(connectorStr);
|
|
|
-
|
|
|
- //*********************End: StopTransaction***************************/
|
|
|
-
|
|
|
-#if 0
|
|
|
- //*********************Start:connectorId***************************/
|
|
|
- loc = strstr(str, "connectorId");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- while (loc[strlen("connectorId")+2+c] != ',')
|
|
|
- {
|
|
|
- sstr[c] = loc[strlen("connectorId")+2+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- tempconnectorId = atoi(sstr);
|
|
|
- }
|
|
|
-// else
|
|
|
-// {
|
|
|
-// IsconnectorIdNULL = TRUE;
|
|
|
-// }
|
|
|
- //*********************End:connectorId***************************/
|
|
|
-#endif
|
|
|
-
|
|
|
- //*********************Start:idTag***************************/
|
|
|
- loc = strstr(str, "idTag");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- while (loc[3+strlen("idTag")+c] != '\"')
|
|
|
- {
|
|
|
- sstr[c] = loc[3+strlen("idTag")+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- strcpy((char*)IdtagStr, sstr);
|
|
|
- }
|
|
|
-// else
|
|
|
-// {
|
|
|
-// IsIdtagNULL = TRUE;
|
|
|
-// }
|
|
|
- //*********************End:idTag***************************/
|
|
|
-
|
|
|
-
|
|
|
- //*********************Start: StartTransaction***************************/
|
|
|
- loc = strstr(str, "StartTransaction");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- // [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
|
|
|
- //DEBUG_INFO("\n sent queue StartTransaction\n");
|
|
|
- if(tempconnectorId > 0)
|
|
|
- {
|
|
|
- sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
|
|
|
- }
|
|
|
-
|
|
|
- //GUID
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- c=0;
|
|
|
- while (str[6+c] != '\"')
|
|
|
- {
|
|
|
- sstr[c] = str[6+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- strcpy(guid, sstr);
|
|
|
-
|
|
|
-
|
|
|
- //Idtag
|
|
|
- loc = strstr(str, "idTag");
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- c=0;
|
|
|
- while (loc[3+strlen("idTag")+c] != '\"')
|
|
|
- {
|
|
|
- sstr[c] = loc[3+strlen("idTag")+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- strcpy((char*)IdtagStr, sstr);
|
|
|
-
|
|
|
- //meterStart
|
|
|
- loc = strstr(str, "meterStart");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- while (loc[strlen("meterStart")+2+c] != ',')
|
|
|
- {
|
|
|
- sstr[c] = loc[strlen("meterStart")+2+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- tempmeterStart = atoi(sstr);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //reservationId
|
|
|
- loc = strstr(str, "reservationId");
|
|
|
- c = 0;
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
- while (loc[strlen("reservationId")+2+c] != ',')
|
|
|
- {
|
|
|
- sstr[c] = loc[strlen("reservationId")+2+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- tempreservationId = atoi(sstr);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //timestamp
|
|
|
- loc = strstr(str, "timestamp");
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- c=0;
|
|
|
- while (loc[3+strlen("timestamp")+c] != '\"')
|
|
|
- {
|
|
|
- sstr[c] = loc[3+strlen("timestamp")+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
- sstr[c] = '\0';
|
|
|
- strcpy((char*)timestampStr, sstr);
|
|
|
-
|
|
|
-
|
|
|
- if(hashmap_operation(1, guid, key_value) == TRUE)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- hashmap_operation(0, guid, tempdata);
|
|
|
- FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
|
|
|
- //DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
|
|
|
- }
|
|
|
- }
|
|
|
- //*********************End: StartTransaction***************************/
|
|
|
-
|
|
|
-
|
|
|
- //****************transactionId********************/
|
|
|
- c=0;
|
|
|
- loc = strstr(str, "transactionId");
|
|
|
- memset(sstr ,0, sizeof(sstr) );
|
|
|
- if(loc != NULL)
|
|
|
- {
|
|
|
-
|
|
|
- while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
|
|
|
- {
|
|
|
- sstr[c] = loc[strlen("transactionId")+2+c];
|
|
|
- c++;
|
|
|
- }
|
|
|
-
|
|
|
- sstr[c] = '\0';
|
|
|
- temptransactionId = atoi(sstr);
|
|
|
-
|
|
|
- //gettransactionId = GetTransactionId(tempconnectorId, IdtagStr);
|
|
|
-
|
|
|
- //From StartTransaction取得IdTag, 存到 StartTransactionIdTagTemp,主要是 給Queue中StopTransaction使用(StartTransaction. StopTransaction不同卡號 ),取得真正的TransactionId
|
|
|
- GetStartTransactionIdTag(tempconnectorId-1);
|
|
|
- DEBUG_INFO("\n StartTransactionIdTagTemp=%s",StartTransactionIdTagTemp);
|
|
|
- gettransactionId = GetTransactionId(tempconnectorId, StartTransactionIdTagTemp);
|
|
|
- DEBUG_INFO("\n gettransactionId=%d",gettransactionId);
|
|
|
- if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
|
|
|
- {
|
|
|
- //replace transactionId of metervalue or stopTransaction
|
|
|
- strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
|
|
|
- sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
|
|
|
- strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
|
|
|
- LWS_Send(strcomposite+2); // skip 2 bytes字串-> 槍號,
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- LWS_Send(str+2); // skip 2 bytes字串-> 槍號,
|
|
|
- gettransactionId=temptransactionId;
|
|
|
- }
|
|
|
-
|
|
|
- if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
|
|
|
- {
|
|
|
- SetTransactionIdZero(gettransactionId);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- LWS_Send(str+2);
|
|
|
- }
|
|
|
-
|
|
|
- result = TRUE;
|
|
|
-}
|
|
|
-else
|
|
|
-{
|
|
|
- result = FALSE;
|
|
|
-}
|
|
|
-fclose(fp);
|
|
|
-return result;
|
|
|
-}
|
|
|
-
|
|
|
-void* processTransactionQueue(void* data)
|
|
|
-{
|
|
|
- char frontUUID[100] ={0};
|
|
|
- char frontData[1200/*1024*4*/] ={0};
|
|
|
- int queueNotEmpty = FALSE;
|
|
|
-
|
|
|
- while(1)
|
|
|
- {
|
|
|
- if(FirstHeartBeatResponse() == 1)
|
|
|
- {
|
|
|
- memset(frontUUID, 0, sizeof(frontUUID));
|
|
|
- memset(frontData, 0, sizeof(frontData));
|
|
|
- queueNotEmpty = FALSE;
|
|
|
-
|
|
|
- queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally
|
|
|
-
|
|
|
- if((queueNotEmpty == TRUE) && (GetOcppConnStatus() == 1)) //OcppConnStatus 0: disconnected, 1: connected
|
|
|
- {
|
|
|
- if((OfflineTransaction == 1) && (OfflineTransactionQueueNum != 0)) //OfflineTransaction 0: no offline Transaction 1: offline Transaction
|
|
|
- {
|
|
|
- TransactionQueueInterval = 2;//10;//2;
|
|
|
- sendbuffer = 1; // 0: no packets to send 1: send the top packet in queue
|
|
|
- OfflineTransactionQueueNum = OfflineTransactionQueueNum - 1;
|
|
|
-
|
|
|
- if(OfflineTransactionQueueNum == 0)
|
|
|
- {
|
|
|
- OfflineTransaction = 0;
|
|
|
-
|
|
|
- }
|
|
|
- sleep(TransactionQueueInterval);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if(TransactionMessageResend <= TransactionMessageAttemptsGet()) //
|
|
|
- {
|
|
|
- DEBUG_INFO("processTransactionQueue queue is not empty!\n");
|
|
|
- TransactionQueueInterval= TransactionMessageRetryIntervalGet()* TransactionMessageResend;
|
|
|
- DEBUG_INFO("TransactionQueueInterval =%d\n",TransactionQueueInterval);
|
|
|
- sleep(TransactionQueueInterval);
|
|
|
- sendbuffer = 1;
|
|
|
- TransactionMessageResend = TransactionMessageResend + 1;
|
|
|
- DEBUG_INFO("After ADD,TransactionMessageResend=%d\n",TransactionMessageResend);
|
|
|
- //sleep(TransactionQueueInterval);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- queue_operation(QUEUE_OPERATION_DEL,"",""); //// delete item
|
|
|
- TransactionQueueInterval = 0;
|
|
|
- TransactionMessageResend = 1;
|
|
|
- sleep(TransactionQueueInterval);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- TransactionQueueInterval = 0;//10;
|
|
|
- sleep(TransactionQueueInterval);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(GetOcppConnStatus() == 0)
|
|
|
- {
|
|
|
- if(queueNotEmpty == TRUE)
|
|
|
- {
|
|
|
- OfflineTransaction = 1; // 0: no offline Transaction 1: offline Transaction
|
|
|
- }
|
|
|
- }
|
|
|
- usleep(5000);
|
|
|
- }
|
|
|
-
|
|
|
- pthread_exit(NULL); //
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-void CheckTransactionPacket(char *uuid)
|
|
|
-{
|
|
|
- char frontUUID[100]={0};
|
|
|
- char frontData[1200]={0};
|
|
|
- int queueNotEmpty = FALSE;
|
|
|
- int cmpResult = 0;
|
|
|
-
|
|
|
- queueNotEmpty = queue_operation(1,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally
|
|
|
- if(queueNotEmpty == TRUE)
|
|
|
- {
|
|
|
- cmpResult = strcmp(frontUUID, uuid);
|
|
|
-
|
|
|
- if (cmpResult == 0)
|
|
|
- {
|
|
|
- DEBUG_INFO("TransactionPacket Compare All right!\n");
|
|
|
- queue_operation(2,"","");//delq(); ---> remove temporally
|
|
|
- TransactionQueueInterval = 0;
|
|
|
- TransactionMessageResend = 1;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int queue_operation(int type, char *frontUUID, char *frontData)
|
|
|
-{
|
|
|
- int result=0;
|
|
|
- while(1)
|
|
|
- {
|
|
|
- if (!IsUsing )
|
|
|
- {
|
|
|
- IsUsing = TRUE;
|
|
|
- //pthread_mutex_unlock(&lock_sentData);
|
|
|
- //pthread_mutex_lock(&lock_sentData);
|
|
|
-
|
|
|
- if(type == QUEUE_OPERATION_SHOWQUEUE) // show items in queue
|
|
|
- {
|
|
|
- result = showqueue();
|
|
|
- }
|
|
|
- else if(type == QUEUE_OPERATION_SHOWFRONT) // show first item
|
|
|
- {
|
|
|
- result = showfront(frontUUID, frontData);
|
|
|
- }
|
|
|
- else if(type == QUEUE_OPERATION_DEL) // delete item
|
|
|
- {
|
|
|
- result = delq();
|
|
|
- }
|
|
|
- else if(type == QUEUE_OPERATION_SENT) // sent items in queue
|
|
|
- {
|
|
|
- result = sentqueue();
|
|
|
- }
|
|
|
- else if(type == QUEUE_OPERATION_ADD) // add items to the queue
|
|
|
- {
|
|
|
- result = addq(frontUUID, frontData);
|
|
|
- }
|
|
|
-
|
|
|
- //pthread_mutex_unlock(&lock_sentData);
|
|
|
- IsUsing = FALSE;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-int removeMessageSentFile(void)
|
|
|
-{
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
-
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
- // Check for directory existence
|
|
|
- if(S_ISDIR(stats.st_mode) == 1)
|
|
|
- {
|
|
|
- //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO("\n directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
-
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
- if((access("/Storage/OCPP/MessageSent",F_OK))!=-1)
|
|
|
- {
|
|
|
- DEBUG_INFO("MessageSent file exist.\n");
|
|
|
- sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/MessageSent");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int changeChageWebSocketPingInterval = FALSE;
|
|
|
-void ChageWebSocketPingInterval(int WebSocketPingInterval)
|
|
|
-{
|
|
|
- changeChageWebSocketPingInterval = TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-//================================================
|
|
|
-// Main process
|
|
|
-//================================================
|
|
|
-int main(void)
|
|
|
-{
|
|
|
- char rmFileCmd[100]={0};
|
|
|
- struct stat stats;
|
|
|
- pthread_t t_ProcQueue;
|
|
|
- DEBUG_INFO("Module_OcppBackend task initialization...\n");
|
|
|
-
|
|
|
- if(ProcessShareMemory()== FAIL)
|
|
|
- {
|
|
|
- return FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- // Check & create OCPP dir
|
|
|
- stat("/Storage/OCPP", &stats);
|
|
|
- if(S_ISDIR(stats.st_mode) != 1)
|
|
|
- {
|
|
|
- DEBUG_INFO("OCPP directory not exist, create dir \n");
|
|
|
- sprintf(rmFileCmd,"mkdir -p /Storage/OCPP");
|
|
|
- system(rmFileCmd);
|
|
|
- }
|
|
|
- memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
-
|
|
|
- //Create Process: Resend Transaction
|
|
|
- pthread_create(&t_ProcQueue, NULL, processTransactionQueue, NULL);
|
|
|
- sqlite3_config(SQLITE_CONFIG_URI,1);
|
|
|
- if(sqlite3_open("file:/Storage/OCPP/charger.db", &db))
|
|
|
- {
|
|
|
- DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
|
|
|
- sqlite3_close( db );
|
|
|
- exit(0);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO( "Opened database successfully\n");
|
|
|
- }
|
|
|
-
|
|
|
- //Create Table log buffer
|
|
|
- if(sqlite3_exec(db, createsql, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
- {
|
|
|
- DEBUG_INFO( "Create log buffer table error message: %s\n", errMsg);
|
|
|
-
|
|
|
- return 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO( "Opened log buffer table successfully\n");
|
|
|
- }
|
|
|
-
|
|
|
- // Create Table OcppAuthCache
|
|
|
- if(sqlite3_exec(db, sqlOcppAuthCache, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
- {
|
|
|
- DEBUG_INFO( "Create OcppAuthCache error message: %s\n", errMsg);
|
|
|
-
|
|
|
- return 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO( "Opened OcppAuthCache table successfully\n");
|
|
|
- }
|
|
|
-
|
|
|
- // Create Table OcppAuthLocal
|
|
|
- if(sqlite3_exec(db, sqlOcppAuthLocal, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
- {
|
|
|
- DEBUG_INFO( "Create Table OcppAuthLocal error %s\n",errMsg);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DEBUG_INFO( "Opened OcppAuthLocal table successfully\n");
|
|
|
- }
|
|
|
-
|
|
|
- initialConfigurationTable();
|
|
|
- removeMessageSentFile();
|
|
|
-
|
|
|
- for(;;)
|
|
|
- {
|
|
|
- // Connect server
|
|
|
- while(ConnectionEstablished==0) // Check InternetConn 0: disconnected, 1: connected
|
|
|
- {
|
|
|
- SetOcppConnStatus(FALSE);
|
|
|
- SetServerSign(FALSE);
|
|
|
- InitialSystemValue();
|
|
|
- if((time((time_t*)NULL)-startTime.connect) >= 30)
|
|
|
- {
|
|
|
- DEBUG_INFO("Server connecting...\n");
|
|
|
- pthread_create(&pid, NULL, ConnectWsServer, NULL);
|
|
|
- startTime.connect=time((time_t*)NULL);
|
|
|
- }
|
|
|
- CheckSystemValue();
|
|
|
- sleep(5);
|
|
|
- lws_service(context, 10000);//timeout_ms
|
|
|
- }
|
|
|
-
|
|
|
- // Sign in
|
|
|
- if( ((GetBootNotificationInterval() != 0 && ((time((time_t*)NULL)-startTime.bootNotification)>= GetBootNotificationInterval()) ) ||
|
|
|
- ((time((time_t*)NULL)-startTime.bootNotification) >= defaultWaitingTime) ) && (GetServerSign() == FALSE))
|
|
|
- {
|
|
|
- sendBootNotificationRequest();
|
|
|
- startTime.bootNotification=time((time_t*)NULL);
|
|
|
- }
|
|
|
-
|
|
|
- // On line operation
|
|
|
- if(GetServerSign() == TRUE)
|
|
|
- {
|
|
|
- if(sendbuffer == 1)
|
|
|
- {
|
|
|
- queue_operation(QUEUE_OPERATION_SENT, "", "");
|
|
|
- sendbuffer = 0;
|
|
|
- }
|
|
|
-
|
|
|
- SetOcppConnStatus(TRUE);
|
|
|
- // Check System Value
|
|
|
- CheckSystemValue();
|
|
|
- if(GetHeartBeatWithNOResponse() >= 3)
|
|
|
- {
|
|
|
- lws_context_destroy(context);
|
|
|
- ConnectionEstablished=0;
|
|
|
- context = NULL;
|
|
|
- SetHeartBeatWithNOResponse();
|
|
|
- }
|
|
|
-
|
|
|
- if((changeChageWebSocketPingInterval == TRUE) || (GetInternetConn() == 0))
|
|
|
- {
|
|
|
- DEBUG_INFO("GetInternetConn() = %d\n", GetInternetConn());
|
|
|
- changeChageWebSocketPingInterval = FALSE;
|
|
|
- lws_context_destroy(context);
|
|
|
- ConnectionEstablished=0;
|
|
|
- context = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
- lws_service(context, 100);//timeout_ms
|
|
|
- }
|
|
|
- pthread_join(t_ProcQueue, NULL);
|
|
|
-
|
|
|
- return FAIL;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
+#include "Module_OcppBackend.h"
|
|
|
+
|
|
|
+typedef enum boolean { FALSE, TRUE } BOOL;
|
|
|
+
|
|
|
+struct lws *wsi_client;
|
|
|
+struct lws_context *context;
|
|
|
+static int sendbuffer = 0;
|
|
|
+pthread_t pid;
|
|
|
+
|
|
|
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
|
|
|
+pthread_mutex_t lock_sentData = PTHREAD_MUTEX_INITIALIZER;
|
|
|
+pthread_mutex_t receiveData = PTHREAD_MUTEX_INITIALIZER;
|
|
|
+
|
|
|
+//==========================================
|
|
|
+// Function prototype
|
|
|
+//==========================================
|
|
|
+void ReceivedMessage(void *in, size_t len);
|
|
|
+
|
|
|
+struct StartTime
|
|
|
+{
|
|
|
+ unsigned int connect;
|
|
|
+ unsigned int bootNotification;
|
|
|
+}startTime;
|
|
|
+
|
|
|
+int SendBufLen=(1024*4);//(1024*3);
|
|
|
+unsigned char SendBuffer[1024*4]={0};
|
|
|
+static int ConnectionEstablished=0;
|
|
|
+static int TransactionMessageResend = 1; // the number of retry to submit a transaction-related message when the Central System fails to process it.
|
|
|
+static int TransactionQueueInterval = 10;//3;
|
|
|
+static int TransactionQueueNum = 0;
|
|
|
+static int OfflineTransactionQueueNum = 0; // Number of offline transactions
|
|
|
+static int OfflineTransaction = 0;
|
|
|
+static int IsUsing = FALSE;
|
|
|
+int defaultWaitingTime = 10; //10 second
|
|
|
+
|
|
|
+char OcppPath[160]={0};
|
|
|
+char OcppProtocol[10]={0},OcppHost[50]={0}, OcppTempPath[50]={0};
|
|
|
+int OcppPort=0;
|
|
|
+unsigned char StartTransactionIdTagTemp[20]={0};
|
|
|
+
|
|
|
+sqlite3 *db;
|
|
|
+char *errMsg = NULL;
|
|
|
+static char *createsql = "CREATE TABLE IF NOT EXISTS log_buffer("
|
|
|
+ "idx integer primary key,"
|
|
|
+ "user_id text,"
|
|
|
+ "cmd_sn text,"
|
|
|
+ "charger_id text,"
|
|
|
+ "gun_type text,"
|
|
|
+ "gun_no text,"
|
|
|
+ "rfid_no text,"
|
|
|
+ "stime text,"
|
|
|
+ "etime text,"
|
|
|
+ "time_len text,"
|
|
|
+ "s_soc text,"
|
|
|
+ "e_soc text,"
|
|
|
+ "stop_reason text,"
|
|
|
+ "power text,"
|
|
|
+ "meter_before text,"
|
|
|
+ "meter_after text,"
|
|
|
+ "charge_price text,"
|
|
|
+ "reserve text,"
|
|
|
+ "surplus_before text,"
|
|
|
+ "surplus_after text,"
|
|
|
+ "service_price text,"
|
|
|
+ "is_pay text,"
|
|
|
+ "charge_strategy text,"
|
|
|
+ "charge_parameter text,"
|
|
|
+ "vin text,"
|
|
|
+ "vehicle_no text,"
|
|
|
+ "start_method text,"
|
|
|
+ "card_type text,"
|
|
|
+ "is_upload text,"
|
|
|
+ "guid text UNIQUE,"
|
|
|
+ "is_buf2OK text);";
|
|
|
+
|
|
|
+static char *sqlOcppAuthCache = "create table if not exists ocpp_auth_cache (idx integer primary key,"
|
|
|
+ "idtag text UNIQUE,"
|
|
|
+ "parent_idtag text,"
|
|
|
+ "expir_date text,"
|
|
|
+ "status text);";
|
|
|
+
|
|
|
+static char *sqlOcppAuthLocal = "create table if not exists ocpp_auth_local (idx integer primary key,"
|
|
|
+ "idtag text UNIQUE,"
|
|
|
+ "parent_idtag text,"
|
|
|
+ "expir_date text,"
|
|
|
+ "status text,"
|
|
|
+ "version text);";
|
|
|
+//=================================
|
|
|
+// Common routine
|
|
|
+//=================================
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+void trim(char *s)
|
|
|
+{
|
|
|
+ int i=0, j, k, l=0;
|
|
|
+
|
|
|
+ while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
|
|
|
+ i++;
|
|
|
+
|
|
|
+ j = strlen(s)-1;
|
|
|
+ while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
|
|
|
+ j--;
|
|
|
+
|
|
|
+ if(i==0 && j==strlen(s)-1) { }
|
|
|
+ else if(i==0) s[j+1] = '\0';
|
|
|
+ else {
|
|
|
+ for(k=i; k<=j; k++) s[l++] = s[k];
|
|
|
+ s[l] = '\0';
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int mystrcmp(char *p1,char *p2)
|
|
|
+{
|
|
|
+ while(*p1==*p2)
|
|
|
+ {
|
|
|
+ if(*p1=='\0' || *p2=='\0')
|
|
|
+ break;
|
|
|
+ p1++;
|
|
|
+ p2++;
|
|
|
+ }
|
|
|
+ if(*p1=='\0' && *p2=='\0')
|
|
|
+ return(PASS);
|
|
|
+ else
|
|
|
+ return(FAIL);
|
|
|
+}
|
|
|
+
|
|
|
+void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
|
|
|
+{
|
|
|
+ strncpy(dest, src + start, cnt);
|
|
|
+ dest[cnt] = 0;
|
|
|
+}
|
|
|
+
|
|
|
+int strposs(char *source, char *substr, int idx)
|
|
|
+{
|
|
|
+ char stack[strlen(source)];
|
|
|
+ int result=0;
|
|
|
+ int count=0;
|
|
|
+
|
|
|
+ while(count<=idx)
|
|
|
+ {
|
|
|
+ memset(stack,0,sizeof stack);
|
|
|
+ strncpy(stack, source+result, strlen(source)-result);
|
|
|
+
|
|
|
+ int loc = strcspn(stack, substr);
|
|
|
+
|
|
|
+ if(loc>0)
|
|
|
+ result += (loc+1);
|
|
|
+ else
|
|
|
+ result = -1;
|
|
|
+
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void getSubStr(char *dest, char* src, char *split, int idx)
|
|
|
+{
|
|
|
+
|
|
|
+ int start = (strposs(src,",",idx)+1);
|
|
|
+ int cnt = (strposs(src,",",idx+1)-2)-(strposs(src,",",idx)+1);
|
|
|
+
|
|
|
+ strncpy(dest, src + start, cnt);
|
|
|
+ dest[cnt] = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void split(char **arr, char *str, const char *del)
|
|
|
+{
|
|
|
+ char *s = strtok(str, del);
|
|
|
+
|
|
|
+ while(s != NULL)
|
|
|
+ {
|
|
|
+ *arr++ = s;
|
|
|
+ s = strtok(NULL, del);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int strpos(char *source, char *substr, int skip)
|
|
|
+{
|
|
|
+ char stack[strlen(source)];
|
|
|
+ strncpy(stack, source+skip, strlen(source)-skip);
|
|
|
+ char *p = strstr(stack, substr);
|
|
|
+ if (p)
|
|
|
+ return p - stack+skip;
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+char * strtrim( char * s )
|
|
|
+{
|
|
|
+ char * p1 = s;
|
|
|
+ char * p2 = s;
|
|
|
+ while(*p1 != '\0')
|
|
|
+ {
|
|
|
+ while(*p1 == '\t' || *p1 == '\n' || *p1 == '\r') //while(*p1 == ' ' || *p1 == '\t' || *p1 == '\n' || *p1 == '\r')
|
|
|
+ {
|
|
|
+ p1 ++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ * p2 ++ = *p1 ++;
|
|
|
+ //printf("p2=%s\n",p2);
|
|
|
+ }
|
|
|
+ *p2 = '\0';
|
|
|
+ return (s);
|
|
|
+}
|
|
|
+
|
|
|
+char *random_uuid(char* buf)
|
|
|
+{
|
|
|
+ uuid_t uuid;
|
|
|
+
|
|
|
+ uuid_generate(uuid);
|
|
|
+ uuid_unparse(uuid, buf);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int GetTransactionQueueNum(void)
|
|
|
+{
|
|
|
+ return TransactionQueueNum;
|
|
|
+}
|
|
|
+
|
|
|
+//==========================================
|
|
|
+// Web socket tranceive routine
|
|
|
+//==========================================
|
|
|
+int SendData(struct lws *wsi)
|
|
|
+{
|
|
|
+ int n;
|
|
|
+ int len;
|
|
|
+ unsigned char out[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING] = {0};
|
|
|
+
|
|
|
+ len = strlen((char *)SendBuffer);
|
|
|
+
|
|
|
+ if(len == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, SendBuffer, len );
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("===========> %s\n", out + LWS_SEND_BUFFER_PRE_PADDING);
|
|
|
+
|
|
|
+ n = lws_write(wsi, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
|
|
|
+ memset(SendBuffer, 0, len);
|
|
|
+
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+static int OCPP16Callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
|
|
+{
|
|
|
+ switch (reason)
|
|
|
+ {
|
|
|
+ case LWS_CALLBACK_PROTOCOL_INIT:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_PROTOCOL_INIT\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH\n");
|
|
|
+
|
|
|
+ char buf[64];
|
|
|
+ char hash[20], key_b64[40];
|
|
|
+
|
|
|
+ lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64));// Sec-WebSocket-Key
|
|
|
+
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request START -----\n");
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_URI);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
|
|
|
+
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b64);
|
|
|
+
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("----- Handshake: Client Request END -----\n");
|
|
|
+
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response START -----\n");
|
|
|
+
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_HTTP);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_UPGRADE);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_CONNECTION);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_ACCEPT);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_PROTOCOL);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("----- Handshake: Server response END -----\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LWS_CALLBACK_WSI_DESTROY:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_WSI_DESTROY\n");
|
|
|
+ pthread_detach(pid);
|
|
|
+ SetServerSign(FALSE);
|
|
|
+ ConnectionEstablished = 0;
|
|
|
+ context = NULL;
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_LOCK_POLL:
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_ADD_POLL_FD:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_ADD_POLL_FD\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_DEL_POLL_FD:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_DEL_POLL_FD\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_UNLOCK_POLL:
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CHANGE_MODE_POLL_FD:
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_WSI_CREATE:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_WSI_CREATE\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_GET_THREAD_ID:
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_ESTABLISHED: //3
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_CLIENT_ESTABLISHED\n");
|
|
|
+
|
|
|
+ char frontUUID[100] ={0};
|
|
|
+ char frontData[1200] ={0};
|
|
|
+ int queueNotEmpty = FALSE;
|
|
|
+
|
|
|
+ //connected
|
|
|
+ ConnectionEstablished=1;
|
|
|
+
|
|
|
+ queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);
|
|
|
+
|
|
|
+ if(queueNotEmpty == TRUE)
|
|
|
+ {
|
|
|
+ OfflineTransaction = 1; // 0: no packets in queue. 1: There are packets in queue.
|
|
|
+ }
|
|
|
+
|
|
|
+ TransactionQueueInterval = 0;
|
|
|
+ TransactionMessageResend = 1;
|
|
|
+
|
|
|
+ //get offline number
|
|
|
+ queue_operation(QUEUE_OPERATION_SHOWQUEUE,"","");
|
|
|
+ OfflineTransactionQueueNum =TransactionQueueNum ;
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_CONNECTION_ERROR://1
|
|
|
+ DEBUG_ERROR("LWS_CALLBACK_CLIENT_CONNECTION_ERROR %s\n", (char *)in );
|
|
|
+ //disconnected
|
|
|
+ ConnectionEstablished=0;
|
|
|
+
|
|
|
+ char buf1[64];
|
|
|
+ char hash1[20]={0}, key_b641[40]={0};
|
|
|
+
|
|
|
+ lws_b64_encode_string(hash1, 16, key_b641, sizeof(key_b641));// Sec-WebSocket-Key
|
|
|
+
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client START =====\n");
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_URI);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("GET %s HTTP/1.1 \n", buf);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_HOST);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Host: %s\n", buf);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Upgrade: websocket\n");
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Connection: Upgrade\n");
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Key: %s\n", key_b641);
|
|
|
+ lws_hdr_copy(wsi, buf, sizeof(buf) - 1, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Version: %d\n", SPEC_LATEST_SUPPORTED);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("===== Handshake: Client END =====\n");
|
|
|
+
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response START =====\n");
|
|
|
+ lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_HTTP);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("HTTP/1.1 %s\n", buf1);
|
|
|
+ lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_UPGRADE);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Upgrade: %s\n", buf1);
|
|
|
+ lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_CONNECTION);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Connection: %s\n", buf1);
|
|
|
+ lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_ACCEPT);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Accept: %s\n", buf1);
|
|
|
+ lws_hdr_copy(wsi, buf1, sizeof(buf1) - 1, WSI_TOKEN_PROTOCOL);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("Sec-WebSocket-Protocol: %s\n", buf1);
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("===== Handshake: Server response END =====\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLOSED://4
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_CLOSED\n");
|
|
|
+ //disconnected
|
|
|
+ ConnectionEstablished=0;
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_WRITEABLE://10
|
|
|
+ //if(need to send message and its relevant data already store into SendBuffer)
|
|
|
+ SendData(wsi);
|
|
|
+ //lws_rx_flow_control( wsi, 1 );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LWS_CALLBACK_CLIENT_RECEIVE://8
|
|
|
+ ((char *)in)[len] = '\0';
|
|
|
+ DEBUG_OCPPMESSAGE_INFO("<===== %s\n", (char *)in);
|
|
|
+
|
|
|
+ char tempin[65536]={0};
|
|
|
+
|
|
|
+ int c = 0;
|
|
|
+ char *loc;
|
|
|
+ char sstr[65536]={ 0 };
|
|
|
+
|
|
|
+ //**********Receive Message**********/
|
|
|
+ c = 0;
|
|
|
+ loc = strstr((const char *)in, "][2,");
|
|
|
+ if(loc == NULL)
|
|
|
+ {
|
|
|
+ loc = strstr((const char *)in, "][3,");
|
|
|
+
|
|
|
+ if(loc == NULL)
|
|
|
+ {
|
|
|
+ loc = strstr((const char *)in, "][4,");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("there are continuous second packet []\n");
|
|
|
+ while (loc[1+c] != '\0')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[1+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+
|
|
|
+ sstr[c] = '\0';
|
|
|
+ strcpy(tempin, sstr);
|
|
|
+ DEBUG_INFO("Final Receive: %s\n", tempin);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ strcpy(tempin,(char *)in);
|
|
|
+ }
|
|
|
+
|
|
|
+ ReceivedMessage((void *)strtrim(tempin), len);
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS\n");
|
|
|
+ break;
|
|
|
+ case LWS_CALLBACK_PROTOCOL_DESTROY:
|
|
|
+ DEBUG_INFO("LWS_CALLBACK_PROTOCOL_DESTROY\n");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ DEBUG_INFO("Reason = %d\n", reason);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct lws_protocols protocols[] =
|
|
|
+{
|
|
|
+ {
|
|
|
+ "ocpp1.6",
|
|
|
+ OCPP16Callback,
|
|
|
+ 10240,//65536,//10240,
|
|
|
+ 10240,//65536,//10240,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ocpp1.6",
|
|
|
+ OCPP16Callback,
|
|
|
+ 10240,//65536,//10240,
|
|
|
+ 10240,//65536,//10240,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ NULL, NULL, 0 /* End of list */
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+void* ConnectWsServer(void* data) //int ConnectWsServer()
|
|
|
+{
|
|
|
+
|
|
|
+ struct lws_context_creation_info ContextInfo;
|
|
|
+ struct lws_client_connect_info ConnInfo;
|
|
|
+ int use_ssl=0;
|
|
|
+
|
|
|
+ if(context!=NULL)
|
|
|
+ {
|
|
|
+ pthread_detach(pthread_self());
|
|
|
+ lws_context_destroy(context);
|
|
|
+ ConnectionEstablished=0;
|
|
|
+ context = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(&ContextInfo, 0, sizeof(struct lws_context_creation_info));
|
|
|
+ if((GetOcppServerURL()==0) || (GetOcppPort() == 0) || (GetOcppPath()==0))
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("OCPP URL is NULL or OCPP Port is zero or OCPP Path is NULL\n");
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ if((strcmp(OcppProtocol,"ws")==0)&&(strlen(OcppProtocol)== 2))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Web socket is non-security mode.\n");
|
|
|
+ use_ssl=0;
|
|
|
+ }
|
|
|
+ else if((strcmp(OcppProtocol,"wss")==0)&&(strlen(OcppProtocol)== 3))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Web socket is security mode.\n");
|
|
|
+ use_ssl=1;
|
|
|
+ }
|
|
|
+
|
|
|
+ ContextInfo.port = CONTEXT_PORT_NO_LISTEN;
|
|
|
+ ContextInfo.iface = NULL;
|
|
|
+ ContextInfo.ssl_private_key_password = NULL;
|
|
|
+ ContextInfo.ssl_cert_filepath = NULL;//"./ssl_key/client_cert.pem";
|
|
|
+ ContextInfo.ssl_private_key_filepath = NULL;//"./ssl_key/client_key.pem";
|
|
|
+ ContextInfo.ssl_ca_filepath = "/root/cacert.pem";//"./cacert.pem";
|
|
|
+ ContextInfo.ssl_cipher_list = NULL; //use default one
|
|
|
+ ContextInfo.gid = -1;
|
|
|
+ ContextInfo.uid = -1;
|
|
|
+ if(use_ssl)
|
|
|
+ {
|
|
|
+ ContextInfo.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT ;
|
|
|
+ }
|
|
|
+
|
|
|
+ ContextInfo.protocols = protocols;
|
|
|
+ ContextInfo.timeout_secs = GetWebSocketPingInterval();//WebSocketPingInterval;//30;//9999;//30;
|
|
|
+ ContextInfo.ws_ping_pong_interval = GetWebSocketPingInterval();//WebSocketPingInterval;//30;//0 for none, else interval in seconds
|
|
|
+ context = lws_create_context(&ContextInfo);
|
|
|
+ if (context == NULL)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("lws_create_context NG");
|
|
|
+
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(&ConnInfo,0,sizeof(struct lws_client_connect_info));
|
|
|
+ // fill up below information
|
|
|
+ ConnInfo.context = context;
|
|
|
+
|
|
|
+ ConnInfo.address=(const char *)OcppHost;
|
|
|
+ DEBUG_INFO("ConnInfo.address: %s\n", ConnInfo.address);
|
|
|
+
|
|
|
+ ConnInfo.port = GetOcppPort();
|
|
|
+ DEBUG_INFO("ConnInfo.port: %d\n", ConnInfo.port);
|
|
|
+
|
|
|
+ ConnInfo.path=(const char *)OcppPath;
|
|
|
+ DEBUG_INFO("ConnInfo.path: %s\n", ConnInfo.path);
|
|
|
+
|
|
|
+ char addr_port[256] = { 0 };
|
|
|
+ sprintf(addr_port, "%s:%u", ConnInfo.address, (ConnInfo.port & 65535) );
|
|
|
+
|
|
|
+ ConnInfo.host= addr_port; // ConnInfo.address;//lws_canonical_hostname(context);
|
|
|
+ ConnInfo.origin="origin";
|
|
|
+ ConnInfo.protocol = protocols[1].name;
|
|
|
+ ConnInfo.ietf_version_or_minus_one = -1;
|
|
|
+
|
|
|
+ if(use_ssl)
|
|
|
+ ConnInfo.ssl_connection = LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
|
|
|
+
|
|
|
+ wsi_client = lws_client_connect_via_info(&ConnInfo);
|
|
|
+ if (!wsi_client)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("lws_client_connect_via_info NG");
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+end:
|
|
|
+ pthread_exit(NULL/*(void *) fname*/);
|
|
|
+}
|
|
|
+
|
|
|
+int showfront(char *uuid, char *data)
|
|
|
+{
|
|
|
+ FILE *fp;
|
|
|
+ int result = FALSE; // 1: TRUE 0:FALSE
|
|
|
+ char str[1200]={0};
|
|
|
+ char sstr[50]={ 0 };//sstr[200]={ 0 };
|
|
|
+ int c = 0;
|
|
|
+ char *loc;
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+
|
|
|
+ // Check for directory existence
|
|
|
+ if (S_ISDIR(stats.st_mode) == 1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
+ FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
+
|
|
|
+ if(log == NULL)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Can't Create File TransactionRelatedQueue \n");
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fclose(log);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /* opening file for reading */
|
|
|
+ fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
|
|
|
+ if(fp == NULL) {
|
|
|
+ DEBUG_INFO("Error opening TransactionRelatedQueue file");
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if( fgets (str, 1200, fp)!=NULL ) {
|
|
|
+ /* writing content to stdout */
|
|
|
+ //DEBUG_INFO("str=%s",str);
|
|
|
+ if ((str[0] == '\n')||(strcmp(str,"")==0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("It is a blank line");
|
|
|
+ fclose(fp);
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+ sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/TransactionRelatedQueue");
|
|
|
+ system(rmFileCmd);
|
|
|
+ result = FALSE;
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //puts(str);
|
|
|
+ //----------------uuid--------------//
|
|
|
+ loc = strstr(str, "\"");
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ c = 0;
|
|
|
+ while (loc[1+c] != '\"')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[1+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+
|
|
|
+ //DEBUG_INFO("\n uuid:%s", sstr);
|
|
|
+ //DEBUG_INFO("\n data:%s", str);
|
|
|
+ strcpy(uuid,sstr);
|
|
|
+ strcpy(data,str);
|
|
|
+ result = TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("queue is null\n");
|
|
|
+ strcpy(uuid,"");
|
|
|
+ strcpy(data,"");
|
|
|
+ result = FALSE;
|
|
|
+ }
|
|
|
+ fclose(fp);
|
|
|
+ return result;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//---------------- addq(): add the item to the end of queue ----------------//
|
|
|
+int addq(char *uuid, char *data)
|
|
|
+ {
|
|
|
+ FILE *outfile;
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+ DEBUG_INFO("addq ");
|
|
|
+ // Check for directory existence
|
|
|
+ if (S_ISDIR(stats.st_mode) == 1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
+ FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
+
|
|
|
+ if(log == NULL)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("Can't Create File TransactionRelatedQueue \n");
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fclose(log);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // open file for writing
|
|
|
+ outfile = fopen ("/Storage/OCPP/TransactionRelatedQueue", "a");
|
|
|
+ DEBUG_INFO("data = %s\n",data);
|
|
|
+ fputs(data, outfile);
|
|
|
+ fputs("\n", outfile);
|
|
|
+ fclose (outfile);
|
|
|
+ TransactionQueueNum = TransactionQueueNum + 1;
|
|
|
+ if(OfflineTransaction == 1) // 0: no offline Transaction 1: offline Transaction
|
|
|
+ {
|
|
|
+ OfflineTransactionQueueNum = OfflineTransactionQueueNum + 1;
|
|
|
+ }
|
|
|
+ DEBUG_INFO("add queue end\n");
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//---------------- delq(): delete the top item --------------//
|
|
|
+int delq()
|
|
|
+{
|
|
|
+ char tempfile[] = "/Storage/OCPP/delqtemp.json";
|
|
|
+ FILE *infile;
|
|
|
+ FILE *outfile;
|
|
|
+ int resultRename=0;
|
|
|
+ char filename[60]={0};
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+
|
|
|
+ DEBUG_INFO("delq()\n");
|
|
|
+ // Check for directory existence
|
|
|
+ if (S_ISDIR(stats.st_mode) == 1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
+ FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
+
|
|
|
+ if(log == NULL)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("log is NULL\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fclose(log);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // open file for writing
|
|
|
+ strcpy(filename, "/Storage/OCPP/TransactionRelatedQueue");
|
|
|
+ infile = fopen ("/Storage/OCPP/TransactionRelatedQueue", "r");
|
|
|
+ outfile = fopen (tempfile, "w");
|
|
|
+
|
|
|
+ /*检测到文件结束标识返回1,否则返回0。*/
|
|
|
+ //DEBUG_INFO("feof(infile) =%d\n",feof(infile));
|
|
|
+ int c;
|
|
|
+ c = fgetc(infile);
|
|
|
+ //printf("file c:%d\n",c);
|
|
|
+ rewind(infile);
|
|
|
+
|
|
|
+ if(c == EOF)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue is NULL\n");
|
|
|
+
|
|
|
+ fclose(infile);
|
|
|
+ fclose(outfile);
|
|
|
+
|
|
|
+ sprintf(rmFileCmd,"rm -f %s",tempfile);
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char buf[1200]={0};
|
|
|
+
|
|
|
+ int i = 0;
|
|
|
+ //DEBUG_INFO("Orignal File is not NULL\n");
|
|
|
+ while (fgets(buf, sizeof(buf), infile) != NULL)
|
|
|
+ {
|
|
|
+ //printf("Orignal File get strings \n");
|
|
|
+ buf[strlen(buf) - 1] = '\0'; // eat the newline fgets() stores
|
|
|
+
|
|
|
+ if(i==0)
|
|
|
+ {
|
|
|
+ TransactionQueueNum = TransactionQueueNum - 1;
|
|
|
+ TransactionQueueInterval = 0;
|
|
|
+ TransactionMessageResend = 1;
|
|
|
+ DEBUG_INFO("delete the item\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(i != 0)
|
|
|
+ {
|
|
|
+ fprintf(outfile,"%s\n", buf);
|
|
|
+ }
|
|
|
+
|
|
|
+ i = i + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(infile);
|
|
|
+ fclose(outfile);
|
|
|
+
|
|
|
+ sprintf(rmFileCmd,"rm -f %s",filename);
|
|
|
+ system(rmFileCmd);
|
|
|
+
|
|
|
+ resultRename = rename(tempfile, filename);
|
|
|
+
|
|
|
+
|
|
|
+ if(resultRename == 0)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue file renamed successfully");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("Error: unable to rename the TransactionRelatedQueue file");
|
|
|
+ }
|
|
|
+
|
|
|
+ DEBUG_INFO("delq() end\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int showqueue()
|
|
|
+{
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+
|
|
|
+ // Check for directory existence
|
|
|
+ if (S_ISDIR(stats.st_mode) == 1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ if((access("/Storage/OCPP/TransactionRelatedQueue",F_OK))!=-1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue exist.\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("TransactionRelatedQueue not exist\n");
|
|
|
+ FILE *log = fopen("/Storage/OCPP/TransactionRelatedQueue", "w+");
|
|
|
+
|
|
|
+ if(log == NULL)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("log is NULL\n");
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fclose(log);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FILE *fp = fopen("/Storage/OCPP/TransactionRelatedQueue", "r");
|
|
|
+ char line[1200]={0};
|
|
|
+ // check if file exist (and you can open it) or not
|
|
|
+ if (fp == NULL) {
|
|
|
+ DEBUG_INFO("can open file TransactionRelatedQueue!");
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ TransactionQueueNum = 0; // the number of packets in queue
|
|
|
+
|
|
|
+ while(fgets(line, sizeof line, fp) != NULL) {
|
|
|
+ //DEBUG_INFO("%s\n", line);
|
|
|
+ TransactionQueueNum = TransactionQueueNum + 1; //the number of packets in queue
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(fp);
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+int sentqueue(){
|
|
|
+FILE *fp;
|
|
|
+int result = FALSE; // 1: TRUE 0:FALSE
|
|
|
+int temptransactionId = 0, gettransactionId = 0;
|
|
|
+int tempconnectorId = 0;
|
|
|
+//int gunIndex = 0;
|
|
|
+char guid[37]={0};
|
|
|
+char tempdata[65]={0};
|
|
|
+char key_value[65]={0};
|
|
|
+int IsStopTransaction = FALSE;
|
|
|
+//int IsconnectorIdNULL = FALSE;
|
|
|
+//int IsIdtagNULL = FALSE;
|
|
|
+char str[1200]={0};
|
|
|
+char strcomposite[1200]={0};
|
|
|
+char rmFileCmd[100]={0};
|
|
|
+char connectorStr[2]={0};
|
|
|
+struct stat stats;
|
|
|
+char sstr[28]={0};
|
|
|
+unsigned char IdtagStr[20]={0};
|
|
|
+unsigned char timestampStr[30]={0};
|
|
|
+int tempmeterStart = 0;
|
|
|
+int tempreservationId = 0;
|
|
|
+int c = 0;
|
|
|
+char *loc;
|
|
|
+
|
|
|
+DEBUG_INFO("sentqueue\n");
|
|
|
+stat("/Storage/OCPP", &stats);
|
|
|
+
|
|
|
+// Check for directory existence
|
|
|
+if (S_ISDIR(stats.st_mode) == 1)
|
|
|
+{
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+}
|
|
|
+else
|
|
|
+{
|
|
|
+ //DEBUG_INFO("\n OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+}
|
|
|
+
|
|
|
+memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+/* opening file for reading */
|
|
|
+fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
|
|
|
+if(fp == NULL) {
|
|
|
+ DEBUG_INFO("Error opening file");
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+if( fgets (str, 1200, fp)!=NULL ) {
|
|
|
+
|
|
|
+ //---- writing content to stdout ---//
|
|
|
+
|
|
|
+ //*********************Start: StopTransaction***************************/
|
|
|
+ loc = strstr(str, "StopTransaction");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ IsStopTransaction = TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(connectorStr,0,sizeof(connectorStr));
|
|
|
+ strncpy(connectorStr, str, 1);
|
|
|
+ tempconnectorId = atoi(connectorStr);
|
|
|
+
|
|
|
+ //*********************End: StopTransaction***************************/
|
|
|
+
|
|
|
+#if 0
|
|
|
+ //*********************Start:connectorId***************************/
|
|
|
+ loc = strstr(str, "connectorId");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ while (loc[strlen("connectorId")+2+c] != ',')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[strlen("connectorId")+2+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ tempconnectorId = atoi(sstr);
|
|
|
+ }
|
|
|
+// else
|
|
|
+// {
|
|
|
+// IsconnectorIdNULL = TRUE;
|
|
|
+// }
|
|
|
+ //*********************End:connectorId***************************/
|
|
|
+#endif
|
|
|
+
|
|
|
+ //*********************Start:idTag***************************/
|
|
|
+ loc = strstr(str, "idTag");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ while (loc[3+strlen("idTag")+c] != '\"')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[3+strlen("idTag")+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ strcpy((char*)IdtagStr, sstr);
|
|
|
+ }
|
|
|
+// else
|
|
|
+// {
|
|
|
+// IsIdtagNULL = TRUE;
|
|
|
+// }
|
|
|
+ //*********************End:idTag***************************/
|
|
|
+
|
|
|
+
|
|
|
+ //*********************Start: StartTransaction***************************/
|
|
|
+ loc = strstr(str, "StartTransaction");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ // [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
|
|
|
+ //DEBUG_INFO("\n sent queue StartTransaction\n");
|
|
|
+ if(tempconnectorId > 0)
|
|
|
+ {
|
|
|
+ sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
|
|
|
+ }
|
|
|
+
|
|
|
+ //GUID
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ c=0;
|
|
|
+ while (str[6+c] != '\"')
|
|
|
+ {
|
|
|
+ sstr[c] = str[6+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ strcpy(guid, sstr);
|
|
|
+
|
|
|
+
|
|
|
+ //Idtag
|
|
|
+ loc = strstr(str, "idTag");
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ c=0;
|
|
|
+ while (loc[3+strlen("idTag")+c] != '\"')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[3+strlen("idTag")+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ strcpy((char*)IdtagStr, sstr);
|
|
|
+
|
|
|
+ //meterStart
|
|
|
+ loc = strstr(str, "meterStart");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ while (loc[strlen("meterStart")+2+c] != ',')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[strlen("meterStart")+2+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ tempmeterStart = atoi(sstr);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //reservationId
|
|
|
+ loc = strstr(str, "reservationId");
|
|
|
+ c = 0;
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+ while (loc[strlen("reservationId")+2+c] != ',')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[strlen("reservationId")+2+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ tempreservationId = atoi(sstr);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //timestamp
|
|
|
+ loc = strstr(str, "timestamp");
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ c=0;
|
|
|
+ while (loc[3+strlen("timestamp")+c] != '\"')
|
|
|
+ {
|
|
|
+ sstr[c] = loc[3+strlen("timestamp")+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+ sstr[c] = '\0';
|
|
|
+ strcpy((char*)timestampStr, sstr);
|
|
|
+
|
|
|
+
|
|
|
+ if(hashmap_operation(1, guid, key_value) == TRUE)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hashmap_operation(0, guid, tempdata);
|
|
|
+ FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
|
|
|
+ //DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //*********************End: StartTransaction***************************/
|
|
|
+
|
|
|
+
|
|
|
+ //****************transactionId********************/
|
|
|
+ c=0;
|
|
|
+ loc = strstr(str, "transactionId");
|
|
|
+ memset(sstr ,0, sizeof(sstr) );
|
|
|
+ if(loc != NULL)
|
|
|
+ {
|
|
|
+
|
|
|
+ while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
|
|
|
+ {
|
|
|
+ sstr[c] = loc[strlen("transactionId")+2+c];
|
|
|
+ c++;
|
|
|
+ }
|
|
|
+
|
|
|
+ sstr[c] = '\0';
|
|
|
+ temptransactionId = atoi(sstr);
|
|
|
+
|
|
|
+ //gettransactionId = GetTransactionId(tempconnectorId, IdtagStr);
|
|
|
+
|
|
|
+ //From StartTransaction取得IdTag, 存到 StartTransactionIdTagTemp,主要是 給Queue中StopTransaction使用(StartTransaction. StopTransaction不同卡號 ),取得真正的TransactionId
|
|
|
+ GetStartTransactionIdTag(tempconnectorId-1);
|
|
|
+ DEBUG_INFO("\n StartTransactionIdTagTemp=%s",StartTransactionIdTagTemp);
|
|
|
+ gettransactionId = GetTransactionId(tempconnectorId, StartTransactionIdTagTemp);
|
|
|
+ DEBUG_INFO("\n gettransactionId=%d",gettransactionId);
|
|
|
+ if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
|
|
|
+ {
|
|
|
+ //replace transactionId of metervalue or stopTransaction
|
|
|
+ strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
|
|
|
+ sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
|
|
|
+ strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
|
|
|
+ LWS_Send(strcomposite+2); // skip 2 bytes字串-> 槍號,
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LWS_Send(str+2); // skip 2 bytes字串-> 槍號,
|
|
|
+ gettransactionId=temptransactionId;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
|
|
|
+ {
|
|
|
+ SetTransactionIdZero(gettransactionId);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LWS_Send(str+2);
|
|
|
+ }
|
|
|
+
|
|
|
+ result = TRUE;
|
|
|
+}
|
|
|
+else
|
|
|
+{
|
|
|
+ result = FALSE;
|
|
|
+}
|
|
|
+fclose(fp);
|
|
|
+return result;
|
|
|
+}
|
|
|
+
|
|
|
+void* processTransactionQueue(void* data)
|
|
|
+{
|
|
|
+ char frontUUID[100] ={0};
|
|
|
+ char frontData[1200/*1024*4*/] ={0};
|
|
|
+ int queueNotEmpty = FALSE;
|
|
|
+
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ if(FirstHeartBeatResponse() == 1)
|
|
|
+ {
|
|
|
+ memset(frontUUID, 0, sizeof(frontUUID));
|
|
|
+ memset(frontData, 0, sizeof(frontData));
|
|
|
+ queueNotEmpty = FALSE;
|
|
|
+
|
|
|
+ queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally
|
|
|
+
|
|
|
+ if((queueNotEmpty == TRUE) && (GetOcppConnStatus() == 1)) //OcppConnStatus 0: disconnected, 1: connected
|
|
|
+ {
|
|
|
+ if((OfflineTransaction == 1) && (OfflineTransactionQueueNum != 0)) //OfflineTransaction 0: no offline Transaction 1: offline Transaction
|
|
|
+ {
|
|
|
+ TransactionQueueInterval = 2;//10;//2;
|
|
|
+ sendbuffer = 1; // 0: no packets to send 1: send the top packet in queue
|
|
|
+ OfflineTransactionQueueNum = OfflineTransactionQueueNum - 1;
|
|
|
+
|
|
|
+ if(OfflineTransactionQueueNum == 0)
|
|
|
+ {
|
|
|
+ OfflineTransaction = 0;
|
|
|
+
|
|
|
+ }
|
|
|
+ sleep(TransactionQueueInterval);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(TransactionMessageResend <= TransactionMessageAttemptsGet()) //
|
|
|
+ {
|
|
|
+ DEBUG_INFO("processTransactionQueue queue is not empty!\n");
|
|
|
+ TransactionQueueInterval= TransactionMessageRetryIntervalGet()* TransactionMessageResend;
|
|
|
+ DEBUG_INFO("TransactionQueueInterval =%d\n",TransactionQueueInterval);
|
|
|
+ sleep(TransactionQueueInterval);
|
|
|
+ sendbuffer = 1;
|
|
|
+ TransactionMessageResend = TransactionMessageResend + 1;
|
|
|
+ DEBUG_INFO("After ADD,TransactionMessageResend=%d\n",TransactionMessageResend);
|
|
|
+ //sleep(TransactionQueueInterval);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ queue_operation(QUEUE_OPERATION_DEL,"",""); //// delete item
|
|
|
+ TransactionQueueInterval = 0;
|
|
|
+ TransactionMessageResend = 1;
|
|
|
+ sleep(TransactionQueueInterval);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ TransactionQueueInterval = 0;//10;
|
|
|
+ sleep(TransactionQueueInterval);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(GetOcppConnStatus() == 0)
|
|
|
+ {
|
|
|
+ if(queueNotEmpty == TRUE)
|
|
|
+ {
|
|
|
+ OfflineTransaction = 1; // 0: no offline Transaction 1: offline Transaction
|
|
|
+ }
|
|
|
+ }
|
|
|
+ usleep(5000);
|
|
|
+ }
|
|
|
+
|
|
|
+ pthread_exit(NULL); //
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void CheckTransactionPacket(char *uuid)
|
|
|
+{
|
|
|
+ char frontUUID[100]={0};
|
|
|
+ char frontData[1200]={0};
|
|
|
+ int queueNotEmpty = FALSE;
|
|
|
+ int cmpResult = 0;
|
|
|
+
|
|
|
+ queueNotEmpty = queue_operation(1,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally
|
|
|
+ if(queueNotEmpty == TRUE)
|
|
|
+ {
|
|
|
+ cmpResult = strcmp(frontUUID, uuid);
|
|
|
+
|
|
|
+ if (cmpResult == 0)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("TransactionPacket Compare All right!\n");
|
|
|
+ queue_operation(2,"","");//delq(); ---> remove temporally
|
|
|
+ TransactionQueueInterval = 0;
|
|
|
+ TransactionMessageResend = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int queue_operation(int type, char *frontUUID, char *frontData)
|
|
|
+{
|
|
|
+ int result=0;
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ if (!IsUsing )
|
|
|
+ {
|
|
|
+ IsUsing = TRUE;
|
|
|
+ //pthread_mutex_unlock(&lock_sentData);
|
|
|
+ //pthread_mutex_lock(&lock_sentData);
|
|
|
+
|
|
|
+ if(type == QUEUE_OPERATION_SHOWQUEUE) // show items in queue
|
|
|
+ {
|
|
|
+ result = showqueue();
|
|
|
+ }
|
|
|
+ else if(type == QUEUE_OPERATION_SHOWFRONT) // show first item
|
|
|
+ {
|
|
|
+ result = showfront(frontUUID, frontData);
|
|
|
+ }
|
|
|
+ else if(type == QUEUE_OPERATION_DEL) // delete item
|
|
|
+ {
|
|
|
+ result = delq();
|
|
|
+ }
|
|
|
+ else if(type == QUEUE_OPERATION_SENT) // sent items in queue
|
|
|
+ {
|
|
|
+ result = sentqueue();
|
|
|
+ }
|
|
|
+ else if(type == QUEUE_OPERATION_ADD) // add items to the queue
|
|
|
+ {
|
|
|
+ result = addq(frontUUID, frontData);
|
|
|
+ }
|
|
|
+
|
|
|
+ //pthread_mutex_unlock(&lock_sentData);
|
|
|
+ IsUsing = FALSE;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+int removeMessageSentFile(void)
|
|
|
+{
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+ // Check for directory existence
|
|
|
+ if(S_ISDIR(stats.st_mode) == 1)
|
|
|
+ {
|
|
|
+ //DEBUG_INFO("\n OCPP directory exist \n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO("\n directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+ if((access("/Storage/OCPP/MessageSent",F_OK))!=-1)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("MessageSent file exist.\n");
|
|
|
+ sprintf(rmFileCmd,"rm -f %s","/Storage/OCPP/MessageSent");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int changeChageWebSocketPingInterval = FALSE;
|
|
|
+void ChageWebSocketPingInterval(int WebSocketPingInterval)
|
|
|
+{
|
|
|
+ changeChageWebSocketPingInterval = TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+//================================================
|
|
|
+// Main process
|
|
|
+//================================================
|
|
|
+int main(void)
|
|
|
+{
|
|
|
+ char rmFileCmd[100]={0};
|
|
|
+ struct stat stats;
|
|
|
+ pthread_t t_ProcQueue;
|
|
|
+ DEBUG_INFO("Module_OcppBackend task initialization...\n");
|
|
|
+
|
|
|
+ if(ProcessShareMemory()== FAIL)
|
|
|
+ {
|
|
|
+ return FAIL;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check & create OCPP dir
|
|
|
+ stat("/Storage/OCPP", &stats);
|
|
|
+ if(S_ISDIR(stats.st_mode) != 1)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("OCPP directory not exist, create dir \n");
|
|
|
+ sprintf(rmFileCmd,"mkdir -p /Storage/OCPP");
|
|
|
+ system(rmFileCmd);
|
|
|
+ }
|
|
|
+ memset(rmFileCmd, 0, sizeof rmFileCmd);
|
|
|
+
|
|
|
+ //Create Process: Resend Transaction
|
|
|
+ pthread_create(&t_ProcQueue, NULL, processTransactionQueue, NULL);
|
|
|
+ sqlite3_config(SQLITE_CONFIG_URI,1);
|
|
|
+ if(sqlite3_open("file:/Storage/OCPP/charger.db", &db))
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
|
|
|
+ sqlite3_close( db );
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Opened database successfully\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ //Create Table log buffer
|
|
|
+ if(sqlite3_exec(db, createsql, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Create log buffer table error message: %s\n", errMsg);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Opened log buffer table successfully\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create Table OcppAuthCache
|
|
|
+ if(sqlite3_exec(db, sqlOcppAuthCache, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Create OcppAuthCache error message: %s\n", errMsg);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Opened OcppAuthCache table successfully\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create Table OcppAuthLocal
|
|
|
+ if(sqlite3_exec(db, sqlOcppAuthLocal, 0, 0, &errMsg) != SQLITE_OK)
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Create Table OcppAuthLocal error %s\n",errMsg);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_INFO( "Opened OcppAuthLocal table successfully\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ initialConfigurationTable();
|
|
|
+ removeMessageSentFile();
|
|
|
+
|
|
|
+ for(;;)
|
|
|
+ {
|
|
|
+ // Connect server
|
|
|
+ while(ConnectionEstablished==0) // Check InternetConn 0: disconnected, 1: connected
|
|
|
+ {
|
|
|
+ SetOcppConnStatus(FALSE);
|
|
|
+ SetServerSign(FALSE);
|
|
|
+ InitialSystemValue();
|
|
|
+ if((time((time_t*)NULL)-startTime.connect) >= 30)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Server connecting...\n");
|
|
|
+ pthread_create(&pid, NULL, ConnectWsServer, NULL);
|
|
|
+ startTime.connect=time((time_t*)NULL);
|
|
|
+ }
|
|
|
+ CheckSystemValue();
|
|
|
+ sleep(5);
|
|
|
+ lws_service(context, 10000);//timeout_ms
|
|
|
+ }
|
|
|
+
|
|
|
+ // Sign in
|
|
|
+ if( ((GetBootNotificationInterval() != 0 && ((time((time_t*)NULL)-startTime.bootNotification)>= GetBootNotificationInterval()) ) ||
|
|
|
+ ((time((time_t*)NULL)-startTime.bootNotification) >= defaultWaitingTime) ) && (GetServerSign() == FALSE))
|
|
|
+ {
|
|
|
+ sendBootNotificationRequest();
|
|
|
+ startTime.bootNotification=time((time_t*)NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ // On line operation
|
|
|
+ if(GetServerSign() == TRUE)
|
|
|
+ {
|
|
|
+ if(sendbuffer == 1)
|
|
|
+ {
|
|
|
+ queue_operation(QUEUE_OPERATION_SENT, "", "");
|
|
|
+ sendbuffer = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ SetOcppConnStatus(TRUE);
|
|
|
+ // Check System Value
|
|
|
+ CheckSystemValue();
|
|
|
+ if(GetHeartBeatWithNOResponse() >= 3)
|
|
|
+ {
|
|
|
+ lws_context_destroy(context);
|
|
|
+ ConnectionEstablished=0;
|
|
|
+ context = NULL;
|
|
|
+ SetHeartBeatWithNOResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+ if((changeChageWebSocketPingInterval == TRUE) || (GetInternetConn() == 0))
|
|
|
+ {
|
|
|
+ DEBUG_INFO("GetInternetConn() = %d\n", GetInternetConn());
|
|
|
+ changeChageWebSocketPingInterval = FALSE;
|
|
|
+ lws_context_destroy(context);
|
|
|
+ ConnectionEstablished=0;
|
|
|
+ context = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lws_service(context, 100);//timeout_ms
|
|
|
+ }
|
|
|
+ pthread_join(t_ProcQueue, NULL);
|
|
|
+
|
|
|
+ return FAIL;
|
|
|
+}
|
|
|
+
|
|
|
+
|