Ver Fonte

2022-01-20/Jerry Wang
Action:
1. Add OCPP 1.6 YES custom DataTransfer logic.
2. Fix CertificateSignedRequest parsing certificate crash problem.
3. Fix pkill problem.

File:
1. define.h
--> Action 1
2. EVSE/Modularization/ocppfiles/MessageHandler.c
--> Action 1,2
3. EVSE/Modularization/ocppfiles/Module_OcppBackend.c
--> Action 3
4. EVSE/Modularization/ocppph/MessageHandler.c
--> Action 1,2
5. EVSE/Modularization/ocppph/Module_OcppBackend.c
--> Action 3

Jerry Wang há 3 anos atrás
pai
commit
233fafe810

+ 457 - 17
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -11,6 +11,7 @@ struct SysConfigAndInfo				*ShmSysConfigAndInfo;
 struct StatusCodeData 				*ShmStatusCodeData;
 struct PsuData 						*ShmPsuData ;
 struct OCPP16Data 					*ShmOCPP16Data;
+struct StructYesCustomData          *ShmYesCustomData;
 
 //ConfigurationMaxKeys
 #define GetConfigurationMaxKeysNUM 	_GetConfiguration_CNT
@@ -125,6 +126,7 @@ struct ClientTime
 	struct timespec StopTransaction;
 	struct timespec MeterValues[CONNECTOR_QUANTITY];
 	struct timespec RemoteStartWait;
+	struct timespec YesCustomCallReader;
 }clientTime;
 
 typedef union
@@ -1136,7 +1138,7 @@ int OCPP_updatePeriodEnergy(uint8_t gun_index)
 					json_object_object_add(periodEnergys, (const char *)period, json_object_new_double(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].presentChargedEnergyPeriod[idxPeriod]));
 				}
 
-				json_object_object_add(EnergyDataTransfer, "periodEnergy", json_object_new_string(json_object_to_json_string_ext(periodEnergys, JSON_C_TO_STRING_PLAIN)));
+				json_object_object_add(EnergyDataTransfer, "periodEnergy", periodEnergys);
 			} //end of the same index
 		}//end of for CHAdeMO_QUANTITY
 	}
@@ -1164,7 +1166,7 @@ int OCPP_updatePeriodEnergy(uint8_t gun_index)
 					json_object_object_add(periodEnergys, (const char *)period, json_object_new_double(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].presentChargedEnergyPeriod[idxPeriod]));
 				}
 
-				json_object_object_add(EnergyDataTransfer, "periodEnergy", json_object_new_string(json_object_to_json_string_ext(periodEnergys, JSON_C_TO_STRING_PLAIN)));
+				json_object_object_add(EnergyDataTransfer, "periodEnergy", periodEnergys);
 			} //end of the same index
 		} // end of for CCS_QUANTITY
 	}
@@ -1192,7 +1194,7 @@ int OCPP_updatePeriodEnergy(uint8_t gun_index)
 					json_object_object_add(periodEnergys, (const char *)period, json_object_new_double(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].presentChargedEnergyPeriod[idxPeriod]));
 				}
 
-				json_object_object_add(EnergyDataTransfer, "periodEnergy", json_object_new_string(json_object_to_json_string_ext(periodEnergys, JSON_C_TO_STRING_PLAIN)));
+				json_object_object_add(EnergyDataTransfer, "periodEnergy", periodEnergys);
 			} //end of the same index
 		} // end of for GB_QUANTITY
 	}
@@ -1214,7 +1216,7 @@ int OCPP_updatePeriodEnergy(uint8_t gun_index)
 					json_object_object_add(periodEnergys, (const char *)period, json_object_new_double(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.presentChargedEnergyPeriod[idxPeriod]));
 				}
 
-				json_object_object_add(EnergyDataTransfer, "periodEnergy", json_object_new_string(json_object_to_json_string_ext(periodEnergys, JSON_C_TO_STRING_PLAIN)));
+				json_object_object_add(EnergyDataTransfer, "periodEnergy", periodEnergys);
 			} //end of the same index
 		}
 	}
