浏览代码

Merge branch 'DO360'

FolusWen 4 年之前
父节点
当前提交
a4d633f353

+ 1 - 0
EVSE/Projects/DO360/Apps/FactoryConfig.c

@@ -123,6 +123,7 @@ int main(int argc,char *argv[])
 	SysConfig.Ccs2PlugInTimes = 0;
 	SysConfig.ChademoPlugInTimes = 0;
 	SysConfig.BillingData.isBilling = 0;
+	SysConfig.BillingData.Currency = 50;
 	SysConfig.isAPP = 1;
 	SysConfig.isQRCode = 1;
 	SysConfig.isRFID = 1;

+ 15 - 2
EVSE/Projects/DO360/Apps/Makefile

@@ -10,7 +10,7 @@ Lib_Module_RFID = "-L../../../Modularization" -lModule_RFID
 Lib_Module_Upgrade = "-L../../../Modularization" -lModule_Upgrade
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
-all: CopyFile apps
+all: CopyFile apps Clean
 #apps: Module_CSU Module_EvComm Module_EventLogging Module_InternalComm Module_LcmControl Module_PrimaryComm Module_PsuComm 
 # ReadCmdline kill.sh
 apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask UnsafetyOutputTool FactoryConfigApp OtherTools
@@ -95,6 +95,19 @@ CopyFile:
 	rm -rfv ../Images/root
 	mkdir -p ../Images/root
 
+Clean: CleanObj CleanExecute
 
+CleanObj:
+	rm -f *.o
 
-	
+CleanExecute:
+	rm -f main
+	rm -f Module_EvComm
+	rm -f Module_EventLogging
+	rm -f Module_InternalComm
+	rm -f Module_LcmControl
+	rm -f Module_PrimaryComm
+	rm -f Module_PsuComm
+	rm -f ReadCmdline
+	rm -f FactoryConfig
+	rm -f UnsafetyOutputTask

+ 620 - 26
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -53,6 +53,8 @@
 
 struct SysConfigAndInfo				*ShmSysConfigAndInfo;
 
+//struct WARNING_CODE_INFO            LastWarningInfo[GENERAL_GUN_QUANTITY];
+
 void PRINTF_FUNC(char *string, ...);
 
 int StoreLogMsg(const char *fmt, ...);
@@ -974,22 +976,52 @@ void DispenserStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
+struct ChargingCapabilityResponse ConnectorCapability[GENERAL_GUN_QUANTITY];
+
 void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
 {
 	struct PACKET_STRUCTURE sendBuffer;
 	unsigned short voltage = 0, current = 0, power = 0;
+	unsigned char currency = 0;
+	unsigned int price = 0, cost = 0, account = 0;
 
 	memset(&sendBuffer, 0x00, sizeof(sendBuffer));
 	voltage = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.MaximumChargingVoltage;
 	current = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.AvailableChargingCurrent;
 	power = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.AvailableChargingPower;
 
-	PRINTF_FUNC("Connector %d Capability Voltage: %d, Current: %d, Power: %d", packet->Header.id, (int)(voltage), (int)(current), (int)(power));
+	currency = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency;
+	price = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].UserPrice;
+	cost = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].TotalCost;
+	account = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AccountBalance;
+
+	if(ConnectorCapability[packet->Header.id - 1].MaxOuputVoltage != voltage ||
+        ConnectorCapability[packet->Header.id - 1].MaxOuputCurrent != current ||
+        ConnectorCapability[packet->Header.id - 1].MaxOuputPower != power)
+	{
+	    PRINTF_FUNC("Connector %d Capability Voltage: %d, Current: %d, Power: %d", packet->Header.id, (int)(voltage), (int)(current), (int)(power));
+	}
+
+	if(ConnectorCapability[packet->Header.id - 1].Currency != currency ||
+        ConnectorCapability[packet->Header.id - 1].UserPrice != price ||
+        ConnectorCapability[packet->Header.id - 1].TotalCost != cost ||
+        ConnectorCapability[packet->Header.id - 1].AccountBalance != account)
+	{
+	    PRINTF_FUNC("Connector %d Currency: %d, UserPrice: %d, Cost: %d, Account: %d", packet->Header.id, (int)(currency), (int)(price), (int)(cost), (int)(account));
+	}
+
+	ConnectorCapability[packet->Header.id - 1].MaxOuputVoltage = voltage;
+	ConnectorCapability[packet->Header.id - 1].MaxOuputCurrent = current;
+	ConnectorCapability[packet->Header.id - 1].MaxOuputPower = power;
+	ConnectorCapability[packet->Header.id - 1].Currency = currency;
+	ConnectorCapability[packet->Header.id - 1].UserPrice = price;
+	ConnectorCapability[packet->Header.id - 1].TotalCost = cost;
+	ConnectorCapability[packet->Header.id - 1].AccountBalance = account;
 
 	sendBuffer.Header.se = packet->Header.se;
 	sendBuffer.Header.id = packet->Header.id;
 	sendBuffer.Header.op = _Header_Response;
-	sendBuffer.Header.len = 8;
+	sendBuffer.Header.len = 21;
 	sendBuffer.Payload.reg = _Reg_Charging_Capability;
 	sendBuffer.Payload.data[0] = _R_OK;
 	sendBuffer.Payload.data[1] = ((voltage >> 8) & 0xFF);
@@ -998,6 +1030,19 @@ void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
 	sendBuffer.Payload.data[4] = (current & 0xFF);
 	sendBuffer.Payload.data[5] = ((power >> 8) & 0xFF);
 	sendBuffer.Payload.data[6] = (power & 0xFF);
+	sendBuffer.Payload.data[7] = currency;
+	sendBuffer.Payload.data[8] = ((price >> 24) & 0xFF);
+	sendBuffer.Payload.data[9] = ((price >> 16) & 0xFF);
+	sendBuffer.Payload.data[10] = ((price >> 8) & 0xFF);
+	sendBuffer.Payload.data[11] = (price & 0xFF);
+    sendBuffer.Payload.data[12] = ((cost >> 24) & 0xFF);
+    sendBuffer.Payload.data[13] = ((cost >> 16) & 0xFF);
+    sendBuffer.Payload.data[14] = ((cost >> 8) & 0xFF);
+    sendBuffer.Payload.data[15] = (cost & 0xFF);
+    sendBuffer.Payload.data[16] = ((account >> 24) & 0xFF);
+    sendBuffer.Payload.data[17] = ((account >> 16) & 0xFF);
+    sendBuffer.Payload.data[18] = ((account >> 8) & 0xFF);
+    sendBuffer.Payload.data[19] = (account & 0xFF);
 
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
@@ -1017,6 +1062,22 @@ void ChargingTargetResponse(int socket, struct PACKET_STRUCTURE *packet, unsigne
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
+void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Software_Update;
+    sendBuffer.Payload.data[0] = _R_OK;
+    sendBuffer.Payload.data[1] = result;
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
 void PlugInStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
 {
 	struct PACKET_STRUCTURE sendBuffer;
@@ -1079,6 +1140,218 @@ void ChargingPermissionResponse(int socket, struct PACKET_STRUCTURE *packet, uns
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
+void AddMiscCommand(struct PACKET_STRUCTURE *packet, struct MISC_COMMAND *misc)
+{
+    packet->Payload.data[packet->Header.len - 1 + 0] = ((misc->Command >> 8) & 0xFF);
+    packet->Payload.data[packet->Header.len - 1 + 1] = ((misc->Command >> 0) & 0xFF);
+    packet->Payload.data[packet->Header.len - 1 + 2] = ((misc->Value >> 24) & 0xFF);
+    packet->Payload.data[packet->Header.len - 1 + 3] = ((misc->Value >> 16) & 0xFF);
+    packet->Payload.data[packet->Header.len - 1 + 4] = ((misc->Value >>  8) & 0xFF);
+    packet->Payload.data[packet->Header.len - 1 + 5] = ((misc->Value >>  0) & 0xFF);
+    packet->Header.len += 6;
+}
+
+void MiscControlResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Misc_Control;
+    sendBuffer.Payload.data[0] = result;
+
+    if(result == _R_OK)
+    {
+        struct MISC_COMMAND misc;
+
+        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AvailabilityRequest)
+        {
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AvailabilityRequest = false;
+            misc.Command = _MiscCmd_ChangeOperative;
+            misc.Value = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.IsAvailable;
+
+            PRINTF_FUNC("Announce Connector %d Availability: %d", packet->Header.id, misc.Value);
+            AddMiscCommand(&sendBuffer, &misc);
+        }
+
+        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStartRequest)
+        {
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStartRequest = false;
+            misc.Command = _MiscCmd_RemoteStart;
+            misc.Value = true;
+
+            PRINTF_FUNC("Announce Connector %d Remote Start: %d", packet->Header.id, misc.Value);
+            AddMiscCommand(&sendBuffer, &misc);
+        }
+
+        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AccountBalanceRequest)
+        {
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AccountBalanceRequest = false;
+            misc.Command = _MiscCmd_AccountBalance;
+            misc.Value = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AccountBalance;
+
+            PRINTF_FUNC("Announce Connector %d Account Balance: %d", packet->Header.id, (misc.Value));
+            AddMiscCommand(&sendBuffer, &misc);
+        }
+
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorID[0] == packet->Header.id)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.ConnectorTimeoutConfigRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.ConnectorTimeoutConfigRequest = false;
+                misc.Command = _MiscCmd_ConnectorTimeout;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout;
+
+                PRINTF_FUNC("Announce Dispenser %d Connection Timeout: %d", dispenserIndex + 1, misc.Value);
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DefaultPriceConfigRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DefaultPriceConfigRequest = false;
+                misc.Command = _MiscCmd_DefaultPrice;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.DispenserInfo.DefaultPrice;
+
+                PRINTF_FUNC("Announce Dispenser %d Default Price: %d", dispenserIndex + 1, misc.Value);
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.CurrencyConfigRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.CurrencyConfigRequest = false;
+                misc.Command = _MiscCmd_Currency;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency;
+
+                PRINTF_FUNC("Announce Dispenser %d Currency Index: %d", dispenserIndex + 1, misc.Value);
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.HardwareRebootRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.HardwareRebootRequest = false;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.HardwareRebootConfirm = true;
+                misc.Command = _MiscCmd_HardwareReboot;
+                misc.Value = true;
+
+                PRINTF_FUNC("Announce Dispenser %d Hardware Reboot: %d", dispenserIndex + 1, misc.Value);
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.SoftwareResetRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.SoftwareResetRequest = false;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.SoftwareResetConfirm = true;
+                misc.Command = _MiscCmd_SoftwareRestart;
+                misc.Value = true;
+
+                PRINTF_FUNC("Announce Dispenser %d Software Reset: %d", dispenserIndex + 1, misc.Value);
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+        }
+    }
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
+void WriteCsuVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Report_Csu_Version;
+    sendBuffer.Payload.data[0] = result;
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
+void WriteOtherVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Report_Other_Version;
+    sendBuffer.Payload.data[0] = result;
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
+void WriteChargingInfoResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Charging_Info;
+    sendBuffer.Payload.data[0] = result;
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
+void ChargerSystemIdResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_Charger_System_Id;
+    sendBuffer.Payload.data[0] = result;
+    if(result == _R_OK)
+    {
+        int strLen = 0;
+        strLen = strlen((char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
+        memcpy(&sendBuffer.Payload.data[sendBuffer.Header.len - 1], (char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, strLen);
+        sendBuffer.Header.len += strLen + 1;
+
+        char TimeSync[32];
+        struct timeb  SeqEndTime;
+        struct tm *tm;
+        ftime(&SeqEndTime);
+        SeqEndTime.time = time(NULL);
+        tm=localtime(&SeqEndTime.time);
+        memset(TimeSync, 0x00, 32);
+
+        sprintf(TimeSync, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+        strLen = strlen(TimeSync);
+        memcpy(&sendBuffer.Payload.data[sendBuffer.Header.len - 1], TimeSync, strLen);
+        sendBuffer.Header.len += strLen + 1;
+        //PRINTF_FUNC("Dispenser %d Read System Id: %s", dispenserIndex + 1, ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
+    }
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
+void WriteWaitPlugInResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_WaitPlugIn;
+    sendBuffer.Payload.data[0] = result;
+
+    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+}
+
 BOOL FindConnectorID(unsigned char dispenserIndex, unsigned char id)
 {
 	BOOL find = false;
@@ -1251,8 +1524,35 @@ BOOL DispenserStatusCodeHandler(struct PACKET_STRUCTURE *packet, unsigned char d
 			memcpy(&ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCode[i][0],
 				&packet->Payload.data[i * 6], 6);
 		}
-
-		PRINTF_FUNC("Dispenser %d, Status Code Len: %d", packet->Header.id, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount);
+/*
+		BOOL needUpdate = FALSE;
+		// check is there new status code
+		for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount; i++)
+		{
+		    if(strcmp(&ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCode[i][0],
+		            &LastWarningInfo[packet->Header.id - 1].WarningCode[i][0]) == 0)
+		    {
+		        needUpdate = TRUE;
+		        break;
+		    }
+		}
+		if(needUpdate)
+		{
+		    memcpy(&LastWarningInfo[packet->Header.id - 1], &ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo, sizeof(struct WARNING_CODE_INFO));
+		}
+*/
+		char strDispenserStatus[128];
+		sprintf(strDispenserStatus, "Dispenser id %d, Status Code Len: %d", packet->Header.id, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount);
+		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount > 0)
+		{
+		    for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount; i++)
+		    {
+		        char strTemp[16];
+		        sprintf(strTemp, ", %s", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCode[i]);
+		        strcat(strDispenserStatus, strTemp);
+		    }
+		}
+		PRINTF_FUNC(strDispenserStatus);
 	}
 	else
 	{
@@ -1283,8 +1583,6 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
     return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
 }
 
-struct timeval _ConnectorCapabilityTime[CONNECTOR_QUANTITY];
-
 BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
 	BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
@@ -1296,12 +1594,6 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 		voltage = (float)((packet->Payload.data[0] << 8) + packet->Payload.data[1]) / 10;
 		current = (float)((packet->Payload.data[2] << 8) + packet->Payload.data[3]) / 10;
 
-//        if(GetTimeoutValue(_ConnectorCapabilityTime[packet->Header.id - 1]) / 1000 >= 2000)
-//        {
-//            gettimeofday(&_ConnectorCapabilityTime[packet->Header.id - 1], NULL);
-//            ShowSocketData(packet);
-//        }
-
 		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus == S_CHARGING)
 		{
 			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage != voltage ||
@@ -1334,6 +1626,11 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 	return done;
 }
 
