Эх сурвалжийг харах

2022-11-23/Jerry Wang
[OCPP 1.6PH]
Action:
Synchronize partial code with OCPP 1.6.(since 2022-09-28 to now)
1. Fix the problem of sending Heartbeat anytime once HeartbeatInterval is set to 0.
2. Fix the problem that charger cannot clear all ChargingProfiles when it recieved the ClearChargingProfile command with connectorId 0.
3. Improve GetDiagnostics logic.
4. Add checking gunType logic for new 'DL' series.
5. Modify AuthorizationKey changeConfiguration logic for transferring hexadecimal represented data to string.
6. Fix the queue mapping problem which cause the transactionId of queued messages always be 0.
7. Add logic to disconnect the websocket if the count of BootNotification no response is over 10 times.

File:
1. EVSE/Modularization/ocppph/MessageHandler.c
--> Action 1-5
1. EVSE/Modularization/ocppph/Module_OcppBackend.c
--> Action 6,7

Jerry Wang 2 жил өмнө
parent
commit
45509ac857

+ 101 - 99
EVSE/Modularization/ocppph/MessageHandler.c

@@ -3986,7 +3986,8 @@ int ProcessShareMemory()
 	 	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
 	 	   ((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
 		    (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
-			(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O'))
+			(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O') ||
+			(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='L'))
 		   ) // 'D' means DC
 		{
 			// DO series
@@ -4382,7 +4383,7 @@ void CheckSystemValue(void)
 	//===============================
 	// send Heartbeat
 	//===============================
-	if((server_sign == TRUE) && (getDiffSecNow(clientTime.Heartbeat) >= (HeartBeatWaitTime + HeartBeatWithNOResponse)))
+	if((server_sign == TRUE) && (HeartBeatWaitTime > 0) && (getDiffSecNow(clientTime.Heartbeat) >= (HeartBeatWaitTime + HeartBeatWithNOResponse)))
 	{
 		//parameter for test
 		sendHeartbeatRequest(0);
@@ -5335,22 +5336,26 @@ int sendBootNotificationRequest(void)
 int sendDataTransferRequest(int gun_index)
 {
 	mtrace();
-	char message[1000]={0};
+	char message[10240]={0};
 	char guid[37]={0};
 	char tempdata[65]={0};
 	int result = FAIL;
 
+	json_object *DataTransfer = json_object_new_object();
+
+	json_object_object_add(DataTransfer, "vendorId", json_object_new_string((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId));
+	json_object_object_add(DataTransfer, "messageId", json_object_new_string((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId));
+	json_object_object_add(DataTransfer, "data", json_object_new_string((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data));
+
+
 	random_uuid(guid);
-	sprintf(message,"[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
-			MESSAGE_TYPE_CALL,
-			guid,
-			ShmOCPP16DataPH->DataTransfer[gun_index].VendorId,
-			ShmOCPP16DataPH->DataTransfer[gun_index].MessageId,
-			ShmOCPP16DataPH->DataTransfer[gun_index].Data);
+	sprintf(message,"[%d,\"%s\",\"DataTransfer\",%s]", MESSAGE_TYPE_CALL,
+													   guid,
+													   json_object_to_json_string_ext(DataTransfer, JSON_C_TO_STRING_PLAIN));
+	json_object_put(DataTransfer);
 
 	LWS_Send(message);
-
-	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
+	sprintf(tempdata, "DataTransfer,%d", gun_index);
 	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
 	{
 		result = PASS;
@@ -5363,7 +5368,7 @@ int sendDataTransferRequest(int gun_index)
 int sendUnplugByDataTransferRequest(int gun_index)
 {
 	mtrace();
-	char message[1000]={0};
+	char message[10752]={0};
 	char guid[37]={0};
 	char tempdata[65]={0};
 	int result = FAIL;
@@ -9824,97 +9829,49 @@ int handleClearChargingProfileRequest(char *uuid, char *payload)
 	json_object_put(ClearChargingProfile);
 
 
-	if(connectorIsNULL == FALSE)
+	if(connectorIdInt > 0)
 	{
-		switch(connectorIdInt)
+		if(chargingProfilePurposeIsNULL == TRUE)
 		{
-			case 0:
-
-			    if(chargingProfilePurposeIsNULL == TRUE)
-				{
-			    	int l = 0;
-			    	strcpy(fname, ChargePointMaxProfile_JSON);
-			    	if((access(fname,F_OK))!=-1)
-			    	{
-			    		strcpy(chargingProfiles[l], fname);
-			    		l = l + 1;
-			    	}
-
-			    	strcpy(fname, TxDefaultProfile_0_JSON);
-			    	if((access(fname,F_OK))!=-1)
-			    	{
-			    		strcpy(chargingProfiles[l], fname);
-			    		l = l + 1;
-			    	}
-			    	ChargeProfileCount = l;
-
-				}
-				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"ChargePointMaxProfile")==0))
-				{
-					strcpy(fname, ChargePointMaxProfile_JSON);
-					if((access(fname,F_OK))!=-1)
-					{
-						strcpy(chargingProfiles[0], fname);
-						ChargeProfileCount = 1;
-					}
-				}
-				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxDefaultProfile")==0))
-				{
-					strcpy(fname, TxDefaultProfile_0_JSON);
-					if((access(fname,F_OK))!=-1)
-					{
-						strcpy(chargingProfiles[0], fname);
-						ChargeProfileCount = 1;
-					}
-				}
+			int m = 0;
+			memset(fname, 0, ARRAY_SIZE(fname));
+			sprintf(fname, "/Storage/OCPP_PH/TxDefaultProfile_%d.json", connectorIdInt);
+			if((access(fname,F_OK))!=-1)
+			{
+				strcpy(chargingProfiles[m], fname);
+				m = m + 1;
+			}
 
-				break;
+			memset(fname, 0, ARRAY_SIZE(fname));
+			sprintf(fname, "/Storage/OCPP_PH/TxProfile_%d.json", connectorIdInt);
+			if((access(fname,F_OK))!=-1)
+			{
+				strcpy(chargingProfiles[m], fname);
+				m = m + 1;
+			}
 
-			default:
-			    if(chargingProfilePurposeIsNULL == TRUE)
-			    {
-			    	int m = 0;
-			    	memset(fname, 0, ARRAY_SIZE(fname));
-			    	sprintf(fname, "/Storage/OCPP_PH/TxDefaultProfile_%d.json", connectorIdInt);
-			    	if((access(fname,F_OK))!=-1)
-			    	{
-			    		strcpy(chargingProfiles[m], fname);
-			    		m = m + 1;
-			    	}
-
-			    	memset(fname, 0, ARRAY_SIZE(fname));
-			    	sprintf(fname, "/Storage/OCPP_PH/TxProfile_%d.json", connectorIdInt);
-			    	if((access(fname,F_OK))!=-1)
-			    	{
-			    		strcpy(chargingProfiles[m], fname);
-			    		m = m + 1;
-			    	}
-
-			    	ChargeProfileCount = m;
-			    }
-				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxDefaultProfile")==0))
-				{
-					//strcpy(fname, TxDefaultProfile_1_JSON);
-					sprintf(fname, "/Storage/OCPP_PH/TxDefaultProfile_%d.json", connectorIdInt);
-					if((access(fname,F_OK))!=-1)
-					{
-						strcpy(chargingProfiles[0], fname);
-						ChargeProfileCount = 1;
-					}
+			ChargeProfileCount = m;
+		}
+		else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxDefaultProfile")==0))
+		{
+			//strcpy(fname, TxDefaultProfile_1_JSON);
+			sprintf(fname, "/Storage/OCPP_PH/TxDefaultProfile_%d.json", connectorIdInt);
+			if((access(fname,F_OK))!=-1)
+			{
+				strcpy(chargingProfiles[0], fname);
+				ChargeProfileCount = 1;
+			}
 
-				}
-				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxProfile")==0))
-				{
-					sprintf(fname, "/Storage/OCPP_PH/TxProfile_%d.json", connectorIdInt);
-					if((access(fname,F_OK))!=-1)
-					{
-						strcpy(chargingProfiles[0], fname);
-						ChargeProfileCount = 1;
-					}
-					//strcpy(fname, TxProfile_1_JSON);
-				}
-				//strcpy(fname, ChargePointMaxProfile_JSON );
-				break;
+		}
+		else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxProfile")==0))
+		{
+			sprintf(fname, "/Storage/OCPP_PH/TxProfile_%d.json", connectorIdInt);
+			if((access(fname,F_OK))!=-1)
+			{
+				strcpy(chargingProfiles[0], fname);
+				ChargeProfileCount = 1;
+			}
+			//strcpy(fname, TxProfile_1_JSON);
 		}
 	}
 	else // Check all Charging Profiles
@@ -11546,6 +11503,31 @@ void* GetDiagnosticsProcess(void* data)
 	}
 	json_object_put(GetDiagnostics);
 
+	// Notify CSU to get log of dispensers.
+	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
+	   ((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
+		(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
+		(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O') ||
+		(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='L'))
+	   )
+	{
+		sprintf((char *)ShmOCPP16DataPH->GetDiagnostics.StartTime,"%s",startTimestr);
+		sprintf((char *)ShmOCPP16DataPH->GetDiagnostics.StopTime,"%s",stopTimestr);
+
+		ShmOCPP16DataPH->MsMsg.bits.GetDiagnosticsReq = TRUE;
+
+		struct timespec timerGetDiagnostics;
+		refreshStartTimer(&timerGetDiagnostics);
+		while(ShmOCPP16DataPH->MsMsg.bits.GetDiagnosticsReq != FALSE)
+		{
+			if(getDiffSecNow(timerGetDiagnostics)>=180)
+			{
+				ShmOCPP16DataPH->MsMsg.bits.GetDiagnosticsReq = FALSE;
+				DEBUG_INFO("Waiting log of dispenser timeout.");
+			}
+		}
+	}
+
 	// Pack log to compress file
 	if((sscanf((char*)startTimestr, "%4d-%2d-%2dT%2d:%2d:%2d", &tmStart.tm_year, &tmStart.tm_mon, &tmStart.tm_mday, &tmStart.tm_hour, &tmStart.tm_min, &tmStart.tm_sec) == 6) &&
 	   (sscanf((char*)stopTimestr, "%4d-%2d-%2dT%2d:%2d:%2d", &tmStop.tm_year, &tmStop.tm_mon, &tmStop.tm_mday, &tmStop.tm_hour, &tmStop.tm_min, &tmStop.tm_sec) == 6))
@@ -11575,6 +11557,9 @@ void* GetDiagnosticsProcess(void* data)
 
 		sprintf(cmdBuf, "%s /Storage/CCS*.zip", cmdBuf);
 		sprintf(cmdBuf, "%s /Storage/OCPP/*.db", cmdBuf);
+		sprintf(cmdBuf, "%s /Storage/OCPP/TransactionRelatedQueue", cmdBuf);
+		sprintf(cmdBuf, "%s /Storage/OCPP/QueueTransactionId", cmdBuf);
+		sprintf(cmdBuf, "%s /Storage/OCPP/OCPPConfiguration", cmdBuf);
 		system(cmdBuf);
 
 		// Pack charging & event log
@@ -19003,7 +18988,24 @@ int setKeyValue(char *key, char *value)
     	if((ShmOCPP16DataPH->ConfigurationTable.CoreProfile[AuthorizationKey].ItemAccessibility == 1) && (strlen(value) <= 40))
     	{
     		strcpy(str, (const char*)value);
-    		sprintf((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[AuthorizationKey].ItemData, "%s", str);
+			int strlength = strlen(str);
+			char capture[3];
+			char stackItem = 0;
+			char password[21] = {0};
+
+			printf("String length: %d\n", strlength);
+
+			for(int idx=0; idx<(strlength/2); idx++)
+			{
+				capture[0] = str[(idx*2)];
+				capture[1] = str[(idx*2)+1];
+				capture[2] = 0;
+				stackItem = (char)strtol(capture, NULL, 16);       // number base 16
+
+				sprintf(password,"%s%c", password, stackItem);
+			}
+
+    		sprintf((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[AuthorizationKey].ItemData, "%s", password);
     		strcpy((char*)ShmSysConfigAndInfo->SysConfig.MaintainServerSecurityPassword, (char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[AuthorizationKey].ItemData);
     		isSuccess = ConfigurationStatus_Accepted;
     	}

+ 45 - 29
EVSE/Modularization/ocppph/Module_OcppBackend.c

@@ -39,6 +39,7 @@ uint8_t	isQueueSendable = 1;
 uint8_t counterQueueSent = 0;
 uint8_t	counterConnect = 0;
 uint8_t counterPingSend = 0;
+uint8_t counterBootNotificationSend = 0;
 
 sqlite3 *db;
 char *errMsg = NULL;
@@ -275,6 +276,7 @@ static int OCPP16Callback(struct lws *wsi, enum lws_callback_reasons reason, voi
 			SetOcppConnStatus(TRUE);
 			refreshStartTimer(&startTime.pingOn);
 			counterPingSend = 0;
+			counterBootNotificationSend = 0;
 			queueOpInfo.TransactionMessageResend = 0;
 			break;
 		case LWS_CALLBACK_CLIENT_CONNECTION_ERROR://1
@@ -971,40 +973,41 @@ int sentqueue()
 				{
 					if(strstr(action, "StartTransaction") != NULL)
 					{
+						char idtag[21]={0};
+						char timestamp[36]={0};
+						int meterStart=0;
+						int reservationId=-1;
+
+						if(json_object_object_get(objPayload, "idTag") != NULL)
+						{
+							sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+						}
+
+						if(json_object_object_get(objPayload, "meterStart") != NULL)
+						{
+							meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
+						}
+
+						if(json_object_object_get(objPayload, "reservationId") != NULL)
+						{
+							reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
+						}
+
+						if(json_object_object_get(objPayload, "timestamp") != NULL)
+						{
+							sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
+						}
+
+						FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
+
 						if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
 						{
 							//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
 						}
 						else
 						{
-							char idtag[21]={0};
-							char timestamp[36]={0};
-							int meterStart=0;
-							int reservationId=-1;
 							sprintf(hashData, "StartTransaction,%d", (connectorId-1));
 							hashmap_operation(HASH_OP_ADD, guid, hashData);
-
-							if(json_object_object_get(objPayload, "idTag") != NULL)
-							{
-								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
-							}
-
-							if(json_object_object_get(objPayload, "meterStart") != NULL)
-							{
-								meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
-							}
-
-							if(json_object_object_get(objPayload, "reservationId") != NULL)
-							{
-								reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
-							}
-
-							if(json_object_object_get(objPayload, "timestamp") != NULL)
-							{
-								sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
-							}
-
-							FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
 							//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
 						}
 
@@ -1440,11 +1443,23 @@ int main(void)
 			// Sign in
 			if((GetServerSign() == FALSE) &&
 			   (isConnectorInitMode(0) != TRUE) &&
-			   ( (GetBootNotificationInterval()>0) ? (getDiffSecNow(startTime.bootNotification) >= GetBootNotificationInterval()) : (getDiffSecNow(startTime.bootNotification) >= defaultWaitingTime) )
+			   ((GetBootNotificationInterval()>0) ? (getDiffSecNow(startTime.bootNotification) >= GetBootNotificationInterval()) : (getDiffSecNow(startTime.bootNotification) >= defaultWaitingTime) )
 			  )
 			{
-				sendBootNotificationRequest();
-				refreshStartTimer(&startTime.bootNotification);
+				if(counterBootNotificationSend>=10)
+				{
+					lws_context_destroy(context);
+					ConnectionEstablished = 0;
+					context = NULL;
+					counterBootNotificationSend = 0;
+					DEBUG_INFO("Disconnect because of 10 times no BootNotification response.\n");
+				}
+				else
+				{
+					sendBootNotificationRequest();
+					refreshStartTimer(&startTime.bootNotification);
+					counterBootNotificationSend++;
+				}
 			}
 
 			// Check System Value
@@ -1453,6 +1468,7 @@ int main(void)
 			// On line operation
 			if(GetServerSign() == TRUE)
 			{
+				counterBootNotificationSend = 0;
 				// Send message from queue
 				if((req_SendQueue == 1) && (isWebsocketSendable || ((queueOpInfo.TransactionMessageResend > 1) && (queueOpInfo.PreTransactionMessageResend != queueOpInfo.TransactionMessageResend))))
 				{