@@ -4025,6 +4027,19 @@ int InitShareMemory()
 	else
 	{}
 
+   	//creat ShmYesCustomData
+	if ((MeterSMId = shmget(ShmYesCustomKey, sizeof(struct StructYesCustomData),  0777)) < 0)
+	{
+		DEBUG_ERROR("shmget StructYesCustomKey NG\n");
+		result = FAIL;
+	}
+	else if ((ShmYesCustomData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat StructYesCustomData NG\n");
+		result = FAIL;
+	}
+	else
+	{}
 
     /****************************** For Initial Settings************************************************/
 	ShmOCPP16Data->GetConfiguration.ResponseUnknownKey = NULL;
@@ -4426,6 +4441,19 @@ void CheckSystemValue(void)
 		HeartBeatWithNOResponse += 1;
 	}
 
+	//===============================
+	// send YES CallReader
+	//===============================
+	if(isWebsocketSendable && (server_sign == TRUE) && (ShmYesCustomData->CallReaderReq == 1) && (getDiffSecNow(clientTime.YesCustomCallReader) >= 5))
+	{
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].MessageId,"call_reader");
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].Data," ");
+		ShmOCPP16Data->CsMsg.bits[0].DataTransferReq = 1;
+		//ShmYesCustomData->CallReaderReq = 0;
+		refreshStartTimer(&clientTime.YesCustomCallReader);
+	}
+
 	for(int gun_index=0;gun_index < gunTotalNumber;gun_index++)
 	{
 		// ClockAlign MeterValue
@@ -10813,6 +10841,410 @@ int handleDataTransferRequest(char *uuid, char *payload)
 			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
 			json_object_put(response);
 		}