+unsigned char FirmwareUpgradeHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    return _R_NoUpgrade;
+}
+
 BOOL ConnectorPlugInHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
 	BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
@@ -1405,8 +1702,8 @@ unsigned char UserIDHandler(struct PACKET_STRUCTURE *packet, unsigned char dispe
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].AuthorizeStatus == _AuthorizeStatus_Pass)
 	{
-	    PRINTF_FUNC("Dispenser id %d user id %s authorizing ok", dispenserIndex + 1, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId);
-	    authorize = _DAS_Allowed;
+        PRINTF_FUNC("Dispenser id %d user id %s authorizing ok", dispenserIndex + 1, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId);
+        authorize = _DAS_Allowed;
 	}
 	else
 	{
@@ -1425,11 +1722,27 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
 	{
 	    switch(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus)
 	    {
+            case S_IDLE:
+                if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Idle ||
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing)
+                {
+                    permission = _DAS_Wait;
+                }
+                else
+                {
+                    permission = _DAS_NotAllowed;
+                    PRINTF_FUNC("Cabinet status idle, not allow dispenser id %d connector id %d charging",
+                                        dispenserIndex + 1, packet->Header.id);
+                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
+                }
+                break;
+
             case S_PREPARING_FOR_EV:
                 if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopRequest ||
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
                 {
                     permission = _DAS_NotAllowed;
+                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
                 }
                 else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus >= _CRS_Preparing &&
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus <= _CRS_Charging)
@@ -1437,14 +1750,14 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                     if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.PermissionRequest)
                     {
                         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.PermissionRequest = true;
-                        PRINTF_FUNC("Allow dispenser index %d connector id %d start to charge", dispenserIndex, packet->Header.id);
+                        PRINTF_FUNC("Allow dispenser index %d connector id %d start preparing to charge", dispenserIndex, packet->Header.id);
                     }
                     permission = _DAS_Allowed;
                 }
                 else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Terminating)
                 {
                     permission = _DAS_NotAllowed;
-                    PRINTF_FUNC("Allow dispenser index %d connector id %d start to charge", dispenserIndex, packet->Header.id);
+                    PRINTF_FUNC("Dispenser Terminating, Not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
                 }
                 else
                 {
@@ -1457,6 +1770,7 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
                 {
                     permission = _DAS_NotAllowed;
+                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d charging", dispenserIndex, packet->Header.id);
                 }
                 else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing ||
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Charging)
@@ -1470,13 +1784,15 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                 }
                 break;
 
-            case S_IDLE:
             case S_TERMINATING:
             case S_COMPLETE:
             case S_ALARM:
             case S_RESERVATION:
             case S_MAINTAIN:
                 permission = _DAS_NotAllowed;
+                PRINTF_FUNC("Cabinet status(%d) not match, not allow dispenser index %d connector id %d charging",
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus,
+                    dispenserIndex, packet->Header.id);
                 break;
 
             default:
@@ -1500,6 +1816,184 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
 	return permission;
 }
 
+BOOL MiscControlHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+    BOOL done = false;
+
+    if(find)
+    {
+        done = true;
+    }
+
+    return done;
+}
+
+unsigned char DispenserWriteCsuVersionInfoHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    char version[32];
+    BOOL writeVersion = FALSE, showVersion = FALSE;;
+
+    memcpy(version, &packet->Payload.data[0], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuBootLoadFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuBootLoadFwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[32], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuKernelFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuKernelFwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[64], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuRootFsFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuRootFsFwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[96], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuPrimFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuPrimFwRev, version, 32);
+        showVersion = true;
+    }
+
+    if(showVersion)
+    {
+        PRINTF_FUNC("********** Dispenser id %d:   Csu Version information **********", dispenserIndex + 1);
+        PRINTF_FUNC("********** CsuBootLoadRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuBootLoadFwRev);
+        PRINTF_FUNC("********** CsuKernelFwRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuKernelFwRev);
+        PRINTF_FUNC("********** CsuRootFsFwRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuRootFsFwRev);
+        PRINTF_FUNC("**********   CsuPrimFwRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].CsuPrimFwRev);
+    }
+    writeVersion = TRUE;
+
+    return writeVersion;
+}
+
+unsigned char DispenserWriteOtherVersionInfoHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    char version[32];
+    BOOL writeVersion = FALSE, showVersion = FALSE;;
+
+    memcpy(version, &packet->Payload.data[0], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].FanModuleFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].FanModuleFwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[32], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].RelayModuleFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].RelayModuleFwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[64], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector1FwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector1FwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[96], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector2FwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector2FwRev, version, 32);
+        showVersion = true;
+    }
+
+    memcpy(version, &packet->Payload.data[128], 32);
+    if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].LedModuleFwRev, version) != 0)
+    {
+        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].LedModuleFwRev, version, 32);
+        showVersion = true;
+    }
+
+    if(showVersion)
+    {
+        PRINTF_FUNC("********** Dispenser id %d: Other Version information **********", dispenserIndex + 1);
+        PRINTF_FUNC("********** FanModuleFwRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].FanModuleFwRev);
+        PRINTF_FUNC("********** RelayModuleRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].RelayModuleFwRev);
+        PRINTF_FUNC("**********  Connector1Rev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector1FwRev);
+        PRINTF_FUNC("**********  Connector2Rev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Connector2FwRev);
+        PRINTF_FUNC("********** LedModuleFwRev: %32s ***", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].LedModuleFwRev);
+    }
+    writeVersion = TRUE;
+
+    return writeVersion;
+}
+
+unsigned char DispenserWriteChargingInfoHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+
+    if(find)
+    {
+        unsigned short voltage = (packet->Payload.data[0] << 8) + (packet->Payload.data[1]);
+        unsigned short current = (packet->Payload.data[2] << 8) + (packet->Payload.data[3]);
+        unsigned int time = (packet->Payload.data[4] << 24) + (packet->Payload.data[5] << 16) + (packet->Payload.data[6] << 8) + (packet->Payload.data[7]);
+        unsigned char soc = (packet->Payload.data[8]);
+
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingVoltage = voltage;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingCurrent = current;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteRemainChargingDuration = time;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteSoc = soc;
+    }
+    else
+    {
+
+    }
+
+    return find;
+}
+
+unsigned char ReadChargerSystemIdHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    BOOL find = TRUE;
+
+    return find;
+}
+
+unsigned char WriteWaitPlugInHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
+{
+    BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+
+    if(find)
+    {
+        unsigned char StartWait = packet->Payload.data[0];
+
+        if(StartWait)
+        {
+            if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.StartWaitPlug)
+            {
+                PRINTF_FUNC("Connector %d Start Wait Plug In", packet->Header.id);
+            }
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.StartWaitPlug = true;
+        }
+        else
+        {
+            if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.StartWaitPlug)
+            {
+                PRINTF_FUNC("Connector %d Stop Wait Plug In", packet->Header.id);
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.NeedCleanAuthorizeInfo = true;
+            }
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.StartWaitPlug = false;
+        }
+    }
+    else
+    {
+
+    }
+
+    return find;
+}
+
 void DisableConnector(unsigned char dispenserIndex)
 {
 	for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorQuantity; i++)
@@ -1521,11 +2015,6 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 
 	PRINTF_FUNC("IP %s connection(%d) is established, start dispenser process", (inet_ntoa(clientInfo.sin_addr)), index);
 
-	for(int i = 0; i < CONNECTOR_QUANTITY; i++)
-	{
-	    memset(&_ConnectorCapabilityTime[i], 0x00, sizeof(struct timeval));
-	}
-
 	while(1)
 	{
 		if((rxLen = recv(socketFd, &receiveBuffer, sizeof(Packet_Structure), MSG_DONTWAIT )) > 0)
@@ -1555,6 +2044,7 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 	                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[index].DispenserIndex = dispenserIndex;
 	                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[index].Status = _CNS_DispenserMatched;
 	                                PRINTF_FUNC("********** Dispenser id %d check in, model name: %s **********\n", dispenserID, modelName);
+	                                memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ModelName, modelName, 64);
 	                                ackResult = _R_OK;
 	                            }
 	                            else
@@ -1600,6 +2090,19 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 						}
 						PRINTF_FUNC("Dispenser ID %d Get Connector ID %s", dispenserID, ackResult == _R_OK ? "OK" : "NG");
 						ConnectorIDResponse(socketFd, &receiveBuffer, ackResult, dispenserIndex);
+
+						if(ackResult == _R_OK)
+						{
+                            if(!ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DispenserConfigSync)
+                            {
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DispenserConfigSync = true;
+
+                                PRINTF_FUNC("Dispenser ID %d Configuration Need To Synchronize", dispenserID);
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.ConnectorTimeoutConfigRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DefaultPriceConfigRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.CurrencyConfigRequest = 1;
+                            }
+						}
 					}
 
 					// Reg: 0x03, Power cabinet status
@@ -1641,6 +2144,12 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 					}
 
 					// Reg: 0x07, Software update
+					if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Software_Update)
+					{
+					    unsigned char NeedUpgrade = FirmwareUpgradeHandler(&receiveBuffer, dispenserIndex);
+
+                        FirmwareUpgradeResponse(socketFd, &receiveBuffer, NeedUpgrade);
+					}
 
 					// Reg: 0x08, Plug-in status
 					if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_Plug_In_Status)
@@ -1677,9 +2186,68 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 					if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Charging_Permission)
 					{
 					    ack = ChargingPermissionHandler(&receiveBuffer, dispenserIndex);
-
 						ChargingPermissionResponse(socketFd, &receiveBuffer, ack);
 					}
