#include <sys/time.h> #include <sys/timeb.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/shm.h> #include <sys/mman.h> #include <linux/wireless.h> #include <linux/sockios.h> #include <linux/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <errno.h> #include <string.h> #include <time.h> #include <ctype.h> #include <ifaddrs.h> #include "libwebsockets.h" #include <lws_config.h> #include "hashmap.h" #include "SystemLogMessage.h" #include "ShareMemory.h" #include <pthread.h> #include "MessageHandler.h" #include "sqlite3.h" #if 0 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #endif #define Debug //#define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 typedef enum boolean { FALSE, TRUE } BOOL; struct lws *wsi_client; struct lws_context *context; static int sendbuffer = 0; extern int server_sign; //extern int TransactionMessageAttemptsValue; //extern int TransactionMessageRetryIntervalValue; //extern int server_pending; //extern struct OCPP16Data *ShmOCPP16Data; extern void CheckSystemValue(void); //extern int TransactionMessageAttemptsGet(void); extern int FirstHeartBeatResponse(void); extern void OCPP_get_TableAuthlocalAllData(void); extern int TransactionMessageAttemptsGet(void); extern int TransactionMessageRetryIntervalGet(void); extern int GetOcppConnStatus(void); extern void SetOcppConnStatus(uint8_t status); extern int GetHeartBeatWithNOResponse(void); extern void SetHeartBeatWithNOResponse(void); //extern int InternetDisconnect(void); pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t lock_sentData = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t receiveData = PTHREAD_MUTEX_INITIALIZER; //struct json_object *parsed_json; //extern struct node Node; //========================================== // Function prototype //========================================== void trim(char *s); int mystrcmp(char *p1,char *p2); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); void getSubStr(char *dest, char* src, char *split, int idx); void split(char **arr, char *str, const char *del); int strpos(char *source, char *substr, int skip); int strposs(char *source, char *substr, int idx); char *random_uuid( char buf[37] ); static int OCPP16Callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); char * strchr(const char *p, int ch); void ReceivedMessage(void *in, size_t len); struct StartTime { unsigned int connect; unsigned int bootNotification; }startTime; #if 0 unsigned char *SendBuffer; int SendBufLen=(1024*4);//(1024*3); #endif int SendBufLen=(1024*4);//(1024*3); unsigned char SendBuffer[1024*4]={0}; static int ConnectionEstablished=0; static int TransactionMessageResend = 1; static int TransactionQueueInterval = 10;//3; // TransactionMessageAttempts static int TransactionQueueNum = 0; static int OfflineTransaction = 0; int defaultWaitingTime = 10; //10 second //=============================== // OCPP SentQueue TransactionId //=============================== static int SentQueueTransactionId[10]={0}; extern int BootNotificationInterval; //char guid[37]; //map_t hashMap; //data_struct_t* mapItem; --- remove for temporally //data_struct_t mapItem[0]={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);"; #if 0 static char *createsChargingRecordsql = "CREATE TABLE IF NOT EXISTS ChargingRecord(" "idx integer primary key," "gun_type text," "connectorId text," "idTag text," "transactionId 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," "reservationId text," "guid text UNIQUE);"; //"is_buf2OK text);"; #endif 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);"; #if 0 static char *sqlInitialOcppAuthLocal = "insert or replace into ocpp_auth_local(idtag, parent_idtag, expir_date, status, version) values('PaHdImHiOnNG','none','2099-12-31T23:59:59.999Z','Accepted','0')"; #endif 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; } //================================= // Common routine //================================= 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; } 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; } 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; } char *random_uuid( char buf[37] ) { const char *c = "89ab"; char *p = buf; int n; for( n = 0; n < 16; ++n ) { int b = rand()%255; switch( n ) { case 6: sprintf(p, "4%x", b%15 ); break; case 8: sprintf(p, "%c%x", c[rand()%strlen(c)], b%15 ); break; default: sprintf(p, "%02x", b); break; } p += 2; switch( n ) { case 3: case 5: case 7: case 9: *p++ = '-'; break; } } *p = 0; return buf; } //========================================== // Web socket tranceive routine //========================================== int SendData(struct lws *wsi) { int n; int len; char *ret; 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 ); ret = strstr((const char *)(out + LWS_SEND_BUFFER_PRE_PADDING), "Heartbeat"); if(ret == NULL) { DEBUG_OCPPMESSAGE_INFO(" SendData= %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: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_PROTOCOL_INIT\n"); #endif break; case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH\n"); #endif break; case LWS_CALLBACK_CLOSED_CLIENT_HTTP: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_CLOSED_CLIENT_HTTP\n"); #endif break; case LWS_CALLBACK_WSI_DESTROY: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_WSI_DESTROY\n"); #endif server_sign = FALSE; break; case LWS_CALLBACK_LOCK_POLL: break; case LWS_CALLBACK_ADD_POLL_FD: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_ADD_POLL_FD\n"); #endif break; case LWS_CALLBACK_DEL_POLL_FD: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_DEL_POLL_FD\n"); #endif break; case LWS_CALLBACK_UNLOCK_POLL: break; case LWS_CALLBACK_CHANGE_MODE_POLL_FD: break; case LWS_CALLBACK_WSI_CREATE: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_WSI_CREATE\n"); #endif break; case LWS_CALLBACK_GET_THREAD_ID: break; case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n"); #endif break; case LWS_CALLBACK_CLIENT_ESTABLISHED://3 #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_CLIENT_ESTABLISHED\n"); #endif //connected ConnectionEstablished=1; break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR://1 #ifdef Debug DEBUG_ERROR("LWS_CALLBACK_CLIENT_CONNECTION_ERROR:%s\n",in); #endif #ifdef SystemLogMessage DEBUG_ERROR("LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); #endif //disconnected ConnectionEstablished=0; break; case LWS_CALLBACK_CLOSED://4 #ifdef SystemLogMessage DEBUG_INFO("LWS_CALLBACK_CLOSED\n"); ConnectionEstablished=0; #endif //disconnected break; case LWS_CALLBACK_CLIENT_WRITEABLE://10 //if(need to send message and its relevant data already store into SendBuffer) #ifdef SystemLogMessage //DEBUG_INFO("LWS_CALLBACK_CLIENT_WRITEABLE\n"); #endif SendData(wsi); break; case LWS_CALLBACK_CLIENT_RECEIVE://8 ((char *)in)[len] = '\0'; //Print Out Adjudgement { char *ret, *ret1; ret = strstr((const char *)in, "currentTime"); ret1 = strstr((const char *)in, "interval"); if(!((ret != NULL)&&(ret1 == NULL))) { DEBUG_OCPPMESSAGE_INFO("Original Receive %s\n", (char *)in); } } char tempin[1024*4]={0}; int c = 0; char *loc; char sstr[600]={ 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 *)tempin, len); break; default: #ifdef Debug DEBUG_INFO("OCPP16Callback:reason=%d\n", reason); #endif break; } return 0; } static struct lws_protocols protocols[] = { { "ocpp1.6", OCPP16Callback, 10240, 10240, }, { "ocpp1.6", OCPP16Callback, 10240, 10240, }, { NULL, NULL, 0 /* End of list */ } }; int ConnectWsServer() { int result = PASS; struct lws_context_creation_info ContextInfo; struct lws_client_connect_info ConnInfo; int use_ssl=0; //lws_set_log_level(LLL_PARSER | LLL_HEADER, NULL); if(context!=NULL) lws_context_destroy(context); memset(&ContextInfo, 0, sizeof(struct lws_context_creation_info)); ContextInfo.port = CONTEXT_PORT_NO_LISTEN; ContextInfo.iface = NULL; ContextInfo.ssl_private_key_password = NULL; ContextInfo.ssl_cert_filepath = NULL; ContextInfo.ssl_private_key_filepath = NULL; ContextInfo.ssl_ca_filepath = "/root/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 = 9999;//30; //if(ping pong enabled) ContextInfo.ws_ping_pong_interval = 30;//0 for none, else interval in seconds context = lws_create_context(&ContextInfo); if (context == NULL) { #ifdef SystemLogMessage DEBUG_ERROR("lws_create_context NG"); #endif result = FAIL; } memset(&ConnInfo,0,sizeof(struct lws_client_connect_info)); // fill up below information ConnInfo.context = context; if((strcmp((const char *)GetOcppServerURL(),"")==0) || (GetOcppPort() == 0) || (strcmp((const char *)GetOcppPath(),"")==0) ) { result = FAIL; DEBUG_ERROR("OCPP URL is NULL or OCPP Port is zero or OCPP Path is NULL\n"); return result; } ConnInfo.address=(const char *)GetOcppServerURL(); ConnInfo.port = GetOcppPort(); ConnInfo.path=(const char *)GetOcppPath(); ConnInfo.host=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) { #ifdef SystemLogMessage DEBUG_ERROR("lws_client_connect_via_info NG"); #endif result = FAIL; } return result; } //void createq(); int showfront(char *uuid, char *data); int addq(char *uuid, char *data) ; int delq(); int sentqueue(); void CheckTransactionPacket(char *uuid); int queue_operation(int type, char *frontUUID, char *frontData); 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 0; } 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(fgetc(fp)==EOF) { //DEBUG_INFO("It is end of file"); fclose(fp); memset(rmFileCmd, 0, sizeof rmFileCmd); sprintf(rmFileCmd,"rm -f %s","../Storage/OCPP/TransactionRelatedQueue"); system(rmFileCmd); result = FALSE; return result; } 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; } //return 1; } else { //DEBUG_INFO("queue is null\n"); strcpy(uuid,""); strcpy(data,""); result = FALSE; //return 0; } fclose(fp); return result; } int addq(char *uuid, char *data) { FILE *outfile; char rmFileCmd[100]={0}; struct stat stats; stat("../Storage/OCPP", &stats); //DEBUG_INFO("addq\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("Can't Create File TransactionRelatedQueue \n"); return 0; } 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; return 0; } int delq() { char tempfile[] = "../Storage/OCPP/temp.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; } 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"); } } 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 0; } 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 0; } while(fgets(line, sizeof line, fp) != NULL) { DEBUG_INFO("%s\n", line); } fclose(fp); return 0; } int sentqueue(){ FILE *fp; int result = FALSE; // 1: TRUE 0:FALSE int temptransactionId = 0; int tempconnectorId = 0; int gunIndex = 0; char guid[37]={0}; char tempdata[65]={0}; char key_value[65]={0}; int IsStopTransaction = FALSE; char str[1200]={0}; char strcomposite[1200]={0}; char rmFileCmd[100]={0}; struct stat stats; char sstr[28]={ 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 */ //*********************StopTransaction***************************/ loc = strstr(str, "StopTransaction"); c = 0; memset(sstr ,0, sizeof(sstr) ); if(loc != NULL) { IsStopTransaction = TRUE; } //*********************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); //DEBUG_INFO("\n tempconnectorId:%d\n", tempconnectorId); } //*********************StartTransaction***************************/ loc = strstr(str, "StartTransaction"); c = 0; memset(sstr ,0, sizeof(sstr) ); if(loc != NULL) { //DEBUG_INFO("\n sent queue StartTransaction\n"); if(tempconnectorId > 0) { sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1)); } else if(tempconnectorId == 0) { sprintf(tempdata, "StartTransaction,%d", 0); } memset(sstr ,0, sizeof(sstr) ); //DEBUG_INFO("\n 0-0. sent queue str=%s\n",str); c=0; while (str[4+c] != '\"') { sstr[c] = str[4+c]; c++; } sstr[c] = '\0'; strcpy(guid, sstr); //DEBUG_INFO("\n 0. sent queue sstr=%s\n",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); //DEBUG_INFO("\n 2. sent queue guid=%s\n",guid); } } //****************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); //puts(str); //DEBUG_INFO("\n uuid:%s", ""); //DEBUG_INFO("\n data:%s", str); if(IsStopTransaction == TRUE) { for(int i=0; i <10; i++) { //DEBUG_INFO("\n StopTransaction i:%d\n", i); //DEBUG_INFO("\n StopTransaction SentQueueTransactionId[i]:%d\n", SentQueueTransactionId[i]); //DEBUG_INFO("\n sStopTransaction temptransactionId:%d\n", temptransactionId); if(SentQueueTransactionId[i] == temptransactionId) { tempconnectorId = i; gunIndex = i; break; } } } else { if(tempconnectorId > 0) { SentQueueTransactionId[tempconnectorId-1] = temptransactionId; gunIndex = tempconnectorId-1; } } //DEBUG_INFO("\n gunIndex=%d \n",gunIndex); //DEBUG_INFO("\n temptransactionId=%d \n",temptransactionId); //DEBUG_INFO("\n GetTransactionId(gunIndex)=%d \n",GetTransactionId(gunIndex)); if((GetTransactionId(gunIndex) != 0)&&(temptransactionId != GetTransactionId(gunIndex))) { strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId")); sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",GetTransactionId(gunIndex)); strcat(strcomposite, loc+strlen("transactionId")+2+c); LWS_Send(strcomposite); } else { LWS_Send(str); } if((IsStopTransaction == TRUE)&&(GetTransactionId(gunIndex) != 0)) { SetTransactionIdZero(gunIndex); } } else { LWS_Send(str); } result = TRUE; //return 1; } else { //DEBUG_INFO("queue is null\n"); result = FALSE; //return 0; } fclose(fp); //DEBUG_INFO("sentqueue end\n"); return result; } // void* processTransactionQueue(void* data) { char frontUUID[100] ={0}; char frontData[1200/*1024*4*/] ={0}; int queueNotEmpty = 0; while(1) { if(FirstHeartBeatResponse() == 1) { memset(frontUUID, 0, sizeof(frontUUID)); memset(frontData, 0, sizeof(frontData)); queueNotEmpty = 0; queueNotEmpty = queue_operation(1,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally if((queueNotEmpty == 1) && (GetOcppConnStatus() == 1)) { if((OfflineTransaction == 1) && (TransactionQueueNum != 0)) { TransactionQueueInterval = 10;//2; sleep(TransactionQueueInterval); sendbuffer = 1; DEBUG_INFO("test 1\n"); } else { OfflineTransaction = 0; if(TransactionMessageResend < TransactionMessageAttemptsGet()) // { DEBUG_INFO("TransactionMessageResend=%d\n",TransactionMessageResend); DEBUG_INFO("TransactionMessageAttemptsGet=%d\n",TransactionMessageAttemptsGet()); DEBUG_INFO("processTransactionQueue queue is not empty!\n"); TransactionQueueInterval= TransactionMessageRetryIntervalGet()* TransactionMessageResend; DEBUG_INFO("TransactionQueueInterval =%d\n",TransactionQueueInterval); sendbuffer = 1; TransactionMessageResend = TransactionMessageResend + 1; DEBUG_INFO("After ADD,TransactionMessageResend=%d\n",TransactionMessageResend); sleep(TransactionQueueInterval); } else { queue_operation(2,"",""); //// delete item TransactionQueueInterval = 0; TransactionMessageResend = 1; sleep(TransactionQueueInterval); } } } else if((queueNotEmpty == 1) && (GetOcppConnStatus() == 0)) { OfflineTransaction = 1; } else { TransactionQueueInterval = 0;//10; sleep(TransactionQueueInterval); } } usleep(5000); } pthread_exit(NULL); // return 0; } void CheckTransactionPacket(char *uuid) { char frontUUID[100]={0}; char frontData[1200]={0}; int queueNotEmpty = 0; int cmpResult = 0; //queue_operation(0,"","");//showqueue(); ---> remove temporally queueNotEmpty = queue_operation(1,frontUUID, frontData);//showfront(frontUUID, frontData); ---> remove temporally if(queueNotEmpty == 1) { cmpResult = strcmp(frontUUID, uuid); //cmpResult = strcmp(frontData, uuid); if (cmpResult == 0) { DEBUG_INFO("TransactionPacket Compare All right!\n"); DEBUG_INFO("frontUUID=%s\n",frontUUID); DEBUG_INFO("uuid=%s\n",uuid); queue_operation(2,"","");//delq(); ---> remove temporally TransactionQueueInterval = 0; TransactionMessageResend = 1; } } } /* type: 0 (showqueue ); type: 1(showfront); type: 2(delq) type: 3 (sentqueue) type: 4 (addq) type: 5(store queue to /Storage/OCPP/ )*/ int queue_operation(int type, char *frontUUID, char *frontData) { pthread_mutex_unlock(&lock_sentData); pthread_mutex_lock(&lock_sentData); int result=0; if(type == 0) // show items in queue result = showqueue(); else if(type == 1) // show first item result = showfront(frontUUID, frontData); else if(type == 2) // delete item result = delq(); else if(type == 3) // sent items in queue result = sentqueue(); else if(type == 4) // add items to the queue result = addq(frontUUID, frontData); pthread_mutex_unlock(&lock_sentData); return result; } char * strchr(const char *p, int ch) { char c; c = ch; for (;; ++p) { if (*p == c) return ((char *)p); if (*p == '\0') return (NULL); } /* NOTREACHED */ return NULL; } 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; } #define SystemLogMessage //================================================ // Main process //================================================ int main(void) { char rmFileCmd[100]={0}; struct stat stats; pthread_t t; #ifdef SystemLogMessage DEBUG_INFO("Initialization...\n"); #endif if(ProcessShareMemory()== FAIL) { return FAIL; } //Create OCPP dir 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); //Create Process: Resend Transaction pthread_create(&t, NULL, processTransactionQueue, NULL); // sqlite3_config(SQLITE_CONFIG_URI,1); if(sqlite3_open("file:/../Storage/OCPP/charger.db", &db)) { #ifdef Debug DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); #endif sqlite3_close( db ); exit(0); } else { #ifdef Debug DEBUG_INFO( "Opened database successfully\n"); #endif } //Create Table log buffer int rc =sqlite3_exec(db, createsql, 0, 0, &errMsg); if (SQLITE_OK != rc) { #ifdef Debug DEBUG_INFO( "Create log buffer table error message: %s\n", errMsg); #endif return 0; } else { #ifdef Debug DEBUG_INFO( "Opened log buffer table successfully\n"); #endif } // Create Table OcppAuthCache rc =sqlite3_exec(db, sqlOcppAuthCache, 0, 0, &errMsg); if (SQLITE_OK != rc) { #ifdef Debug DEBUG_INFO( "Create OcppAuthCache error message: %s\n", errMsg); #endif return 0; } else { #ifdef Debug DEBUG_INFO( "Opened OcppAuthCache table successfully\n"); #endif } // Create Table OcppAuthLocal rc =sqlite3_exec(db, sqlOcppAuthLocal, 0, 0, &errMsg); if (SQLITE_OK != rc) { #ifdef Debug DEBUG_INFO( "Create Table OcppAuthLocal error %s\n",errMsg); #endif return 0; } else { #ifdef Debug DEBUG_INFO( "Opened OcppAuthLocal table successfully\n"); #endif } initialConfigurationTable(); removeMessageSentFile(); //queryAllData(); OCPP_get_TableAuthlocalAllData(); for(;;) { while(ConnectionEstablished==0) { SetOcppConnStatus(FALSE); if((time((time_t*)NULL)-startTime.connect)>=60) { #ifdef Debug DEBUG_INFO("Execute ConnectWsServer\n"); #endif ConnectWsServer(); startTime.connect=time((time_t*)NULL); } // Check System Value, process offline Transaction CheckSystemValue(); lws_service(context, 10000);//timeout_ms } if(( (BootNotificationInterval != 0 && ((time((time_t*)NULL)-startTime.bootNotification)>=BootNotificationInterval) ) || ((time((time_t*)NULL)-startTime.bootNotification)>=defaultWaitingTime) ) && ((server_sign == FALSE)/*|| (server_pending == TRUE)*/)) { //hashmapForMessageNew(); sendBootNotificationRequest(); startTime.bootNotification=time((time_t*)NULL); } if(server_sign == TRUE) { if(sendbuffer == 1) { queue_operation(3, "", "");//sentqueue() sendbuffer = 0; } SetOcppConnStatus(TRUE); // Check System Value CheckSystemValue(); if(GetHeartBeatWithNOResponse() >= 3) { lws_context_destroy(context); ConnectionEstablished=0; context = NULL; SetHeartBeatWithNOResponse(); } } lws_service(context, 100);//timeout_ms } pthread_join(t, NULL); // //hashmapForMessageFree(); return FAIL; }