+		else if(strstr(tempmessageId, "refund_status") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "status") != NULL)
+				{
+					//DEBUG_INFO("status: %s\n", json_object_get_string(json_object_object_get(data, "status")));
+					if(strcmp(json_object_get_string(json_object_object_get(data, "status")), "T") || strcmp(json_object_get_string(json_object_object_get(data, "status")), "F"))
+					{
+						sprintf((char*)ShmYesCustomData->RefundStatus.status, "%s", json_object_get_string(json_object_object_get(data, "status")));
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("status value is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("status data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeDate") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->RefundStatus.chargeDate, "%s", json_object_get_string(json_object_object_get(data,"chargeDate")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeDate data can not get."));
+				}
+
+				if(json_object_object_get(data, "holdAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "holdAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.holdAmt = json_object_get_int(json_object_object_get(data, "holdAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("holdAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("holdAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "chargeAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.chargeAmt = json_object_get_int(json_object_object_get(data, "chargeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("chargeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "refundAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "refundAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.refundAmt = json_object_get_int(json_object_object_get(data, "refundAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("refundAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("refundAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "page") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "page")) >= 0 && json_object_get_int(json_object_object_get(data, "page")) <= 3)
+						ShmYesCustomData->RefundStatus.page = json_object_get_int(json_object_object_get(data, "page"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("page data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("page data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->RefundStatusReq = 1;
+					DEBUG_INFO("<<< RefundStatus:{status:%s, chargeDate:%s, holdAmt:%d, chargeAmt:%d, refundAmt:%d, page:%d}\n",
+							ShmYesCustomData->RefundStatus.status,
+							ShmYesCustomData->RefundStatus.chargeDate,
+							ShmYesCustomData->RefundStatus.holdAmt,
+							ShmYesCustomData->RefundStatus.chargeAmt,
+							ShmYesCustomData->RefundStatus.refundAmt,
+							ShmYesCustomData->RefundStatus.page);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("refund_status content got something wrong."));
+			}
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "deduct_status") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "status") != NULL)
+				{
+					//DEBUG_INFO("status: %s\n", json_object_get_string(json_object_object_get(data, "status")));
+					if((strcmp(json_object_get_string(json_object_object_get(data, "status")), "T")==0) || (strcmp(json_object_get_string(json_object_object_get(data, "status")), "F")==0))
+					{
+						sprintf((char*)ShmYesCustomData->DeductStatus.status, "%s", json_object_get_string(json_object_object_get(data, "status")));
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("status value is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("status data can not get."));
+				}
+
+				if(json_object_object_get(data, "autoLoadAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "autoLoadAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.autoLoadAmt = json_object_get_int(json_object_object_get(data, "autoLoadAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("autoLoadAmt is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("autoLoadAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "beforeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "beforeAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.beforeAmt = json_object_get_int(json_object_object_get(data, "beforeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("beforeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("beforeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "chargeAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.chargeAmt = json_object_get_int(json_object_object_get(data, "chargeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("chargeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "afterAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "afterAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.afterAmt = json_object_get_int(json_object_object_get(data, "afterAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("afterAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("afterAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "page") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "page")) >= 0)
+						ShmYesCustomData->DeductStatus.page = json_object_get_int(json_object_object_get(data, "page"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("page data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("page data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->DeductStatusReq = 1;
+					DEBUG_INFO("<<< deduct_status:{status:%s, autoLoadAmt:%d, beforeAmt:%d, chargeAmt:%d, afterAmt:%d, page:%d}\n",
+									ShmYesCustomData->DeductStatus.status,
+									ShmYesCustomData->DeductStatus.autoLoadAmt,
+									ShmYesCustomData->DeductStatus.beforeAmt,
+									ShmYesCustomData->DeductStatus.chargeAmt,
+									ShmYesCustomData->DeductStatus.afterAmt,
+									ShmYesCustomData->DeductStatus.page);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("deduct_status content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "charge_info") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "station_name") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->ChargerInfo.station_name, "%s", json_object_get_string(json_object_object_get(data,"station_name")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("station_name data can not get."));
+				}
+
+				if(json_object_object_get(data, "station_id") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->ChargerInfo.station_id, "%s", json_object_get_string(json_object_object_get(data,"station_id")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("station_id data can not get."));
+				}
+
+				if(json_object_object_get(data, "charge_id") != NULL)
+				{
+					for(int idx=0;idx<json_object_array_length(json_object_object_get(data, "charge_id"));idx++)
+					{
+						sprintf((char*)ShmYesCustomData->ChargerInfo.charge_id[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(data, "charge_id"), idx)));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("charge_id data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->ChargerInfoReq = 1;
+					DEBUG_INFO("<<< charge_info:{station_name:%s, station_id:%s, charge_id[0]:%s, charge_id[1]:%s}\n",
+									ShmYesCustomData->ChargerInfo.station_name,
+									ShmYesCustomData->ChargerInfo.station_id,
+									ShmYesCustomData->ChargerInfo.charge_id[0],
+									ShmYesCustomData->ChargerInfo.charge_id[1]);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("charger_info content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "weather_info") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "weather") != NULL)
+				{
+					ShmYesCustomData->WeatherInfo.weatherId = json_object_get_int(json_object_object_get(data, "weather"));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("weather data can not get."));
+				}
+
+				if(json_object_object_get(data, "temperature") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->WeatherInfo.temperature, "%s", json_object_get_string(json_object_object_get(data,"temperature")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("temperature data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->WeatherInfoReq = 1;
+					DEBUG_INFO("<<< weather_info:{weather:%d, temperature:%s}\n",
+									ShmYesCustomData->WeatherInfo.weatherId,
+									ShmYesCustomData->WeatherInfo.temperature
+									);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("weather_info content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "set_qrcode") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "connectorId") != NULL)
+				{
+					if((json_object_get_int(json_object_object_get(data, "connectorId")) > 0) && (json_object_get_int(json_object_object_get(data, "connectorId")) <= gunTotalNumber))
+					{
+						int idx = json_object_get_int(json_object_object_get(data, "connectorId"))-1;
+						if(json_object_object_get(data, "qrcode") != NULL)
+						{
+							sprintf((char *)ShmYesCustomData->QrCode[idx], "%s", json_object_get_string(json_object_object_get(data,"qrcode")));
+							ShmYesCustomData->SetQrCodeReq = 1;
+							DEBUG_INFO("<<< set_qrcode:{connectorId:%d, qrcode:%s}\n",
+											idx,
+											ShmYesCustomData->QrCode[idx]
+											);
+						}
+						else
+						{
+							json_object_object_add(response, "status", json_object_new_string("Rejected"));
+							json_object_object_add(response, "data", json_object_new_string("qrcode data can not get."));
+						}
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("connectorId data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("connectorId data can not get."));
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("set_qrcode content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
 		else
 		{
 			// Can not find valid message id
@@ -14444,7 +14876,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 	CertificateSigned = json_tokener_parse(payload);
 	if(!is_error(CertificateSigned))
 	{
-		sprintf((char*)ShmOCPP16Data->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(CertificateSigned, "certificateChain"), 0)));
+		sprintf((char*)ShmOCPP16Data->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_object_get(CertificateSigned, "certificateChain")));
 	}
 	json_object_put(CertificateSigned);
 
@@ -14898,21 +15330,29 @@ void handleBootNotificationResponse(char *payload, int gun_index)
 
 void handleDataTransferResponse(char *payload, int gun_index)
 {
-	char sstr[160]={0};//sstr[200]={ 0 };
-	int c = 0;
-	char *loc;
-	DEBUG_INFO("handleDataTransferResponse ...\n");
-	loc = strstr(payload, "status");
+	json_object *DataTransfer = json_tokener_parse(payload);
+	char status[32];
 
-	c = 0;
-	while (loc[3+strlen("status")+c] != '\"')
+	if(!is_error(DataTransfer))
 	{
-		sstr[c] = loc[3+strlen("status")+c];
-		c++;
-	}
-	sstr[c] = '\0';
 
-	DEBUG_INFO(" DataTransferResponse=%s\n", sstr);
+		// Required data
+		sprintf(status, "%s", json_object_get_string(json_object_object_get(DataTransfer, "status")));
+		DEBUG_INFO("Status: %s.\n", status);
+
+		// Optional data
+		if(json_object_object_get(DataTransfer, "data") != NULL)
+		DEBUG_INFO("Data: %s\n", json_object_get_string(json_object_object_get(DataTransfer, "data")));
+
+		// YES call_reader message confirm
+		if(ShmYesCustomData->CallReaderReq == 1)
+		{
+			sprintf((char *)ShmYesCustomData->CallReaderStatus, "%s",status);
+			ShmYesCustomData->CallReaderConf = 1;
+			ShmYesCustomData->CallReaderReq = 0;
+			DEBUG_INFO("Report CallReader status to CSU: %s\n",ShmYesCustomData->CallReaderStatus);
+		}
+	}
 }
 
 void handleDiagnosticsStatusNotificationResponse(char *payload, int gun_index)

+ 3 - 3
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -1253,7 +1253,7 @@ void* processWatchdog()
 			if(counterLwsRestart >= 2)
 			{
 				DEBUG_INFO("LWS watch dog timeout over 3 count.\n");
-				system("pkill OcppBackend");
+				system("killall OcppBackend");
 			}
 			else
 				counterLwsRestart++;
@@ -1264,13 +1264,13 @@ void* processWatchdog()
 		if(counterConnect >= 2)
 		{
 			DEBUG_INFO("Connect OCPP server timeout over 3 count.\n");
-			system("pkill OcppBackend");
+			system("killall OcppBackend");
 		}
 
 		if((0 < GetWebSocketPingInterval()) && ((GetWebSocketPingInterval()+5) <= getDiffSecNow(startTime.pingOn)) && (wsi_client != NULL) && (GetServerSign() == TRUE))
 		{
 			DEBUG_WARN("Pong packet receive timeout.\n");
-			system("pkill OcppBackend");
+			system("killall OcppBackend");
 		}
 
 		usleep(500000);

+ 455 - 13
EVSE/Modularization/ocppph/MessageHandler.c

@@ -12,6 +12,7 @@ struct StatusCodeData 				*ShmStatusCodeData;
 struct PsuData 						*ShmPsuData ;
 struct OCPP16Data 					*ShmOCPP16Data;
 struct OCPP16Data 					*ShmOCPP16DataPH;
+struct StructYesCustomData          *ShmYesCustomData;
 
 //ConfigurationMaxKeys
 #define GetConfigurationMaxKeysNUM 	_GetConfiguration_CNT
@@ -126,6 +127,7 @@ struct ClientTime
 	struct timespec StopTransaction;
 	struct timespec MeterValues[CONNECTOR_QUANTITY];
 	struct timespec RemoteStartWait;
+	struct timespec YesCustomCallReader;
 }clientTime;
 
 typedef union
@@ -3543,6 +3545,20 @@ int InitShareMemory()
 	else
 	{}
 
+   	//creat ShmYesCustomData
+	if ((MeterSMId = shmget(ShmYesCustomKey, sizeof(struct StructYesCustomData),  0777)) < 0)
+	{
+		DEBUG_ERROR("shmget StructYesCustomKey NG\n");
+		result = FAIL;
+	}
+	else if ((ShmYesCustomData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat StructYesCustomData NG\n");
+		result = FAIL;
+	}
+	else
+	{}
+
     /****************************** For Initial Settings************************************************/
 	ShmOCPP16DataPH->GetConfiguration.ResponseUnknownKey = NULL;
 	ShmOCPP16DataPH->SendLocalList.LocalAuthorizationList = NULL;
@@ -3945,6 +3961,19 @@ void CheckSystemValue(void)
 		HeartBeatWithNOResponse += 2;
 	}
 
+	//===============================
+	// send YES CallReader
+	//===============================
+	if(isWebsocketSendable && (server_sign == TRUE) && (ShmYesCustomData->CallReaderReq == 1) && (getDiffSecNow(clientTime.YesCustomCallReader) >= 5))
+	{
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].MessageId,"call_reader");
+		sprintf((char*)ShmOCPP16Data->DataTransfer[0].Data," ");
+		ShmOCPP16Data->CsMsg.bits[0].DataTransferReq = 1;
+		//ShmYesCustomData->CallReaderReq = 0;
+		refreshStartTimer(&clientTime.YesCustomCallReader);
+	}
+
 	for(int gun_index=0;gun_index < gunTotalNumber;gun_index++)
 	{
 		// ClockAlign MeterValue
@@ -10316,6 +10345,410 @@ int handleDataTransferRequest(char *uuid, char *payload)
 			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
 			json_object_put(response);
 		}
+		else if(strstr(tempmessageId, "refund_status") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "status") != NULL)
+				{
+					//DEBUG_INFO("status: %s\n", json_object_get_string(json_object_object_get(data, "status")));
+					if(strcmp(json_object_get_string(json_object_object_get(data, "status")), "T") || strcmp(json_object_get_string(json_object_object_get(data, "status")), "F"))
+					{
+						sprintf((char*)ShmYesCustomData->RefundStatus.status, "%s", json_object_get_string(json_object_object_get(data, "status")));
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("status value is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("status data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeDate") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->RefundStatus.chargeDate, "%s", json_object_get_string(json_object_object_get(data,"chargeDate")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeDate data can not get."));
+				}
+
+				if(json_object_object_get(data, "holdAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "holdAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.holdAmt = json_object_get_int(json_object_object_get(data, "holdAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("holdAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("holdAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "chargeAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.chargeAmt = json_object_get_int(json_object_object_get(data, "chargeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("chargeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "refundAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "refundAmt")) >= 0)
+						ShmYesCustomData->RefundStatus.refundAmt = json_object_get_int(json_object_object_get(data, "refundAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("refundAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("refundAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "page") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "page")) >= 0 && json_object_get_int(json_object_object_get(data, "page")) <= 3)
+						ShmYesCustomData->RefundStatus.page = json_object_get_int(json_object_object_get(data, "page"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("page data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("page data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->RefundStatusReq = 1;
+					DEBUG_INFO("<<< RefundStatus:{status:%s, chargeDate:%s, holdAmt:%d, chargeAmt:%d, refundAmt:%d, page:%d}\n",
+							ShmYesCustomData->RefundStatus.status,
+							ShmYesCustomData->RefundStatus.chargeDate,
+							ShmYesCustomData->RefundStatus.holdAmt,
+							ShmYesCustomData->RefundStatus.chargeAmt,
+							ShmYesCustomData->RefundStatus.refundAmt,
+							ShmYesCustomData->RefundStatus.page);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("refund_status content got something wrong."));
+			}
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "deduct_status") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "status") != NULL)
+				{
+					//DEBUG_INFO("status: %s\n", json_object_get_string(json_object_object_get(data, "status")));
+					if((strcmp(json_object_get_string(json_object_object_get(data, "status")), "T")==0) || (strcmp(json_object_get_string(json_object_object_get(data, "status")), "F")==0))
+					{
+						sprintf((char*)ShmYesCustomData->DeductStatus.status, "%s", json_object_get_string(json_object_object_get(data, "status")));
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("status value is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("status data can not get."));
+				}
+
+				if(json_object_object_get(data, "autoLoadAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "autoLoadAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.autoLoadAmt = json_object_get_int(json_object_object_get(data, "autoLoadAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("autoLoadAmt is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("autoLoadAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "beforeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "beforeAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.beforeAmt = json_object_get_int(json_object_object_get(data, "beforeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("beforeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("beforeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "chargeAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "chargeAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.chargeAmt = json_object_get_int(json_object_object_get(data, "chargeAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("chargeAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("chargeAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "afterAmt") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "afterAmt")) >= 0)
+						ShmYesCustomData->DeductStatus.afterAmt = json_object_get_int(json_object_object_get(data, "afterAmt"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("afterAmt data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("afterAmt data can not get."));
+				}
+
+				if(json_object_object_get(data, "page") != NULL)
+				{
+					if(json_object_get_int(json_object_object_get(data, "page")) >= 0)
+						ShmYesCustomData->DeductStatus.page = json_object_get_int(json_object_object_get(data, "page"));
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("page data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("page data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->DeductStatusReq = 1;
+					DEBUG_INFO("<<< deduct_status:{status:%s, autoLoadAmt:%d, beforeAmt:%d, chargeAmt:%d, afterAmt:%d, page:%d}\n",
+									ShmYesCustomData->DeductStatus.status,
+									ShmYesCustomData->DeductStatus.autoLoadAmt,
+									ShmYesCustomData->DeductStatus.beforeAmt,
+									ShmYesCustomData->DeductStatus.chargeAmt,
+									ShmYesCustomData->DeductStatus.afterAmt,
+									ShmYesCustomData->DeductStatus.page);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("deduct_status content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "charge_info") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "station_name") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->ChargerInfo.station_name, "%s", json_object_get_string(json_object_object_get(data,"station_name")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("station_name data can not get."));
+				}
+
+				if(json_object_object_get(data, "station_id") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->ChargerInfo.station_id, "%s", json_object_get_string(json_object_object_get(data,"station_id")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("station_id data can not get."));
+				}
+
+				if(json_object_object_get(data, "charge_id") != NULL)
+				{
+					for(int idx=0;idx<json_object_array_length(json_object_object_get(data, "charge_id"));idx++)
+					{
+						sprintf((char*)ShmYesCustomData->ChargerInfo.charge_id[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(data, "charge_id"), idx)));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("charge_id data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->ChargerInfoReq = 1;
+					DEBUG_INFO("<<< charge_info:{station_name:%s, station_id:%s, charge_id[0]:%s, charge_id[1]:%s}\n",
+									ShmYesCustomData->ChargerInfo.station_name,
+									ShmYesCustomData->ChargerInfo.station_id,
+									ShmYesCustomData->ChargerInfo.charge_id[0],
+									ShmYesCustomData->ChargerInfo.charge_id[1]);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("charger_info content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "weather_info") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "weather") != NULL)
+				{
+					ShmYesCustomData->WeatherInfo.weatherId = json_object_get_int(json_object_object_get(data, "weather"));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("weather data can not get."));
+				}
+
+				if(json_object_object_get(data, "temperature") != NULL)
+				{
+					sprintf((char *)ShmYesCustomData->WeatherInfo.temperature, "%s", json_object_get_string(json_object_object_get(data,"temperature")));
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("temperature data can not get."));
+				}
+
+				if(strcmp(json_object_get_string(json_object_object_get(response,"status")),"Accepted")==0)
+				{
+					ShmYesCustomData->WeatherInfoReq = 1;
+					DEBUG_INFO("<<< weather_info:{weather:%d, temperature:%s}\n",
+									ShmYesCustomData->WeatherInfo.weatherId,
+									ShmYesCustomData->WeatherInfo.temperature
+									);
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("weather_info content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
+		else if(strstr(tempmessageId, "set_qrcode") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+
+				if(json_object_object_get(data, "connectorId") != NULL)
+				{
+					if((json_object_get_int(json_object_object_get(data, "connectorId")) > 0) && (json_object_get_int(json_object_object_get(data, "connectorId")) <= gunTotalNumber))
+					{
+						int idx = json_object_get_int(json_object_object_get(data, "connectorId"))-1;
+						if(json_object_object_get(data, "qrcode") != NULL)
+						{
+							sprintf((char *)ShmYesCustomData->QrCode[idx], "%s", json_object_get_string(json_object_object_get(data,"qrcode")));
+							ShmYesCustomData->SetQrCodeReq = 1;
+							DEBUG_INFO("<<< set_qrcode:{connectorId:%d, qrcode:%s}\n",
+											idx,
+											ShmYesCustomData->QrCode[idx]
+											);
+						}
+						else
+						{
+							json_object_object_add(response, "status", json_object_new_string("Rejected"));
+							json_object_object_add(response, "data", json_object_new_string("qrcode data can not get."));
+						}
+					}
+					else
+					{
+						json_object_object_add(response, "status", json_object_new_string("Rejected"));
+						json_object_object_add(response, "data", json_object_new_string("connectorId data is invalid."));
+					}
+				}
+				else
+				{
+					json_object_object_add(response, "status", json_object_new_string("Rejected"));
+					json_object_object_add(response, "data", json_object_new_string("connectorId data can not get."));
+				}
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("set_qrcode content got something wrong."));
+			}
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string_ext(response, JSON_C_TO_STRING_PLAIN));
+			json_object_put(response);
+		}
 		else
 		{
 			// Can not find valid message id
@@ -13946,7 +14379,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 	CertificateSigned = json_tokener_parse(payload);
 	if(!is_error(CertificateSigned))
 	{
-		sprintf((char*)ShmOCPP16DataPH->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(CertificateSigned, "certificateChain"), 0)));
+		sprintf((char*)ShmOCPP16DataPH->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_object_get(CertificateSigned, "certificateChain")));
 	}
 	json_object_put(CertificateSigned);
 
@@ -14400,20 +14833,29 @@ void handleBootNotificationResponse(char *payload, int gun_index)
 
 void handleDataTransferResponse(char *payload, int gun_index)
 {
-	char sstr[160]={0};//sstr[200]={ 0 };
-	int c = 0;
-	char *loc;
-	DEBUG_INFO("handleDataTransferResponse ...\n");
-	loc = strstr(payload, "status");
-	c = 0;
-	while (loc[3+strlen("status")+c] != '\"')
+	json_object *DataTransfer = json_tokener_parse(payload);
+	char status[32];
+
+	if(!is_error(DataTransfer))
 	{
-		sstr[c] = loc[3+strlen("status")+c];
-		c++;
-	}
-	sstr[c] = '\0';
 
-	DEBUG_INFO(" DataTransferResponse=%s\n", sstr);
+		// Required data
+		sprintf(status, "%s", json_object_get_string(json_object_object_get(DataTransfer, "status")));
+		DEBUG_INFO("Status: %s.\n", status);
+
+		// Optional data
+		if(json_object_object_get(DataTransfer, "data") != NULL)
+		DEBUG_INFO("Data: %s\n", json_object_get_string(json_object_object_get(DataTransfer, "data")));
+
+		// YES call_reader message confirm
+		if(ShmYesCustomData->CallReaderReq == 1)
+		{
+			sprintf((char *)ShmYesCustomData->CallReaderStatus, "%s",status);
+			ShmYesCustomData->CallReaderConf = 1;
+			ShmYesCustomData->CallReaderReq = 0;
+			DEBUG_INFO("Report CallReader status to CSU: %s\n",ShmYesCustomData->CallReaderStatus);
+		}
+	}
 }
 
 void handleDiagnosticsStatusNotificationResponse(char *payload, int gun_index)

+ 3 - 3
EVSE/Modularization/ocppph/Module_OcppBackend.c

@@ -1251,7 +1251,7 @@ void* processWatchdog()
 			if(counterLwsRestart >= 2)
 			{
 				DEBUG_INFO("LWS watch dog timeout over 3 count.\n");
-				system("pkill OcppBackend");
+				system("killall OcppBackendPH");
 			}
 			else
 				counterLwsRestart++;
@@ -1262,13 +1262,13 @@ void* processWatchdog()
 		if(counterConnect >= 2)
 		{
 			DEBUG_INFO("Connect OCPP server timeout over 3 count.\n");
-			system("pkill OcppBackend");
+			system("killall OcppBackendPH");
 		}
 
 		if((0 < GetWebSocketPingInterval()) && ((GetWebSocketPingInterval()+5) <= getDiffSecNow(startTime.pingOn)) && (wsi_client != NULL) && (GetServerSign() == TRUE))
 		{
 			DEBUG_WARN("Pong packet receive timeout.\n");
-			system("pkill OcppBackend");
+			system("killall OcppBackendPH");
 		}
 
 

+ 60 - 0
EVSE/Projects/define.h

@@ -186,6 +186,7 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 #define ShmLedBdKey				1011
 #define ShmOcpp20ModuleKey		1012
 #define ShmRelay2BdKey			1013
+#define ShmYesCustomKey         1014
 
 #define FaultCodeLength         5
 #define AlarmCodeLength         20
@@ -4590,6 +4591,65 @@ struct StructSessionTarget
     unsigned short      targetDuration;     // Unit: Minutes    0 is unlimit
 };
 
+//===================================
+// YES custom protocol
+//===================================
+struct StructRefundStatus
+{
+	unsigned char status[10];
+	unsigned char chargeDate[32];
+	int holdAmt;
+	int chargeAmt;
+	int refundAmt;
+	int page;
+};
+
+struct StructDeductStatus
+{
+    unsigned char status[10];
+    int autoLoadAmt;
+    int beforeAmt;
+    int chargeAmt;
+    int afterAmt;
+    int page;
+};
+
+struct StructChargerInfo
+{
+    unsigned char station_name[64];
+    unsigned char station_id[64];
+    unsigned char charge_id[4][64];
+};
+
+struct StructWeatherInfo
+{
+    int weatherId;
+    unsigned char temperature[64];
+};
+
+struct StructYesCustomData
+{
+    struct StructRefundStatus RefundStatus;
+    struct StructDeductStatus DeductStatus;
+    struct StructChargerInfo ChargerInfo;
+    struct StructWeatherInfo WeatherInfo;
+    unsigned char QrCode[4][128];
+    unsigned char CallReaderStatus[10];
+
+    unsigned char CallReaderReq:1;
+    unsigned char CallReaderConf:1;
+    unsigned char RefundStatusReq:1;
+    unsigned char RefundStatusConf:1;
+    unsigned char DeductStatusReq:1;
+    unsigned char DeductStatusConf:1;
+    unsigned char ChargerInfoReq:1;
+    unsigned char ChargerInfoConf:1;
+    unsigned char WeatherInfoReq:1;
+    unsigned char WeatherInfoConf:1;
+    unsigned char SetQrCodeReq:1;
+    unsigned char SetQrCodeConf:1;
+};
+
 struct OCPP16Data
 {
     unsigned char                           OcppServerURL[512];     //http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"