+
+					// Reg: 0x0C, Misc Control
+					if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Misc_Control)
+					{
+					    if(MiscControlHandler(&receiveBuffer, dispenserIndex))
+					    {
+					        ackResult = _R_OK;
+					    }
+					    MiscControlResponse(socketFd, &receiveBuffer, dispenserIndex, ackResult);
+					}
+
+					// Reg: 0x0D, Report csu version
+					if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_Report_Csu_Version)
+                    {
+					    if(DispenserWriteCsuVersionInfoHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+					    WriteCsuVersionResponse(socketFd, &receiveBuffer, ackResult);
+                    }
+
+					// Reg: 0x0E, Report other version
+                    if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_Report_Other_Version)
+                    {
+                        if(DispenserWriteOtherVersionInfoHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+                        WriteOtherVersionResponse(socketFd, &receiveBuffer, ackResult);
+                    }
+
+                    // Reg: 0x0F, Charging info
+                    if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_Charging_Info)
+                    {
+                        if(DispenserWriteChargingInfoHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+                        WriteChargingInfoResponse(socketFd, &receiveBuffer, ackResult);
+                    }
+
+                    // Reg: 0x10, Charger system id
+                    if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Charger_System_Id)
+                    {
+                        if(ReadChargerSystemIdHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+                        ChargerSystemIdResponse(socketFd, &receiveBuffer, dispenserIndex, ackResult);
+                    }
+
+                    // Reg: 0x11, Wait plug in
+                    if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_WaitPlugIn)
+                    {
+                        if(WriteWaitPlugInHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+                        WriteWaitPlugInResponse(socketFd, &receiveBuffer, ackResult);
+                    }
 				}
 
 				// clean timeout
@@ -1694,8 +2262,9 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 
 		if(timeout >= DISPENSER_SOCKET_TIMEOUT)
 		{
-			//timeout
-			PRINTF_FUNC("IP: %s, Socket %d connection timeout", (inet_ntoa(clientInfo.sin_addr)), index);
+            //timeout
+            PRINTF_FUNC("IP: %s, Socket %d connection timeout", (inet_ntoa(clientInfo.sin_addr)), index);
+
 			if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[index].Status == _CNS_DispenserMatched)
 			{
 				DisableConnector(dispenserIndex);
@@ -1778,8 +2347,12 @@ void InitDispenserInfo(void)
 	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.Value = 0;
 	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AuthorizeStatus = 0;
 	    memset(&ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].WarningInfo, 0x00, sizeof(struct WARNING_CODE_INFO));
+
+	    //memset(&LastWarningInfo[i], 0x00, sizeof(struct WARNING_CODE_INFO));
 	}
 	memset(&ShmSysConfigAndInfo->SysInfo.DispenserInfo, 0x00, sizeof(struct DispenserInfoData));
+
+	ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency = ShmSysConfigAndInfo->SysConfig.BillingData.Currency;
 }
 
 void tcpSocketServerStart(void)
@@ -1817,7 +2390,28 @@ void tcpSocketServerStart(void)
 	while(1)
 	{
 		clientSockFd = accept(sockFd, (struct sockaddr*) &clientInfo, &addrlen);
-		PRINTF_FUNC("\nClient ip: %s is accepted at port: %d", inet_ntoa(clientInfo.sin_addr), clientInfo.sin_port);
+		/*
+		if((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == ENONET) ||
+            (errno == EPROTO) || (errno == ENOPROTOOPT) || (errno == EOPNOTSUPP) ||
+            (errno == ENETDOWN) || (errno == ENETUNREACH) || (errno == EHOSTDOWN) ||
+            (errno == EHOSTUNREACH) || (errno == ECONNABORTED))
+		{
+		    printf("accept error: %s\n", strerror(errno));
+            //exit(EXIT_FAILURE);
+            //break;
+		}
+		else if ( errno == EINTR)
+		{
+		    printf("accept EINTRn");
+		    continue;
+		}
+		else
+		{
+            printf("AccepCb: accept error: %s\n", strerror(errno));
+            //break;
+            //exit(EXIT_FAILURE);
+		}*/
+		PRINTF_FUNC("Client ip: %s is accepted at port: %d", inet_ntoa(clientInfo.sin_addr), clientInfo.sin_port);
 
 		connectIndex = FindFreeChannel();
 		if(connectIndex >= 0)

+ 43 - 0
EVSE/Projects/DO360/Apps/Module_EvComm.h

@@ -52,6 +52,12 @@ enum PAYLOAD_REGISTER
 	_Reg_Connector_State			= 0x09,
 	_Reg_User_ID					= 0x0A,
 	_Reg_Charging_Permission		= 0x0B,
+	_Reg_Misc_Control               = 0x0C,
+	_Reg_Report_Csu_Version         = 0x0D,
+	_Reg_Report_Other_Version       = 0x0E,
+	_Reg_Charging_Info              = 0x0F,
+	_Reg_Charger_System_Id          = 0x10,
+	_Reg_WaitPlugIn                 = 0x11,
 };
 
 enum Response_Result
@@ -60,6 +66,12 @@ enum Response_Result
 	_R_NG	= 0x02,
 };
 
+enum Response_Upgrade
+{
+    _R_NeedUpgrade  = 0x01,
+    _R_NoUpgrade    = 0x02,
+};
+
 enum PlugIn_Status
 {
 	_PIS_UnPlugged	= 0x00,
@@ -130,4 +142,35 @@ enum ConnectionStatus
 	_CNS_DispenserMatched		= 0x02,
 };
 
+struct MISC_COMMAND
+{
+    unsigned short  Command;
+    unsigned int    Value;
+};
+
+enum MiscCommand
+{
+    _MiscCmd_None               = 0x0000,
+    _MiscCmd_ConnectorTimeout   = 0x0001,
+    _MiscCmd_ChangeOperative    = 0x0002,
+    _MiscCmd_DefaultPrice       = 0x0003,
+    _MiscCmd_Currency           = 0x0004,
+    _MiscCmd_AccountBalance     = 0x0005,
+    _MiscCmd_HardwareReboot     = 0x0101,
+    _MiscCmd_SoftwareRestart    = 0x0102,
+    _MiscCmd_RemoteStart        = 0x0103,
+};
+
+struct ChargingCapabilityResponse
+{
+    unsigned char  ResponseResult;          // 1: OK, 2 NG
+    unsigned short MaxOuputVoltage;         // unit = 0.1 volt
+    unsigned short MaxOuputCurrent;         // unit = 0.1 Amp
+    unsigned short MaxOuputPower;           // unit = 0.1 kW
+    unsigned char  Currency;                // currency index
+    unsigned int   UserPrice;               // unit = 0.01 dollar
+    unsigned int   TotalCost;               // unit = 0.01 dollar
+    int            AccountBalance;          // unit = 0.01 dollar
+};
+
 #endif /* MODULE_EVCOMM_H_ */

+ 39 - 0
EVSE/Projects/DO360/Apps/Module_EventLogging.c

@@ -208,6 +208,9 @@ void RemoveFaultCodeToBuf(unsigned char *Code)
 	}
 }
 
+unsigned char MiscRequirement = 0;
+unsigned char VersionInfoRequirement = 0;
+
 int main(void)
 {
 	int ByteCount,BitCount;
@@ -228,6 +231,42 @@ int main(void)
 
 	for(;;)
 	{
+	    if(MiscRequirement != ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement)
+	    {
+	        memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
+            memcpy(EventCodeTmp, "B40001", sizeof(EventCodeTmp) - 1);
+
+	        if(ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement)
+	        {
+	            DEBUG_INFO("********** Misc Command Need Announcement **********\n");
+	            AddFaultCodeToBuf(EventCodeTmp);
+	        }
+	        else
+	        {
+	            DEBUG_INFO("********** Misc Command Announced **********\n");
+	            RemoveFaultCodeToBuf(EventCodeTmp);
+	        }
+	        MiscRequirement = ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement;
+	    }
+
+	    if(VersionInfoRequirement != ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo)
+	    {
+            memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
+            memcpy(EventCodeTmp, "B40999", sizeof(EventCodeTmp) - 1);
+
+	        if(ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo)
+	        {
+                DEBUG_INFO("********** Need Update Dispenser Version Info **********\n");
+                AddFaultCodeToBuf(EventCodeTmp);
+	        }
+	        else
+	        {
+	            DEBUG_INFO("********** Dispenser Version Info Updated **********\n");
+	            RemoveFaultCodeToBuf(EventCodeTmp);
+	        }
+	        VersionInfoRequirement = ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo;
+	    }
+
 		//check Fault Status
 		for(ByteCount=0;ByteCount<4;ByteCount++)
 		{

+ 555 - 24
EVSE/Projects/DO360/Apps/main.c

@@ -83,6 +83,12 @@
 #define		GUN_COMP_WAIT_TIMEOUT	10
 #define		GUN_PRECHARGING_TIMEOUT	60
 
+#define     REBOOT_TIMEOUT              10
+#define     RESET_TIMEOUT               10
+#define     OCPP_COST_REQ_INTERVAL      5
+#define     DISPENSER_RECONNECTE_TIME   30
+#define     FORCE_BALANCE_TIME          5
+
 char 	*valid_Internet[2] 	  = {"8.8.8.8", "180.76.76.76"};
 unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
 int whileLoopTime = 10000; // 10 ms
@@ -168,7 +174,7 @@ bool isModelNameMatch = true;
 
 //int rfidFd = -1;
 //char* rfidPortName = "/dev/ttyS2";
-char* fwVersion = "D0.05.00.0000.00";
+char* fwVersion = "D0.06.00.0000.00";
 
 sqlite3 *localDb;
 bool isDb_ready;
@@ -307,7 +313,7 @@ int StoreLogMsg_1(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]SystemLog",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
 			tm->tm_year+1900,tm->tm_mon+1);
@@ -1050,6 +1056,9 @@ int isReachableInternet()
 
 void InitEthernet()
 {
+    system("ifconfig eth0 down");
+    system("ifconfig eth1 down");
+    sleep(2);
 	char tmpbuf[256];
 	// /sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 down
 	system("echo 1 > /sys/class/gpio/gpio110/value");//reset PHY
@@ -3107,6 +3116,43 @@ void PowerCabinetAuthorizingSettingInitial(void)
     ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.StartAuthorize = false;
     ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.AuthorizingCompleted = false;
     ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.AuthorizeTargetIndex = 0;
+    ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.BackendAuthorized = false;
+}
+
+void FouceAnnounceAccountBalance(unsigned char index, unsigned char AuthorizeSrc)
+{
+    switch(AuthorizeSrc)
+    {
+        case _AuthorizeSrc_Local:
+            for(int i = 0; i < 2; i++)
+            {
+                if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].ConnectorID[i] != 0)
+                {
+                    unsigned char ConnectorIndex =  ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].ConnectorID[i] - 1;
+
+                    if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AnnounceBalance)
+                    {
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AnnounceBalance = true;
+
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].AccountBalance = 0;
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AccountBalanceRequest = true;
+                        PRINTF_FUNC("Force Announce Account Balance To Dispenser %d Connector %d", index + 1, ConnectorIndex + 1);
+                    }
+                }
+            }
+
+            break;
+        case _AuthorizeSrc_Remote:
+            if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance)
+            {
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance = true;
+
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].AccountBalance = 0;
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AccountBalanceRequest = true;
+                PRINTF_FUNC("Force Announce Account Balance To Connector %d", index + 1);
+            }
+            break;
+    }
 }
 
 void AuthorizingSettingInitial(unsigned char index, unsigned char AuthorizeSrc)
@@ -3131,6 +3177,15 @@ void AuthorizingSettingInitial(unsigned char index, unsigned char AuthorizeSrc)
                     {
                         PRINTF_FUNC("*********** Connector id %d AuthorizeReqClean ***********", ConnectorIndex + 1);
                         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AuthorizeRequestType = _AuthorizeSrc_None;
+
+                        if(chargingInfo[ConnectorIndex]->SystemStatus == S_IDLE)
+                        {
+                            PRINTF_FUNC("*********** Connector id %d Clean UserId & UserPrice ***********", ConnectorIndex + 1);
+                            memset(chargingInfo[ConnectorIndex]->StartUserId, 0x00, 32);
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].UserPrice = 0;
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].AccountBalance = -6553500;
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AnnounceBalance = false;
+                        }
                     }
                 }
             }
@@ -3146,6 +3201,15 @@ void AuthorizingSettingInitial(unsigned char index, unsigned char AuthorizeSrc)
             {
                 PRINTF_FUNC("*********** Connector id %d AuthorizeReqClean ***********", index + 1);
                 ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AuthorizeRequestType = _AuthorizeSrc_None;
+
+                if(chargingInfo[index]->SystemStatus == S_IDLE)
+                {
+                    PRINTF_FUNC("*********** Connector id %d Clean UserId & UserPrice ***********", index + 1);
+                    memset(chargingInfo[index]->StartUserId, 0x00, 32);
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].UserPrice = 0;
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].AccountBalance = -6553500;
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance = false;
+                }
             }
             break;
     }
@@ -3197,6 +3261,13 @@ void SetConnectorAuthorizeOK(unsigned char index, unsigned char AuthorizeSrc)
                         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AuthorizeRequestType = _AuthorizeSrc_Local;
                         memcpy(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].GeneralChargingData.StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, 32);
                         PRINTF_FUNC("*********** Connector id %d LocalAuthorize OK ***********", ConnectorIndex + 1);
+
+                        if(!ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.BackendAuthorized)
+                        {
+                            // authorized without backend need to trigger announce AccountBalance
+                            //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].AccountBalance = 0;
+                            //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[ConnectorIndex].Parameter.bits.AccountBalanceRequest = true;
+                        }
                     }
                 }
             }
@@ -3227,6 +3298,11 @@ void AuthorizeTimeoutProcess(void)
         switch(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].AuthorizeStatus)
         {
             case _AuthorizeStatus_Pass:
+                if(GetTimeoutValue(_ConnectorAuthorizing_Time[index]) / uSEC_VAL >= FORCE_BALANCE_TIME)
+                {
+                    FouceAnnounceAccountBalance(index, _AuthorizeSrc_Remote);
+                }
+
                 if(GetTimeoutValue(_ConnectorAuthorizing_Time[index]) / uSEC_VAL >= _connectionTimeout)
                 {
                     PRINTF_FUNC("*********** Connector id %d  Plug In Timeout  ***********\n", index + 1);
@@ -3235,6 +3311,8 @@ void AuthorizeTimeoutProcess(void)
                 break;
 
             case _AuthorizeStatus_Fail:
+                FouceAnnounceAccountBalance(index, _AuthorizeSrc_Remote);
+
                 if(GetTimeoutValue(_ConnectorAuthorizing_Time[index]) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT)
                 {
                     PRINTF_FUNC("*********** Connector id %d Authorized Return ***********", index + 1);
@@ -3250,6 +3328,11 @@ void AuthorizeTimeoutProcess(void)
         switch(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].AuthorizeStatus)
         {
             case _AuthorizeStatus_Pass:
+                if(GetTimeoutValue(_DispenserAuthorizing_Time[index]) / uSEC_VAL >= FORCE_BALANCE_TIME)
+                {
+                    FouceAnnounceAccountBalance(index, _AuthorizeSrc_Local);
+                }
+
                 if(GetTimeoutValue(_DispenserAuthorizing_Time[index]) / uSEC_VAL >= _connectionTimeout)
                 {
                     PRINTF_FUNC("*********** Dispenser id %d  Plug In Timeout  ***********\n", index + 1);
@@ -3258,6 +3341,8 @@ void AuthorizeTimeoutProcess(void)
                 break;
 
             case _AuthorizeStatus_Fail:
+                FouceAnnounceAccountBalance(index, _AuthorizeSrc_Local);
+
                 if(GetTimeoutValue(_DispenserAuthorizing_Time[index]) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT)
                 {
                     PRINTF_FUNC("*********** Dispenser id %d Authorized Return ***********", index + 1);
@@ -3371,6 +3456,7 @@ void PowerCabinetAuthorizeProcess(void)
                                 PRINTF_FUNC("*********** %s id %d OCPP Authorize %s ***********",
                                     str_auth_src[ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.AuthorizeSrc], target + 1, accept ? "OK" : "NG");
                                 *AuthorizeStatus = accept ? _AuthorizeStatus_Pass : _AuthorizeStatus_Fail;
+                                ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.BackendAuthorized = true;
                             }
                         }
                         else
@@ -4039,6 +4125,25 @@ void StopGunInfoTimeoutDet(unsigned char gunIndex)
 	}
 }
 
+void TriggerDispenserConnectionTimeoutSetting(void)
+{
+    BOOL trigger = FALSE;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.ConnectorTimeoutConfigRequest = 1;
+            trigger = TRUE;
+        }
+    }
+
+    if(trigger)
+    {
+        PRINTF_FUNC("********** Trigger Dispenser Connector Timeout Value: %d **********\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout);
+    }
+}
+
 void CheckConnectionTimeout(void)
 {
 	if(system("pidof -s OcppBackend > /dev/null") != 0)
@@ -4060,6 +4165,12 @@ void CheckConnectionTimeout(void)
 			_connectionTimeout = CONN_PLUG_TIME_OUT;
 		}
 	}
+
+	if(_connectionTimeout != ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout)
+	{
+	    ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout = _connectionTimeout;
+	    TriggerDispenserConnectionTimeoutSetting();
+	}
 }
 
 void CreateTimeoutFork()
@@ -4336,6 +4447,311 @@ int isReservationExpired(unsigned char gun_index)
 	return result;
 }
 
+struct timeval _Reboot_time;
+
+void TriggerDispenserHardwareReboot(void)
+{
+    BOOL trigger = FALSE;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootConfirm &&
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootRequest == 0)
+            {
+                trigger = TRUE;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootRequest = 1;
+            }
+        }
+    }
+
+    if(trigger)
+    {
+        gettimeofday(&_Reboot_time, NULL);
+        PRINTF_FUNC("********** Trigger Dispenser Hardware Reboot **********");
+    }
+}
+
+BOOL IsDispenserHardwareRebootResponsed(void)
+{
+    BOOL response_ok = TRUE;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            if(!ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootConfirm)
+            {
+                response_ok = FALSE;
+
+                // 10s for reboot request timeout
+                if((GetTimeoutValue(_Reboot_time) / uSEC_VAL) >= REBOOT_TIMEOUT)
+                {
+                    response_ok = TRUE;
+                    PRINTF_FUNC("Reboot request timeout");
+                }
+            }
+        }
+    }
+
+    return response_ok;
+}
+
+struct timeval _Reset_time;
+
+void TriggerDispenserSoftwareReset(void)
+{
+    BOOL trigger = FALSE;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetConfirm == 0 &&
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetRequest == 0)
+            {
+                trigger = TRUE;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetRequest = 1;
+            }
+        }
+    }
+
+    if(trigger)
+    {
+        gettimeofday(&_Reset_time, NULL);
+        PRINTF_FUNC("********** Trigger Dispenser Software Reset **********");
+    }
+}
+
+BOOL IsDispenserSoftwareResetResponsed(void)
+{
+    BOOL response_ok = TRUE;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            if(!ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetConfirm)
+            {
+                response_ok = FALSE;
+
+                // 10s for reset request timeout
+                if((GetTimeoutValue(_Reset_time) / uSEC_VAL) >= RESET_TIMEOUT)
+                {
+                    response_ok = TRUE;
+                    PRINTF_FUNC("Reset request timeout");
+                }
+            }
+        }
+    }
+
+    return response_ok;
+}
+
+// the unit of return value: 0.01 dollar
+int TariffParsing(char *StringItem, char *TariffCode)
+{
+    char *ptrSave, *ptrToken;
+    char strSource[128];
+    int fee = 0;
+
+    memcpy(strSource, StringItem, 128);
+
+    ptrToken = strtok_r(strSource, ";", &ptrSave);
+    while(ptrToken != NULL)
+    {
+        char *strTariff = strstr(ptrToken, TariffCode);
+        if(strTariff != NULL)
+        {
+            char *strFee = strstr(strTariff, "$");
+            if(strFee != NULL)
+            {
+                strFee++;
+                float fFee = atof(strFee);
+                fee = (int)(fFee * 100);
+                break;
+            }
+        }
+        ptrToken = strtok_r(NULL, ";", &ptrSave);
+    }
+    return fee;
+}
+
+void DefaultPriceHandler(char *StrDefaultPrice)
+{
+    BOOL trigger = FALSE;
+    unsigned int ConnectionFee = 0, CurrentRate = 0, OccupancyFee = 0;
+
+    PRINTF_FUNC("********** Default Price: %s", StrDefaultPrice);
+    ConnectionFee = TariffParsing(StrDefaultPrice, "Connection Fee");
+    PRINTF_FUNC("**********  Connection Fee: %d.%02d **********", (ConnectionFee / 100), (ConnectionFee % 100));
+    CurrentRate = TariffParsing(StrDefaultPrice, "Current Rate");
+    PRINTF_FUNC("**********    Current Rate: %d.%02d **********", (CurrentRate / 100), (CurrentRate % 100));
+    OccupancyFee = TariffParsing(StrDefaultPrice, "Occupancy Fee");
+    PRINTF_FUNC("**********   Occupancy Fee: %d.%02d **********", (OccupancyFee / 100), (OccupancyFee % 100));
+
+    ShmSysConfigAndInfo->SysInfo.DispenserInfo.DefaultPrice = CurrentRate;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.DefaultPriceConfigRequest == 0)
+            {
+                trigger = TRUE;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.DefaultPriceConfigRequest = 1;
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.CurrencyConfigRequest = 1;
+            }
+        }
+    }
+
+    if(trigger)
+    {
+        PRINTF_FUNC("********** Trigger Dispenser Default Price **********");
+    }
+}
+
+void UserPriceHandler(char *UserId, char *UserPrice)
+{
+    unsigned int ConnectionFee = 0, CurrentRate = 0, OccupancyFee = 0;
+    int AccountBalance = 0;
+
+    ConnectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Connection Fee");
+    CurrentRate = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Current Rate");
+    OccupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Occupancy Fee");
+    AccountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Account Balance");
+
+    PRINTF_FUNC("********** User Id: %s **********", ShmOCPP16Data->Cost.SetUserPrice.idToken);
+    PRINTF_FUNC("********** User Price: %s", ShmOCPP16Data->Cost.SetUserPrice.price);
+    PRINTF_FUNC("**********  Connection Fee: %d.%02d **********", (ConnectionFee / 100), (ConnectionFee % 100));
+    PRINTF_FUNC("**********    Current Rate: %d.%02d **********", (CurrentRate / 100), (CurrentRate % 100));
+    PRINTF_FUNC("**********   Occupancy Fee: %d.%02d **********", (OccupancyFee / 100), (OccupancyFee % 100));
+    PRINTF_FUNC("********** Account Balance: %d.%02d **********", (AccountBalance / 100), (AccountBalance % 100));
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(strcmp((char *)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.StartUserId, UserId) == EQUAL)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].UserPrice != CurrentRate ||
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance != AccountBalance)
+            {
+                PRINTF_FUNC("********** Connector Id %d User Price %d.%02d, Account Balance %d.%02d **********",
+                    (i + 1), (CurrentRate / 100), (CurrentRate % 100), (AccountBalance / 100), (AccountBalance % 100));
+            }
+
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].UserPrice = CurrentRate;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance = AccountBalance;
+
+            int DispenserIndex = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].ParentDispensetIndex;
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].AuthorizeStatus == _AuthorizeStatus_Pass &&
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AuthorizeRequestType == _AuthorizeSrc_Local)
+            {
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AccountBalanceRequest = true;
+            }
+        }
+    }
+}
+
+void RunningFinalCostHandler(void)
+{
+    unsigned int ConnectionFee = 0, SessionFee = 0, OccupancyFee = 0, TotalCost = 0;
+    int AccountBalance = 0;
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.SystemStatus >= S_REASSIGN_CHECK &&
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.SystemStatus <= S_COMPLETE)
+        {
+            if(strlen((char *)ShmOCPP16Data->Cost.RunningCost[i].description) > 0)
+            {
+                ConnectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[i].description, "Connection Fee");
+                SessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[i].description, "Session Fee");
+                OccupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[i].description, "Occupancy Fee");
+                TotalCost = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[i].description, "Total Cost");
+                AccountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[i].description, "Account Balance");
+
+                PRINTF_FUNC("********** Connector Id: %d Running Cost **********", (i + 1));
+                PRINTF_FUNC("**********  Connection Fee: %d.%02d **********", (ConnectionFee / 100), (ConnectionFee % 100));
+                PRINTF_FUNC("**********     Session Fee: %d.%02d **********", (SessionFee / 100), (SessionFee % 100));
+                PRINTF_FUNC("**********   Occupancy Fee: %d.%02d **********", (OccupancyFee / 100), (OccupancyFee % 100));
+                PRINTF_FUNC("**********      Total Cost: %d.%02d **********", (TotalCost / 100), (TotalCost % 100));
+                PRINTF_FUNC("********** Account Balance: %d.%02d **********", (AccountBalance / 100), (AccountBalance % 100));
+
+                if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].TotalCost != TotalCost ||
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance != AccountBalance)
+                {
+                    PRINTF_FUNC("********** Connector Id %d Total Cost %d.%02d, Account Balance %d.%02d **********",
+                        (i + 1), (TotalCost / 100), (TotalCost % 100), (AccountBalance / 100), (AccountBalance % 100));
+                }
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].TotalCost = TotalCost;
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance = AccountBalance;
+
+                memset(&ShmOCPP16Data->Cost.RunningCost[i], 0x00, sizeof(struct StrcutRunningFinalCost));
+            }
+
+            if(strlen((char *)ShmOCPP16Data->Cost.FinalCost[i].description) > 0)
+            {
+                ConnectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[i].description, "Connection Fee");
+                SessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[i].description, "Session Fee");
+                OccupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[i].description, "Occupancy Fee");
+                TotalCost = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[i].description, "Total Cost");
+                AccountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[i].description, "Account Balance");
+
+                PRINTF_FUNC("********** Connector Id: %d Final Cost **********", (i + 1));
+                PRINTF_FUNC("**********  Connection Fee: %d.%02d **********", (ConnectionFee / 100), (ConnectionFee % 100));
+                PRINTF_FUNC("**********     Session Fee: %d.%02d **********", (SessionFee / 100), (SessionFee % 100));
+                PRINTF_FUNC("**********   Occupancy Fee: %d.%02d **********", (OccupancyFee / 100), (OccupancyFee % 100));
+                PRINTF_FUNC("**********      Total Cost: %d.%02d **********", (TotalCost / 100), (TotalCost % 100));
+                PRINTF_FUNC("********** Account Balance: %d.%02d **********", (AccountBalance / 100), (AccountBalance % 100));
+
+                if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].TotalCost != TotalCost ||
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance != AccountBalance)
+                {
+                    PRINTF_FUNC("********** Connector Id %d Total Cost %d.%02d, Account Balance %d.%02d **********",
+                        (i + 1), (TotalCost / 100), (TotalCost % 100), (AccountBalance / 100), (AccountBalance % 100));
+                }
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].TotalCost = TotalCost;
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance = AccountBalance;
+
+                memset(&ShmOCPP16Data->Cost.FinalCost[i], 0x00, sizeof(struct StrcutRunningFinalCost));
+            }
+        }
+    }
+}
+
+struct timeval _Cost_Price_time;
+char MyDefaultPriceString[128];
+struct StrcutSetUserPrice MyUserPrice;
+char MyConnectorRunningCostString[CONNECTOR_QUANTITY][128];
+char MyConnectorFinalCostString[CONNECTOR_QUANTITY][128];
+
+void CheckOcppCostAndPrice(void)
+{
+    // 5s for reboot request timeout
+    if((GetTimeoutValue(_Cost_Price_time) / uSEC_VAL) >= OCPP_COST_REQ_INTERVAL)
+    {
+        gettimeofday(&_Cost_Price_time, NULL);
+
+        if(strcmp(MyDefaultPriceString, (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData) != EQUAL)
+        {
+            DefaultPriceHandler((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData);
+
+            memcpy(MyDefaultPriceString, ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData, 128);
+        }
+
+        if(strlen((char *)ShmOCPP16Data->Cost.SetUserPrice.idToken) > 0 && strlen((char *)ShmOCPP16Data->Cost.SetUserPrice.price) > 0)
+        {
+            UserPriceHandler((char *)ShmOCPP16Data->Cost.SetUserPrice.idToken, (char *)ShmOCPP16Data->Cost.SetUserPrice.price);
+
+            memset(&ShmOCPP16Data->Cost.SetUserPrice, 0x00, sizeof(struct StrcutSetUserPrice));
+        }
+
+        RunningFinalCostHandler();
+    }
+}
+
 //===============================================
 // OCPP
 //===============================================
@@ -4367,28 +4783,47 @@ void CheckOcppStatus()
 			}
 		}
 
-		if (canReset)
+		if(canReset)
 		{
-			ShmOCPP16Data->MsMsg.bits.ResetReq = NO;
-			sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted");
-			if(strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL)
-			{
-				DEBUG_ERROR_MSG("****** Hard Reboot ****** \n");
-				ShmOCPP16Data->MsMsg.bits.ResetConf = YES;
-				sleep(3);
-				system("reboot -f");
-			}
-			else if (strcmp((char *)ShmOCPP16Data->Reset.Type, "Soft") == EQUAL)
-			{
-				DEBUG_ERROR_MSG("****** Soft Reboot ****** \n");
-				ShmOCPP16Data->MsMsg.bits.ResetConf = YES;
-				sleep(3);
-				system("killall OcppBackend &");
-				KillTask();
-				system("/usr/bin/run_evse_restart.sh");
-			}
+		    if(strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL)
+		    {
+                //trigger dispenser to hardware reboot
+                TriggerDispenserHardwareReboot();
+
+                if(IsDispenserHardwareRebootResponsed())
+                {
+                    ShmOCPP16Data->MsMsg.bits.ResetReq = NO;
+                    sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted");
+                    DEBUG_ERROR_MSG("****** Hard Reboot ****** \n");
+
+                    ShmOCPP16Data->MsMsg.bits.ResetConf = YES;
+                    sleep(3);
+                    system("reboot -f");
+                }
+		    }
+
+		    if(strcmp((char *)ShmOCPP16Data->Reset.Type, "Soft") == EQUAL)
+		    {
+                //trigger dispenser to software reset
+                TriggerDispenserSoftwareReset();
+
+                if(IsDispenserSoftwareResetResponsed())
+                {
+                    ShmOCPP16Data->MsMsg.bits.ResetReq = NO;
+                    sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted");
+                    DEBUG_ERROR_MSG("****** Soft Reboot ****** \n");
+
+                    ShmOCPP16Data->MsMsg.bits.ResetConf = YES;
+                    sleep(3);
+                    system("killall OcppBackend &");
+                    KillTask();
+                    system("/usr/bin/run_evse_restart.sh");
+                }
+		    }
 		}
 	}
+
+	CheckOcppCostAndPrice();
 }
 
 void OcppStartTransation(byte gunIndex)
@@ -4551,6 +4986,7 @@ void ChkOcppStatus(byte gunIndex)
                 DB_Update_Operactive(localDb, gunIndex, true);
 
             chargingInfo[gunIndex]->IsAvailable = YES;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].Parameter.bits.AvailabilityRequest = 1;
 
 			if (chargingInfo[gunIndex]->SystemStatus == S_IDLE ||
 				chargingInfo[gunIndex]->SystemStatus == S_RESERVATION ||
@@ -4565,6 +5001,7 @@ void ChkOcppStatus(byte gunIndex)
                 DB_Update_Operactive(localDb, gunIndex, false);
 
             chargingInfo[gunIndex]->IsAvailable = NO;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].Parameter.bits.AvailabilityRequest = 1;
 
 			if (chargingInfo[gunIndex]->SystemStatus == S_IDLE ||
 				chargingInfo[gunIndex]->SystemStatus == S_RESERVATION ||
@@ -5282,13 +5719,60 @@ bool GetStartChargingByAlterMode(byte _gun)
 	return result;
 }
 
+void CheckMiscCommandRequirement(void)
+{
+    BOOL NeedAnnouncement = FALSE;
 
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AvailabilityRequest ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.RemoteStartRequest ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AccountBalanceRequest)
+        {
+            NeedAnnouncement = TRUE;
+        }
 
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.ConnectorTimeoutConfigRequest ||
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.DefaultPriceConfigRequest ||
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.CurrencyConfigRequest ||
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootRequest ||
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetRequest)
+        {
+            NeedAnnouncement = TRUE;
+        }
+    }
+
+    ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement = NeedAnnouncement;
+}
 
+void CheckDispenserVersionUpdateRequirement(void)
+{
 
+}
 
+void DispenserConnectionRetryHandler(void)
+{
+    unsigned short _timeout = 0;
+    unsigned int _price = 0;
+    unsigned char _currency = 0;
 
-struct timeval _dispenserDisconnection_time;
+    PRINTF_FUNC("********** Kill ModuleEvComm Task & Retry To Excute ModuleEvComm **********");
+
+    _timeout = ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout;
+    _price = ShmSysConfigAndInfo->SysInfo.DispenserInfo.DefaultPrice;
+    _currency = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency;
+
+    system("killall Module_EvComm");
+    usleep(100000);
+    system("/root/Module_EvComm &");
+    usleep(100000);
+
+    ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectorTimeout = _timeout;
+    ShmSysConfigAndInfo->SysInfo.DispenserInfo.DefaultPrice = _price;
+    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency = _currency;
+}
+
+struct timeval _dispenserDisconnection_time, _dispenserConnectionRetry_time;
 
 int main(void)
 {
@@ -5475,6 +5959,17 @@ int main(void)
 		{
             if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity == 0)
             {
+                if(ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.DispenserDisconnection == 0)
+                {
+                    ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.DispenserDisconnection = 1;
+                    gettimeofday(&_dispenserConnectionRetry_time, NULL);
+                }
+                if((GetTimeoutValue(_dispenserConnectionRetry_time) / uSEC_VAL) >= DISPENSER_RECONNECTE_TIME)
+                {
+                    DispenserConnectionRetryHandler();
+                    gettimeofday(&_dispenserConnectionRetry_time, NULL);
+                }
+
                 if((GetTimeoutValue(_dispenserDisconnection_time) / 1000) >= 1000)
                 {
                     ShmPrimaryMcuData->OutputDrv.bits.SystemLed2Drv = ShmPrimaryMcuData->OutputDrv.bits.SystemLed1Drv ? false : true;
@@ -5484,11 +5979,15 @@ int main(void)
             }
             else
             {
+                ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.DispenserDisconnection = 0;
                 ShmPrimaryMcuData->OutputDrv.bits.SystemLed1Drv = true;
                 ShmPrimaryMcuData->OutputDrv.bits.SystemLed2Drv = false;
             }
 		}
 
+		CheckMiscCommandRequirement();
+		CheckDispenserVersionUpdateRequirement();
+
 		for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
 		{
 			//CheckGpioInStatus();
@@ -5532,6 +6031,19 @@ int main(void)
 						strcpy((char *)chargingInfo[gun_index]->StopDateTime, "");
 						strcpy((char *)chargingInfo[gun_index]->StartUserId, "");
 						strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "");
+
+						// clean connector infomation
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteChargingVoltage = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteChargingCurrent = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteRemainChargingDuration = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteSoc = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].UserPrice = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].TotalCost = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].AccountBalance = -6553500;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.AnnounceBalance = false;
+
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.StartWaitPlug = false;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.NeedCleanAuthorizeInfo = false;
 					}
 					else if (chargingInfo[gun_index]->SystemStatus == S_RESERVATION &&
 							isModeChange(gun_index))
@@ -5547,7 +6059,7 @@ int main(void)
 
 					if (ShmSysConfigAndInfo->SysWarningInfo.Level == 2)
 					{
-						if (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected)
+						//if (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected)
 						{
 							ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_FIX;
 						}
@@ -5629,6 +6141,25 @@ int main(void)
                                     }
                                     continue;
                                 }
+                                else
+                                {
+                                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.NeedCleanAuthorizeInfo)
+                                    {
+                                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.StartWaitPlug = false;
+                                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.NeedCleanAuthorizeInfo = false;
+
+                                        PRINTF_FUNC("Connector %d Stop Wait Plug In", gun_index + 1);
+
+                                        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.AuthorizeRequestType == _AuthorizeSrc_Local)
+                                        {
+                                            AuthorizingSettingInitial(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].ParentDispensetIndex, _AuthorizeSrc_Local);
+                                        }
+                                        else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.AuthorizeRequestType == _AuthorizeSrc_Remote)
+                                        {
+                                            AuthorizingSettingInitial(gun_index, _AuthorizeSrc_Remote);
+                                        }
+                                    }
+                                }
 
                                 /*
 								// 卡號驗證成功後,等待充電槍插入充電車
@@ -6207,7 +6738,7 @@ int main(void)
 					    }
 					}
 
-					if(chargingInfo[gun_index]->ConnectorPlugIn == NO &&
+					if((chargingInfo[gun_index]->ConnectorPlugIn == NO || ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Enable == false) &&
                         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.PsuReleasable)
 					{
 						setChargerMode(gun_index, MODE_IDLE);

二进制
EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin


二进制
EVSE/Projects/DO360/Images/ramdisk.gz


+ 223 - 193
EVSE/Projects/define.h

@@ -1,4 +1,4 @@
-#ifndef	DEFINE_H_
+#ifndef	DEFINE_H_
 #define	DEFINE_H_
 
 /**************************************************************************************/
@@ -473,7 +473,7 @@ struct ChargingInfoData
 	float PilotVoltage;
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
-	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID,back-end,BLE.
+	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
@@ -528,8 +528,16 @@ typedef union
     unsigned int SettingValue;
     struct
     {
-        unsigned int AuthorizeRequest:1;        // 0: idle, 1: requesting
-        unsigned int res:31;
+        unsigned int DispenserConfigSync:1;             // 0: not synced,   1: synced
+        unsigned int AuthorizeRequest:1;                // 0: idle,         1: requesting                           ( dispenser -> cabinet)
+        unsigned int ConnectorTimeoutConfigRequest:1;   // 0: no request,   1: connector timeout setting            (    ocpp   -> cabinet -> dispenser)
+        unsigned int DefaultPriceConfigRequest:1;       // 0: no request,   1: default price setting                (    ocpp   -> cabinet -> dispenser)
+        unsigned int CurrencyConfigRequest:1;           // 0: no request,   1: currency setting                     (    ocpp   -> cabinet -> dispenser)
+        unsigned int HardwareRebootRequest:1;           // 0: no request,   1: hardware reboot request              (    ocpp   -> cabinet -> dispenser)
+        unsigned int HardwareRebootConfirm:1;           // 0: no effect,    1: dispenser confirmed
+        unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
+        unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
+        unsigned int res:23;
     }bits;
 }DispenserSettingFlag;
 
@@ -601,6 +609,10 @@ struct DispenserInfoData
     }CheckInLog;                                                        // record dispenser checkin status
     unsigned char               ConnectorLog[GENERAL_GUN_QUANTITY];     // record connector quantity of dispenser
     struct ConnectionInfoData   ConnectionInfo[GENERAL_GUN_QUANTITY];
+
+    unsigned short      ConnectorTimeout;           // connector plug in timeout, unit 1s
+    unsigned int        DefaultPrice;               // dispenser default price, unit: 0.01 (dollar/kWh)
+    unsigned char       Currency;                   // dispenser currency index
 };
 
 struct WARNING_CODE_INFO
@@ -618,13 +630,18 @@ typedef union
     struct
     {
         unsigned int  AuthorizeRequestType:4;           // 0: not authorize, 1: local authorized, 2: remote start authorized
-        unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging
-        unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start
-        unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop
-        unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop
-        unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop
+        unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging                   ( dispenser -> cabinet)
+        unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
+        unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop                                     (    ocpp   -> cabinet -> dispenser)
+        unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop                                     (    ocpp   -> cabinet -> dispenser)
+        unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop                           ( dispenser -> cabinet)
         unsigned int  PsuReleasable:1;
-        unsigned int  res:22;
+        unsigned int  AvailabilityRequest:1;            // 0: no request,    1: change availability                             (    ocpp   -> cabinet -> dispenser)
+        unsigned int  AccountBalanceRequest:1;          // 0: no request,    1: set account balance                             (    ocpp   -> cabinet -> dispenser)
+        unsigned int  AnnounceBalance:1;                //
+        unsigned int  StartWaitPlug:1;                  //
+        unsigned int  NeedCleanAuthorizeInfo:1;         //
+        unsigned int  res:17;
     }bits;
 }ConnectorParameter;
 
@@ -632,13 +649,22 @@ struct ConnectorInfoData
 {
     unsigned char RemoteStatus;                         // 0: Idle, 1: Preparing, 2: Charging, 3: Terminating
     unsigned char Enable;                               // 0: Disable, 1: Enable
-    unsigned char ReadyToCharge;                        // 0: Not Ready, 1: Ready to Charge
+    unsigned char ReadyToCharge;                        // 0: Not Ready, 1: Ready to Charge (no use)
     unsigned char ParentDispensetIndex;                 // Parent Dispenser Index: 0 ~ 3
     ConnectorParameter       Parameter;
                                                         // 0: Authorize idle, 1: Authorize wait,   2: Authorizing
     unsigned char            AuthorizeStatus;           // 3: Authorize ok,   4: Authorizing fail
     struct ChargingInfoData  GeneralChargingData;
     struct WARNING_CODE_INFO WarningInfo;
+
+    unsigned short          RemoteChargingVoltage;          // charging voltage from connector, unit: 0.1V
+    unsigned short          RemoteChargingCurrent;          // charging current from connector, unit: 0.1A
+    unsigned int            RemoteRemainChargingDuration;   // remain charging duration from connector, unit: 1s
+    unsigned char           RemoteSoc;                      // ev battery soc from connector, unit: 1%
+
+    unsigned int            UserPrice;                      // connector user's user price, unit: 0.01 (dollar / kWh)
+    unsigned int            TotalCost;                      // connector user's total cost, unit: 0.01 dollar
+    int                     AccountBalance;                 // connector user's account balance, unit: 0.01 dollar
 };
 
 typedef union
@@ -650,7 +676,11 @@ typedef union
         unsigned int AuthorizingCompleted:1;    // 0: not yet, 1: authorizing completed
         unsigned int AuthorizeTargetIndex:4;    // dispenser or connector index from 0 ~ 3
         unsigned int AuthorizeSrc:4;            // 0: not authorize, 1: local authorize, 2: remote authorize
-        unsigned int res:22;
+        unsigned int MiscNeedAnnouncement:1;    // 0: no requirement, 1: need to announce something to dispenser
+        unsigned int NeedDispenserVerInfo:1;    // 0: no requirement, 1: need dispenser to report it's version info
+        unsigned int DispenserDisconnection:1;  // 0: no connection,  1: dispenser connected
+        unsigned int BackendAuthorized:1;       // 0: local authorized, 1: backend authorized
+        unsigned int res:18;
     }bits;
 }CabinetSettingFlag;
 
@@ -911,7 +941,7 @@ struct FaultCodeData
 			unsigned char ShutterFault:1;						//bit 1
 			unsigned char BleModuleBroken:1;					//bit 2
 			unsigned char RotarySwitchFault:1;					//bit 3 
-			unsigned char CcsLiquidChillerWaterLevelFault:1;			//bit 4 
+			unsigned char CcsLiquidChillerWaterLevelFault:1;    //bit 4
 			unsigned char :3;									//bit 5 ~ 7	reserved
 		}bits;
 	}FaultEvents;
@@ -1022,9 +1052,9 @@ char AlarmStatusCode[128][6]=
 	"012300",	// System AC output OCP L3
 	"012301",	// Circuit Short L2
 	"012302",	// Circuit Short L3
-	"012303",	// CCS liquid chiller water level warning
-	"012304",	// connection disconnected from power cabinet
-	"012305",	// Meter communication timeout
+	"012303",   // CCS liquid chiller water level warning
+	"012304",   // connection disconnected from power cabinet
+	"012305",   // Meter communication timeout
 
 };
 struct AlarmCodeData
@@ -1140,9 +1170,9 @@ struct AlarmCodeData
 			unsigned char GbtOutputUVPFail :1;					//bit 2
 			unsigned char GbtboardStestFail :1;					//bit 3
 			unsigned char AcConnectorStestFail:1;				//bit 4
-			unsigned char LedboardStestFail:1;					//bit 5
-			unsigned char AcSystemInputOVP:1;					//bit 6
-			unsigned char AcSystemInputUVP:1;					//bit 7
+			unsigned char LedboardStestFail:1;									//bit 5
+			unsigned char AcSystemInputOVP:1;									//bit 6
+			unsigned char AcSystemInputUVP:1;									//bit 7
 			//AlarmVal[12]
 			unsigned char ChademoGroundWarning :1;					//bit 0
 			unsigned char CcsGroundfaultWarning :1;					//bit 1
@@ -1151,11 +1181,11 @@ struct AlarmCodeData
 			unsigned char SystemAcOutputOCPL3:1;					//bit 4
 			unsigned char CircuitShortL2:1;							//bit 5
 			unsigned char CircuitShortL3:1;							//bit 6
-			unsigned char CcsLiquidChillerWaterLevelWarning:1;		//bit 7
+			unsigned char CcsLiquidChillerWaterLevelWarning:1;      //bit 7
 			//AlarmVal[13]
-			unsigned char DisconnectedFromDo :1;					//bit 0
-			unsigned char MeterCommTimeout:1;						//bit 1
-			unsigned char Reserved :6;								//bit 2~bit7
+            unsigned char DisconnectedFromDo:1;                     //bit 0
+            unsigned char MeterCommTimeout:1;                       //bit 1
+            unsigned char Reserved :6;                              //bit 2~bit7
 		}bits;
 	}AlarmEvents;
 };
@@ -3580,11 +3610,11 @@ struct PrimaryMcuData
 			unsigned char Button2:1;								//bit 7,	H: Push, 		L:Release
 			//InputDetValue[1]
 			unsigned char EmergencyButton:1;						//bit 0,	H: Push, 		L:Release
-			unsigned char Key0:1; 								//bit 1,	H: ON, 		L:OFF
-			unsigned char Key1:1; 								//bit 2,	H: ON, 		L:OFF
-			unsigned char Key2:1;								//bit 3,	H: ON, 		L:OFF
-			unsigned char Key3:1; 								//bit 4,	H: ON, 		L:OFF
-			unsigned char :3;									//bit 5~7,	Reserved
+            unsigned char Key0:1;                               //bit 1,    H: ON,      L:OFF
+            unsigned char Key1:1;                               //bit 2,    H: ON,      L:OFF
+            unsigned char Key2:1;                               //bit 3,    H: ON,      L:OFF
+            unsigned char Key3:1;                               //bit 4,    H: ON,      L:OFF
+            unsigned char :3;                                   //bit 5~7,  Reserved
 		}bits;
 	}InputDet;
 };
@@ -4022,171 +4052,171 @@ struct OCPP16ConfigurationTable
 
 struct StrcutSetUserPrice
 {
-	unsigned char 	idToken[20];
-	unsigned char	price[256];
+    unsigned char   idToken[20];
+    unsigned char   price[256];
 };
 
 struct StrcutRunningFinalCost
 {
-	int 			txId;
-	unsigned char	description[256];
+    int             txId;
+    unsigned char   description[256];
 };
 
 struct StructCost
 {
-	struct StrcutSetUserPrice		SetUserPrice;
-	struct StrcutRunningFinalCost	RunningCost[CONNECTOR_QUANTITY];
-	struct StrcutRunningFinalCost	FinalCost[CONNECTOR_QUANTITY];
+    struct StrcutSetUserPrice       SetUserPrice;
+    struct StrcutRunningFinalCost   RunningCost[CONNECTOR_QUANTITY];
+    struct StrcutRunningFinalCost   FinalCost[CONNECTOR_QUANTITY];
 };
 
 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"
-	unsigned char                           ChargeBoxId[128];
-	unsigned char                           OcppConnStatus;         //0: disconnected, 1: connected
-	unsigned int                            Timeout_Secs;
-	unsigned short                          Ping_Pong_Interval;
-	union
-	{
-		//Operations Initiated by Charge Point
-		unsigned char CpMsgValue[CONNECTOR_QUANTITY];
-		struct
-		{
-			//CpMsgValue[0]
-			unsigned char DataTransferReq:1;        //bit 0,
-			unsigned char DataTransferConf:1;       //bit 1,
-			unsigned char StartTransactionReq:1;    //bit 2,
-			unsigned char StartTransactionConf:1;   //bit 3,
-			unsigned char StopTransactionReq:1;     //bit 4,
-			unsigned char StopTransactionConf:1;    //bit 5,
-			unsigned char :2;                       //bit 6,7 , reserved
-		} bits[CONNECTOR_QUANTITY];
-	}CpMsg;
-
-	union
-	{
-		//Operations Initiated by Sequence Point
-		unsigned char SpMsgValue[1];
-		struct
-		{
-			//SpMsgValue[0]
-			unsigned char BootNotificationReq :1;               //bit 0,
-			unsigned char BootNotificationConf :1;              //bit 1,
-			unsigned char AuthorizeReq :1;                      //bit 2,
-			unsigned char AuthorizeConf :1;                     //bit 3,
-			unsigned char DiagnosticsStatusNotificationReq :1;  //bit 4,
-			unsigned char DiagnosticsStatusNotificationConf :1; //bit 5,
-			unsigned char FirmwareStatusNotificationReq :1;     //bit 6,
-			unsigned char FirmwareStatusNotificationConf :1;    //bit 7,
-		} bits;
-	} SpMsg;
+    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"
+    unsigned char                           ChargeBoxId[128];
+    unsigned char                           OcppConnStatus;         //0: disconnected, 1: connected
+    unsigned int                            Timeout_Secs;
+    unsigned short                          Ping_Pong_Interval;
+    union
+    {
+        //Operations Initiated by Charge Point
+        unsigned char CpMsgValue[CONNECTOR_QUANTITY];
+        struct
+        {
+            //CpMsgValue[0]
+            unsigned char DataTransferReq:1;        //bit 0,
+            unsigned char DataTransferConf:1;       //bit 1,
+            unsigned char StartTransactionReq:1;    //bit 2,
+            unsigned char StartTransactionConf:1;   //bit 3,
+            unsigned char StopTransactionReq:1;     //bit 4,
+            unsigned char StopTransactionConf:1;    //bit 5,
+            unsigned char :2;                       //bit 6,7 , reserved
+        } bits[CONNECTOR_QUANTITY];
+    }CpMsg;
 
-	union
-	{
-		//Operations Initiated by Central System
-		unsigned char CsMsgValue[3 * (CONNECTOR_QUANTITY)];
-		struct
-		{
-			//CsMsgValue[0]
-			unsigned char CancelReservationReq :1;      //bit 0,
-			unsigned char CancelReservationConf :1;     //bit 1,
-			unsigned char ChangeAvailabilityReq :1;     //bit 2,
-			unsigned char ChangeAvailabilityConf :1;    //bit 3,
-			unsigned char ReserveNowReq :1;             //bit 4,
-			unsigned char ReserveNowConf :1;            //bit 5,
-			unsigned char SetChargingProfileReq :1;     //bit 6,
-			unsigned char SetChargingProfileConf :1;    //bit 7,
-			//CsMsgValue[1]
-			unsigned char TriggerMessageReq :1;         //bit 0,
-			unsigned char TriggerMessageConf :1;        //bit 1,
-			unsigned char UnlockConnectorReq :1;        //bit 2,
-			unsigned char UnlockConnectorConf :1;       //bit 3,
-			unsigned char RemoteStartTransactionReq :1; //bit 4,
-			unsigned char RemoteStartTransactionConf :1;//bit 5,
-			unsigned char RemoteStopTransactionReq :1;  //bit 6,
-			unsigned char RemoteStopTransactionConf :1; //bit 7,
-			//CsMsgValue[2]
-			unsigned char ClearChargingProfileReq :1;   //bit 0,
-			unsigned char ClearChargingProfileConf :1;  //bit 1,
-			unsigned char DataTransferReq :1;           //bit 2,
-			unsigned char DataTransferConf :1;          //bit 3,
-			unsigned char GetCompositeScheduleReq :1;   //bit 4,
-			unsigned char GetCompositeScheduleConf :1;  //bit 5,
-			unsigned char :2;                           //bit 6,7
-		} bits[CONNECTOR_QUANTITY];
-	}CsMsg;
+    union
+    {
+        //Operations Initiated by Sequence Point
+        unsigned char SpMsgValue[1];
+        struct
+        {
+            //SpMsgValue[0]
+            unsigned char BootNotificationReq :1;               //bit 0,
+            unsigned char BootNotificationConf :1;              //bit 1,
+            unsigned char AuthorizeReq :1;                      //bit 2,
+            unsigned char AuthorizeConf :1;                     //bit 3,
+            unsigned char DiagnosticsStatusNotificationReq :1;  //bit 4,
+            unsigned char DiagnosticsStatusNotificationConf :1; //bit 5,
+            unsigned char FirmwareStatusNotificationReq :1;     //bit 6,
+            unsigned char FirmwareStatusNotificationConf :1;    //bit 7,
+        } bits;
+    } SpMsg;
 
-	union
-	{
-		//Operations Initiated by Main System
-		unsigned char MsMsgValue[2];
-		struct
-		{
-			//CsMsgValue[0]
-			unsigned char ChangeConfigurationReq :1;    //bit 0,
-			unsigned char ChangeConfigurationConf :1;   //bit 1,
-			unsigned char ClearCacheReq :1;             //bit 2,
-			unsigned char ClearCacheConf :1;            //bit 3,
-			unsigned char GetConfigurationReq :1;       //bit 4,
-			unsigned char GetConfigurationConf :1;      //bit 5,
-			unsigned char UpdateFirmwareReq :1;         //bit 6,
-			unsigned char UpdateFirmwareConf :1;        //bit 7,
-			//CsMsgValue[1]
-			unsigned char GetDiagnosticsReq :1;         //bit 0,
-			unsigned char GetDiagnosticsConf :1;        //bit 1,
-			unsigned char GetLocalListVersionReq :1;    //bit 2,
-			unsigned char GetLocalListVersionConf :1;   //bit 3,
-			unsigned char ResetReq :1;                  //bit 4,
-			unsigned char ResetConf :1;                 //bit 5,
-			unsigned char SendLocalListReq :1;          //bit 6,
-			unsigned char SendLocalListConf :1;         //bit 7,
-		} bits;
-	} MsMsg;
+    union
+    {
+        //Operations Initiated by Central System
+        unsigned char CsMsgValue[3 * (CONNECTOR_QUANTITY)];
+        struct
+        {
+            //CsMsgValue[0]
+            unsigned char CancelReservationReq :1;      //bit 0,
+            unsigned char CancelReservationConf :1;     //bit 1,
+            unsigned char ChangeAvailabilityReq :1;     //bit 2,
+            unsigned char ChangeAvailabilityConf :1;    //bit 3,
+            unsigned char ReserveNowReq :1;             //bit 4,
+            unsigned char ReserveNowConf :1;            //bit 5,
+            unsigned char SetChargingProfileReq :1;     //bit 6,
+            unsigned char SetChargingProfileConf :1;    //bit 7,
+            //CsMsgValue[1]
+            unsigned char TriggerMessageReq :1;         //bit 0,
+            unsigned char TriggerMessageConf :1;        //bit 1,
+            unsigned char UnlockConnectorReq :1;        //bit 2,
+            unsigned char UnlockConnectorConf :1;       //bit 3,
+            unsigned char RemoteStartTransactionReq :1; //bit 4,
+            unsigned char RemoteStartTransactionConf :1;//bit 5,
+            unsigned char RemoteStopTransactionReq :1;  //bit 6,
+            unsigned char RemoteStopTransactionConf :1; //bit 7,
+            //CsMsgValue[2]
+            unsigned char ClearChargingProfileReq :1;   //bit 0,
+            unsigned char ClearChargingProfileConf :1;  //bit 1,
+            unsigned char DataTransferReq :1;           //bit 2,
+            unsigned char DataTransferConf :1;          //bit 3,
+            unsigned char GetCompositeScheduleReq :1;   //bit 4,
+            unsigned char GetCompositeScheduleConf :1;  //bit 5,
+            unsigned char :2;                           //bit 6,7
+        } bits[CONNECTOR_QUANTITY];
+    }CsMsg;
 
-	union
-	{
-		//Operations triggered by CSU
-		unsigned char CSUMsgValue[CONNECTOR_QUANTITY];
-		struct
-		{
-			//CSUMsgValue[0]
-			unsigned char ChargingProfileReq:1;     //bit 0,
-			unsigned char ChargingProfileConf:1;    //bit 0,
-			unsigned char :6;                       //bit 1,2,3,4,5,6,7 , reserved
-		} bits[CONNECTOR_QUANTITY];
-	}CSUMsg;
+    union
+    {
+        //Operations Initiated by Main System
+        unsigned char MsMsgValue[2];
+        struct
+        {
+            //CsMsgValue[0]
+            unsigned char ChangeConfigurationReq :1;    //bit 0,
+            unsigned char ChangeConfigurationConf :1;   //bit 1,
+            unsigned char ClearCacheReq :1;             //bit 2,
+            unsigned char ClearCacheConf :1;            //bit 3,
+            unsigned char GetConfigurationReq :1;       //bit 4,
+            unsigned char GetConfigurationConf :1;      //bit 5,
+            unsigned char UpdateFirmwareReq :1;         //bit 6,
+            unsigned char UpdateFirmwareConf :1;        //bit 7,
+            //CsMsgValue[1]
+            unsigned char GetDiagnosticsReq :1;         //bit 0,
+            unsigned char GetDiagnosticsConf :1;        //bit 1,
+            unsigned char GetLocalListVersionReq :1;    //bit 2,
+            unsigned char GetLocalListVersionConf :1;   //bit 3,
+            unsigned char ResetReq :1;                  //bit 4,
+            unsigned char ResetConf :1;                 //bit 5,
+            unsigned char SendLocalListReq :1;          //bit 6,
+            unsigned char SendLocalListConf :1;         //bit 7,
+        } bits;
+    } MsMsg;
 
-	struct StructBootNotification               BootNotification;
-	struct StructHeartbeat                      Heartbeat;
-	struct StructAuthorize                      Authorize;
-	struct StructStartTransaction               StartTransaction[CONNECTOR_QUANTITY];
-	struct StructStopTransaction                StopTransaction[CONNECTOR_QUANTITY];
-	struct StructStatusNotification             StatusNotification[CONNECTOR_QUANTITY];
-	struct StructCancelReservation              CancelReservation[CONNECTOR_QUANTITY];
-	struct StructChangeAvailability             ChangeAvailability[CONNECTOR_QUANTITY];
-	struct StructChangeConfiguration            ChangeConfiguration;
-	struct StructClearCache                     ClearCache;
-	struct StructClearChargingProfile           ClearChargingProfile[CONNECTOR_QUANTITY];
-	struct StructDataTransfer                   DataTransfer[CONNECTOR_QUANTITY];
-	struct StructDiagnosticsStatusNotification  DiagnosticsStatusNotification;
-	struct StructFirmwareStatusNotification     FirmwareStatusNotification;
-	struct StructGetCompositeSchedule           GetCompositeSchedule[CONNECTOR_QUANTITY];
-	struct StructGetConfiguration               GetConfiguration;
-	struct StructGetDiagnostics                 GetDiagnostics;
-	struct StructGetLocalListVersion            GetLocalListVersion;
-	struct StructMeterValues                    MeterValues[CONNECTOR_QUANTITY];
-	struct StructRemoteStartTransaction         RemoteStartTransaction[CONNECTOR_QUANTITY];
-	struct StructRemoteStopTransaction          RemoteStopTransaction[CONNECTOR_QUANTITY];
-	struct StructReserveNow                     ReserveNow[CONNECTOR_QUANTITY];
-	struct StructReset                          Reset;
-	struct StructSendLocalList                  SendLocalList;
-	struct StructSetChargingProfile             SetChargingProfile[CONNECTOR_QUANTITY];
-	struct StructTriggerMessage                 TriggerMessage[CONNECTOR_QUANTITY];
-	struct StructUnlockConnector                UnlockConnector[CONNECTOR_QUANTITY];
-	struct StructUpdateFirmware                 UpdateFirmware;
-	struct OCPP16ConfigurationTable             ConfigurationTable;
-	struct StructChargingProfile                SmartChargingProfile[CONNECTOR_QUANTITY];
-	struct StructCost							Cost;
+    union
+    {
+        //Operations triggered by CSU
+        unsigned char CSUMsgValue[CONNECTOR_QUANTITY];
+        struct
+        {
+            //CSUMsgValue[0]
+            unsigned char ChargingProfileReq:1;     //bit 0,
+            unsigned char ChargingProfileConf:1;    //bit 0,
+            unsigned char :6;                       //bit 1,2,3,4,5,6,7 , reserved
+        } bits[CONNECTOR_QUANTITY];
+    }CSUMsg;
+
+    struct StructBootNotification               BootNotification;
+    struct StructHeartbeat                      Heartbeat;
+    struct StructAuthorize                      Authorize;
+    struct StructStartTransaction               StartTransaction[CONNECTOR_QUANTITY];
+    struct StructStopTransaction                StopTransaction[CONNECTOR_QUANTITY];
+    struct StructStatusNotification             StatusNotification[CONNECTOR_QUANTITY];
+    struct StructCancelReservation              CancelReservation[CONNECTOR_QUANTITY];
+    struct StructChangeAvailability             ChangeAvailability[CONNECTOR_QUANTITY];
+    struct StructChangeConfiguration            ChangeConfiguration;
+    struct StructClearCache                     ClearCache;
+    struct StructClearChargingProfile           ClearChargingProfile[CONNECTOR_QUANTITY];
+    struct StructDataTransfer                   DataTransfer[CONNECTOR_QUANTITY];
+    struct StructDiagnosticsStatusNotification  DiagnosticsStatusNotification;
+    struct StructFirmwareStatusNotification     FirmwareStatusNotification;
+    struct StructGetCompositeSchedule           GetCompositeSchedule[CONNECTOR_QUANTITY];
+    struct StructGetConfiguration               GetConfiguration;
+    struct StructGetDiagnostics                 GetDiagnostics;
+    struct StructGetLocalListVersion            GetLocalListVersion;
+    struct StructMeterValues                    MeterValues[CONNECTOR_QUANTITY];
+    struct StructRemoteStartTransaction         RemoteStartTransaction[CONNECTOR_QUANTITY];
+    struct StructRemoteStopTransaction          RemoteStopTransaction[CONNECTOR_QUANTITY];
+    struct StructReserveNow                     ReserveNow[CONNECTOR_QUANTITY];
+    struct StructReset                          Reset;
+    struct StructSendLocalList                  SendLocalList;
+    struct StructSetChargingProfile             SetChargingProfile[CONNECTOR_QUANTITY];
+    struct StructTriggerMessage                 TriggerMessage[CONNECTOR_QUANTITY];
+    struct StructUnlockConnector                UnlockConnector[CONNECTOR_QUANTITY];
+    struct StructUpdateFirmware                 UpdateFirmware;
+    struct OCPP16ConfigurationTable             ConfigurationTable;
+    struct StructChargingProfile                SmartChargingProfile[CONNECTOR_QUANTITY];
+    struct StructCost                           Cost;
 };
 
 
@@ -4393,7 +4423,7 @@ struct IdTokenInfoType
 	short int	chargingPriority;								// Optional. Priority from a business point of view. Default priority is 0, The range is from -9 to 9. Higher values indicate a higher priority.
 	unsigned char language1[8];									// Optional. Preferred user interface language of identifier user. Contains a language code as defined in [RFC5646].
 	unsigned int evseId[100];									// Optional. Only used when the IdToken is only valid for one or more specific EVSEs, not for the entire Charging Station.
-	unsigned char language2[8];									// Optional. Second preferred user interface language of identifier user. Don?�t use when language1 is omitted, has to be different from language1.
+	unsigned char language2[8];									// Optional. Second preferred user interface language of identifier user. Dont use when language1 is omitted, has to be different from language1.
 	struct GroupIdTokenType groupIdToken;						// Optional. This contains the group identifier.
 	struct MessageContentType personalMessage;					// Optional. Personal message that can be shown to the EV Driver and can be used for tariff information, user greetings etc.
 };
@@ -4516,8 +4546,8 @@ struct ChargingProfileType
 
 struct ModemType
 {
-	unsigned char iccid[20];										// Optional. This contains the ICCID of the modem?�s SIM card.
-	unsigned char imsi[20];											// Optional. This contains the IMSI of the modem?�s SIM card.
+	unsigned char iccid[20];										// Optional. This contains the ICCID of the modems SIM card.
+	unsigned char imsi[20];											// Optional. This contains the IMSI of the modems SIM card.
 };
 
 struct ChargingStationType
@@ -4730,7 +4760,7 @@ struct ReportDataType
 
 struct SetMonitoringDataType
 {
-	unsigned int id;												// Optional. An id SHALL only be given to replace an existing monitor. The Charging Station handles the generation of id?�s for new monitors.
+	unsigned int id;												// Optional. An id SHALL only be given to replace an existing monitor. The Charging Station handles the generation of ids for new monitors.
 	float value;													// Required. Value for threshold or delta monitoring. For Periodic or PeriodicClockAligned this is the interval in seconds.
 	unsigned char type[32];											// Required. The type of this monitor, e.g. a threshold, delta or periodic monitor.
 	unsigned char severity;											// Required. The severity that will be assigned to an event that is triggered by this monitor.
@@ -4789,7 +4819,7 @@ struct BootNotification_20
 {
 	unsigned char reason[20];										// Required. This contains the reason for sending this message to the CSMS.
 	struct ChargingStationType chargingStation;						// Required. Identifies the Charging Station
-	unsigned char Response_currentTime[28];							// Required. This contains the CSMS?�s current time.
+	unsigned char Response_currentTime[28];							// Required. This contains the CSMSs current time.
 	unsigned int Response_interval;									// Required. When Status is Accepted, this contains the heartbeat interval in seconds. If the CSMS returns something other than Accepted, the value of the interval field indicates the minimum wait time before sending a next BootNotification request.
 	unsigned char Response_status[16];								// Required. This contains whether the Charging Station has been registered within the CSMS.
 };
@@ -4812,7 +4842,7 @@ struct CertificateSigned_20
 struct ChangeAvailability_20
 {
 	unsigned char operationalStatus[16];							// Required. This contains the type of availability change that the Charging Station should perform.
-	struct EVSEType evse;											// Optional. Contains Id?�s to designate a specific EVSE/connector by index numbers. When omitted, the message refers to the Charging Station as a whole.
+	struct EVSEType evse;											// Optional. Contains Ids to designate a specific EVSE/connector by index numbers. When omitted, the message refers to the Charging Station as a whole.
 	unsigned char Response_status[16];								// Required. This indicates whether the Charging Station is able to perform the availability change.
 	unsigned char guid[37];											// Save guid from server request
 };
@@ -5002,7 +5032,7 @@ struct GetVariables_20
 {
 	struct GetVariableDataType getVariableData[CtrlrVariable_CNT];				// Required. List of requested variables.
 	struct GetVariableResultType Response_getVariableResult[CtrlrVariable_CNT];	// Required. List of requested variables and their values.
-	unsigned char guid[37];														// Save guid from server request
+	unsigned char guid[37];                                                     // Save guid from server request
 };
 
 struct Heartbeat_20
@@ -5026,7 +5056,7 @@ struct LogStatusNotification_20
 
 struct MeterValues_20
 {
-	unsigned int evseId;											// Required. This contains a number (>0) designating an EVSE of the Charging Station. ????(zero) is used to designate the main power meter.
+	unsigned int evseId;											// Required. This contains a number (>0) designating an EVSE of the Charging Station. ‘0’ (zero) is used to designate the main power meter.
 	struct MeterValueType meterValue[1];							// Required. The sampled meter values with timestamps.
 };
 
@@ -5040,7 +5070,7 @@ struct NotifyChargingLimit_20
 struct NotifyCustomerInformation_20
 {
 	unsigned char data[512];										// Required. (Part of) the requested data. No format specified in which the data is returned. Should be human readable.
-	unsigned char tbc;												// Optional. ?�to be continued??indicator. Indicates whether another part of the monitoringData follows in an upcoming notifyMonitoringReportRequest message. Default value when omitted is false.
+	unsigned char tbc;												// Optional. “to be continued” indicator. Indicates whether another part of the monitoringData follows in an upcoming notifyMonitoringReportRequest message. Default value when omitted is false.
 	unsigned int seqNo;												// Required. Sequence number of this message. First message starts at 0.
 	unsigned char generatedAt[28];									// Required. Timestamp of the moment this message was generated at the Charging Station.
 	unsigned int requestId;											// Required. The Id of the request.
@@ -5072,7 +5102,7 @@ struct NotifyEVChargingSchedule_20
 struct NotifyEvent_20
 {
 	unsigned char generatedAt[28];									// Required. Timestamp of the moment this message was generated at the Charging Station.
-	unsigned char tbc;												// Optional. ?�to be continued??indicator. Indicates whether another part of the report follows in an upcoming notifyEventRequest message. Default value when omitted is false.
+	unsigned char tbc;												// Optional. “to be continued” indicator. Indicates whether another part of the report follows in an upcoming notifyEventRequest message. Default value when omitted is false.
 	unsigned int seqNo;												// Required. Sequence number of this message. First message starts at 0.
 	struct EventDataType eventData[10];								// Required. List of EventData.
 };
@@ -5080,7 +5110,7 @@ struct NotifyEvent_20
 struct NotifyMonitoringReport_20
 {
 	unsigned int requestId;											// Required. The id of the GetMonitoringRequest that requested this report.
-	unsigned char tbc;												// Optional. ?�to be continued??indicator.
+	unsigned char tbc;												// Optional. “to be continued” indicator.
 	unsigned int seqNo;												// Required. Sequence number of this message. First message starts at 0.
 	unsigned char generatedAt[28];									// Required. Timestamp of the moment this message was generated at the Charging Station.
 	struct MonitoringDataType monitor[10];							// Optional. List of MonitoringData containing monitoring settings.
@@ -5090,7 +5120,7 @@ struct NotifyReport_20
 {
 	unsigned int requestId;											// Required. The id of the GetReportRequest or GetBaseReportRequest that requested this report
 	unsigned char generatedAt[28];									// Required. Timestamp of the moment this message was generated at the Charging Station.
-	unsigned char tbc;												// Optional. ?�to be continued??indicator.
+	unsigned char tbc;												// Optional. “to be continued” indicator.
 	unsigned int seqNo;												// Required. Sequence number of this message. First message starts at 0.
 	struct ReportDataType reportData[10];							// Optional. List of ReportData.
 };
@@ -5229,9 +5259,9 @@ struct SetVariableMonitoring_20
 
 struct SetVariables_20
 {
-	struct SetVariableDataType setVariableData[CtrlrVariable_CNT];				// Required. List of Component-Variable pairs and attribute values to set.
-	struct SetVariableResultType Response_setVariableResult[CtrlrVariable_CNT];	// Required. List of result statuses per Component-Variable.
-	unsigned char guid[37];														// Save guid from server request
+	struct SetVariableDataType setVariableData[CtrlrVariable_CNT];              // Required. List of Component-Variable pairs and attribute values to set.
+	struct SetVariableResultType Response_setVariableResult[CtrlrVariable_CNT]; // Required. List of result statuses per Component-Variable.
+	unsigned char guid[37];                                                     // Save guid from server request
 };
 
 struct SignCertificate_20
@@ -5309,7 +5339,7 @@ struct OCPP20Data
 	unsigned char 							OcppConnStatus;			//0: disconnected, 1: connected
 	unsigned int 							Timeout_Secs;
 	unsigned short 							Ping_Pong_Interval;
-	struct ReportDataType 					ControllerComponentVariable[CtrlrVariable_CNT];
+	struct ReportDataType                   ControllerComponentVariable[CtrlrVariable_CNT];
 
 	union
 	{