Selaa lähdekoodia

Merge branch 'master' into DO360

Wendell 2 vuotta sitten
vanhempi
commit
58240e0124

+ 61 - 11
EVSE/Modularization/Module_Wifi.c

@@ -30,12 +30,12 @@
 
 #include 	<unistd.h>
 #include 	<stdarg.h>
-#include    <stdio.h>      /*標準輸入輸出定義*/
-#include    <stdlib.h>     /*標準函數庫定義*/
-#include    <unistd.h>     /*Unix 標準函數定義*/
-#include    <fcntl.h>      /*檔控制定義*/
-#include    <termios.h>    /*PPSIX 終端控制定義*/
-#include    <errno.h>      /*錯誤號定義*/
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
 #include 	<errno.h>
 #include 	<string.h>
 #include	<time.h>
@@ -44,6 +44,7 @@
 #include	<sqlite3.h>
 #include	<json-c/json.h>
 #include    <signal.h>
+#include	<regex.h>
 #include	"define.h"
 
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -197,7 +198,7 @@ struct interface_info
 	int authType;
 	int rssi;
 	int cnt_InternetFail;
-	char *currentInterface;
+	char currentInterface[16];
 	char currentSSID[256];
 	char currentPasswd[256];
 	char currentMAC[24];
@@ -260,7 +261,7 @@ int isValidCheckSum(uint8_t *message);
 char *Support_InterfaceSTA[2]	= {"mlan0", "wlan0"};
 char *Support_InterfaceAP[1]	= {"uap0"};
 char *valid_Internet[3]			= {"8.8.8.8", "180.76.76.76", "192.168.10.10"};
-char *Version_And_Date[2]		= {"V0.23","2022-02-09"};
+char *Version_And_Date[2]		= {"V0.24","2022-05-26"};
 int protocol_Version [] 		= {0,7,0};
 
 int StoreLogMsg(const char *fmt, ...)
@@ -444,6 +445,31 @@ int InitShareMemory()
     return result;
 }
 
+//==========================================
+// Valid MAC address
+//==========================================
+int isMacValid(char *MacAddress)
+{
+	int result = FALSE;
+    int r,cflags=0;
+    regmatch_t pm[10];
+    const size_t nmatch = 10;
+    regex_t reg;
+
+    r=regcomp(&reg, "^[0-9A-F]\\([0-9A-F]\\:[0-9A-F]\\)\\{5\\}[0-9A-F]$", cflags);
+    if(r==0)
+    {
+    	r=regexec(&reg, MacAddress, nmatch, pm, cflags);
+    }
+    regfree(&reg);
+
+    if(r==0)result = TRUE;
+
+    DEBUG_INFO("MAC(%s) format valid result: %d\n", MacAddress, result);
+
+    return result;
+}
+
 //==========================================
 // Get parameters from shared memory
 //==========================================
@@ -504,7 +530,7 @@ int isFindInterface()
 				{
 					if(mystrcmp(ifa->ifa_name, Support_InterfaceAP[idx]) == PASS)
 					{
-						Wifi.currentInterface = ifa->ifa_name;
+						sprintf(Wifi.currentInterface, "%s", ifa->ifa_name);
 						result = PASS;
 					}
 				}
@@ -527,7 +553,7 @@ int isFindInterface()
 				{
 					if(mystrcmp(ifa->ifa_name, Support_InterfaceSTA[idx]) == PASS)
 					{
-						Wifi.currentInterface = ifa->ifa_name;
+						sprintf(Wifi.currentInterface, "%s", ifa->ifa_name);
 						result = PASS;
 					}
 				}
@@ -816,7 +842,14 @@ int setWPAconf()
 					strcat(buffer, "\"\n    key_mgmt=WPA-EAP WPA-PSK \n");
 					strcat(buffer, "    bgscan=\"simple:10:-65:3600\" \n");
 					strcat(buffer, "    scan_ssid=1\n");
-					strcat(buffer, "    psk=\"");
+					if((strlen((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac) > 0) && isMacValid((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac))
+					{
+						strcat(buffer, "\n    bssid=");
+						strcat(buffer, (char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac);
+						strcat(buffer, "\n    psk=\"");
+					}
+					else
+						strcat(buffer, "    psk=\"");
 					strcat(buffer, (char*)Wifi_A.passwd);
 					strcat(buffer, "\"\n}\n\n");
 				}
@@ -831,6 +864,11 @@ int setWPAconf()
 					strcat(buffer, "\"\n    auth_alg=OPEN SHARED\n");
 					strcat(buffer, "    bgscan=\"simple:10:-65:3600\"\n");
 					strcat(buffer, "    scan_ssid=1\n");
+					if((strlen((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac) > 0) && isMacValid((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac))
+					{
+						strcat(buffer, "\n    bssid=");
+						strcat(buffer, (char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac);
+					}
 					strcat(buffer, "\n}\n\n");
 				}
 
@@ -839,6 +877,11 @@ int setWPAconf()
 				strcat(buffer, "\"\n    key_mgmt=NONE");
 				strcat(buffer, "\n    bgscan=\"simple:10:-65:3600\"");
 				strcat(buffer, "\n    scan_ssid=1");
+				if((strlen((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac) > 0) && isMacValid((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac))
+				{
+					strcat(buffer, "\n    bssid=");
+					strcat(buffer, (char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac);
+				}
 				strcat(buffer, "\n}");
 			}
 			else
@@ -848,6 +891,11 @@ int setWPAconf()
 				strcat(buffer, "\"\n    key_mgmt=NONE");
 				strcat(buffer, "\n    bgscan=\"simple:10:-65:3600\"");
 				strcat(buffer, "\n    scan_ssid=1");
+				if((strlen((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac) > 0) && isMacValid((char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac))
+				{
+					strcat(buffer, "\n    bssid=");
+					strcat(buffer, (char*)ShmSysConfigAndInfo->SysConfig.AthInterface.WifiTargetBssidMac);
+				}
 				strcat(buffer, "\n}");
 			}
 
@@ -936,6 +984,8 @@ int setWPAconf()
 			system(cmdBuf);
 			sprintf(cmdBuf, "echo wpa_pairwise=CCMP >> /etc/hostapd.conf");
 			system(cmdBuf);
+			sprintf(cmdBuf, "echo ignore_broadcast_ssid=%d >> /etc/hostapd.conf", ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiBroadcastSsid^1)==0?0:1));
+			system(cmdBuf);
 			sprintf(cmdBuf, "hostapd /etc/hostapd.conf -B");
 			system(cmdBuf);
 

+ 270 - 70
EVSE/Modularization/ocpp20/MessageHandler.c

@@ -52,6 +52,27 @@ static char *BootReasonEnumTypeStr[] = {
 	MACROSTR(Watchdog)
 };
 
+static char *SecurityEventEnumTypeStr[] = {
+	MACROSTR(FirmwareUpdated),
+	MACROSTR(FailedToAuthenticateAtCsms),
+	MACROSTR(CsmsFailedToAuthenticate),
+	MACROSTR(SettingSystemTime),
+	MACROSTR(StartupOfTheDevice),
+	MACROSTR(ResetOrReboot),
+	MACROSTR(SecurityLogWasCleared),
+	MACROSTR(ReconfigurationOfSecurityParameters),
+	MACROSTR(MemoryExhaustion),
+	MACROSTR(InvalidMessages),
+	MACROSTR(AttemptedReplayAttacks),
+	MACROSTR(TamperDetectionActivated),
+	MACROSTR(InvalidFirmwareSignature),
+	MACROSTR(InvalidFirmwareSigningCertificate),
+	MACROSTR(InvalidCsmsCertificate),
+	MACROSTR(InvalidChargingStationCertificate),
+	MACROSTR(InvalidTLSVersion),
+	MACROSTR(InvalidTLSCipherSuite)
+};
+
 static char *CancelReservationStatusEnumTypeStr[] = {
 	MACROSTR(Accepted),
 	MACROSTR(Rejected)
@@ -1035,6 +1056,9 @@ int DB_Initial()
 	char *sqlBootType 	  =  "create table if not exists ocpp20_boot_type (idx integer primary key,"
 							 "type text);";
 
+	char *sqlSecurityEventType 	  =  "create table if not exists ocpp20_securityevent_type (idx integer primary key,"
+							 "type text);";
+
 
 	char *sqlNetworkProfile	= "create table if not exists ocpp20_networkprofile (idx integer primary key,"
 								 "slot integer UNIQUE, connectionData text);";
@@ -1096,6 +1120,16 @@ int DB_Initial()
 			DEBUG_INFO( "Create OCPP 2.0 boot_type table successfully\n");
 		}
 
+		if (sqlite3_exec(db, sqlSecurityEventType, 0, 0, &errMsg) != SQLITE_OK)
+		{
+			result = FAIL;
+			DEBUG_ERROR( "Create OCPP 2.0 securityevent_type table error message: %s\n", errMsg);
+		}
+		else
+		{
+			DEBUG_INFO( "Create OCPP 2.0 securityevent_type table successfully\n");
+		}
+
 		if (sqlite3_exec(db, sqlNetworkProfile, 0, 0, &errMsg) != SQLITE_OK)
 		{
 			result = FAIL;
@@ -1377,6 +1411,55 @@ int DB_updateBootType(BootReasonEnumType reason)
 	 return result;
 }
 
+int SecurityEventTypecallback(void *para, int columnCount, char **columnValue, char **columnName)
+{
+	sprintf((char*)ShmOCPP20Data->SecurityEventNotification.type,"%s", columnValue[1] ? columnValue[1] : SecurityEventEnumTypeStr[SecurityEventEnumType_ResetOrReboot]);
+
+	return 0;
+}
+
+void DB_getSecurityEventType()
+{
+    char sql[256];
+    char* errMsg = NULL;
+
+    sprintf(sql,"select * from ocpp20_securityevent_type;");
+
+    /* Execute SQL statement */
+    if(sqlite3_exec(db, sql, SecurityEventTypecallback, 0, &errMsg) != SQLITE_OK )
+    {
+    	DEBUG_INFO("SQL error: %s\n", errMsg);
+    }
+}
+
+int DB_cbUpdateSecurityEventType(void *para, int columnCount, char **columnValue, char **columnName)
+{
+   for(int i = 0; i<columnCount; i++)
+   {
+     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+   }
+
+   return 0;
+}
+
+int DB_updateSecurityEventType(SecurityEventEnumType reason)
+{
+	int result = PASS;
+	 char sql[512];
+	 char* errMsg = NULL;
+
+	 sprintf(sql,"insert or replace into ocpp20_securityevent_type (idx, type) VALUES(1, '%s');", SecurityEventEnumTypeStr[reason]);
+
+	 //* Execute SQL statement */
+	 if(sqlite3_exec(db, sql, DB_cbUpdateSecurityEventType, 0, &errMsg) != SQLITE_OK)
+	 {
+		 DEBUG_INFO("SQL error: %s\n", errMsg);
+		 result = FAIL;
+	 }
+
+	 return result;
+}
+
 int DB_variableClear()
 {
 	int result = PASS;
@@ -1533,7 +1616,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variable.name, "TxEndedInterval");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableCharacteristics.unit, "Seconds");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].value, "0");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval]);
@@ -1542,7 +1625,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].component.name, "AuthCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variable.name, "Enabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled]);
@@ -1550,7 +1633,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].component.name, "AlignedDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variable.name, "AdditionalInfoItemsPerMessage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].value, "0");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage]);
@@ -1558,7 +1641,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].component.name, "AuthCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variable.name, "OfflineTxForUnknownIdEnabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled]);
@@ -1566,7 +1649,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].component.name, "AuthCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variable.name, "AuthorizeRemoteStart");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart]);
@@ -1574,7 +1657,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].component.name, "AuthCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variable.name, "LocalAuthorizeOffline");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].value, "TRUE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline]);
@@ -1582,7 +1665,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].component.name, "AuthCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variable.name, "LocalPreAuthorize");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].value, "TRUE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize]);
@@ -1591,7 +1674,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variable.name, "MasterPassGroupId");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
 		ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableCharacteristics.maxLimit = 36;
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].value, " ");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId]);
@@ -1941,7 +2024,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variable.name, "Enabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "TRUE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled]);
@@ -1950,7 +2033,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.maxLimit = 5000;
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].value, "5000");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries]);
@@ -1958,7 +2041,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variable.name, "Available");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].value, "TRUE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available]);
@@ -1967,7 +2050,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.name, "ItemsPerMessage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.instance, "SendLocalList");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].value, "500");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage]);
@@ -2544,7 +2627,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variable.name, "ChargingBeforeAcceptedEnabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled]);
@@ -2553,7 +2636,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variable.name, "EVConnectionTimeOut");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableCharacteristics.unit, "Seconds");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value, "180");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut]);
@@ -2561,7 +2644,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variable.name, "StopTxOnEVSideDisconnect");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].value, "TRUE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect]);
@@ -2569,7 +2652,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variable.name, "TxBeforeAcceptedEnabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled]);
@@ -2577,7 +2660,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variable.name, "TxStartPoint");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].value, "PowerPathClosed");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint]);
@@ -2585,7 +2668,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variable.name, "TxStopPoint");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].value, "PowerPathClosed");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint]);
@@ -2594,7 +2677,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variable.name, "MaxEnergyOnInvalidId");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableCharacteristics.unit, "Wh");
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].value, "0");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId]);
@@ -2602,7 +2685,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].component.name, "TxCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variable.name, "StopTxOnInvalidId");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId]);
@@ -6947,6 +7030,22 @@ void CheckSystemValue(void)
 		ShmOCPP20Data->SpMsg.bits.Get15118EVCertificateReq = OFF;
 	}
 
+	if(isWebsocketSendable &&
+	   (server_sign == TRUE) &&
+	   (ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq == ON))
+	{
+		sendSecurityEventNotificationRequest();
+		ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = OFF;
+	}
+
+	if(isWebsocketSendable &&
+	   (server_sign == TRUE) &&
+	   (ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq == ON))
+	{
+		sendNotifyCustomerInformationRequest();
+		ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq = OFF;
+	}
+
 	for(int gun_index=0;gun_index < gunTotalNumber;gun_index++)
 	{
 		// ClockAlign MeterValue
@@ -7316,9 +7415,11 @@ void CheckSystemValue(void)
 					{
 						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
 						AcPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState;
-						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;
 
-						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus >= SYS_MODE_CHARGING) &&
+						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_AUTHORIZING)
+							cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;
+
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus >= SYS_MODE_PREPARING) &&
 						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus <= SYS_MODE_COMPLETE))
 						{
 							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
@@ -7921,11 +8022,13 @@ int sendFirmwareStatusNotificationRequest(char *status)
 	{
 		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Installed;
 		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
+		DB_updateSecurityEventType(SecurityEventEnumType_FirmwareUpdated);
 	}
 	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallRebooting])==0)
 	{
 		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallRebooting;
 		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
+		DB_updateSecurityEventType(SecurityEventEnumType_FirmwareUpdated);
 	}
 	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallScheduled])==0)
 	{
@@ -9807,12 +9910,37 @@ int sendSecurityEventNotificationRequest()
 	char message[4096]={0};
 	char guid[37]={0};
 	char tempdata[128]={0};
+	struct timeval tmnow;
+	struct tm *tm;
+	char buf[28];//, usec_buf[6];
 	json_object *SecurityEventNotification = json_object_new_object();
 	DEBUG_INFO("sendSecurityEventNotificationRequest...\n");
 
+	DB_getSecurityEventType();
+
+	gettimeofday(&tmnow, NULL);
+
+	time_t t;
+	t = time(NULL);
+	/*UTC time and date*/
+	tm = gmtime(&t);
+	strftime(buf,28,"%Y-%m-%dT%H:%M:%SZ", tm);
+#if 0 // remove temporally
+	strftime(buf,30,"%Y-%m-%dT%H:%M:%S", tm);
+	strcat(buf,".");
+	sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
+	strcat(buf,usec_buf);
+#endif
+	printf("%s",buf);
+
+	strcpy((char *)ShmOCPP20Data->SecurityEventNotification.timestamp, buf);
+	if(strlen((char *)ShmOCPP20Data->SecurityEventNotification.techInfo)==0)
+		sprintf((char*)ShmOCPP20Data->SecurityEventNotification.type,"%s", SecurityEventEnumTypeStr[SecurityEventEnumType_ResetOrReboot]);
+
 	json_object_object_add(SecurityEventNotification, "type", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.type));
 	json_object_object_add(SecurityEventNotification, "timestamp", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.timestamp));
-	json_object_object_add(SecurityEventNotification, "techInfo", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.techInfo));
+	if(strlen((char *)ShmOCPP20Data->SecurityEventNotification.techInfo)>0)
+		json_object_object_add(SecurityEventNotification, "techInfo", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.techInfo));
 
 	random_uuid(guid);
 	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "SecurityEventNotification", json_object_to_json_string_ext(SecurityEventNotification, JSON_C_TO_STRING_PLAIN));
@@ -10214,7 +10342,7 @@ S_FAULT                 =12
 					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
 					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
 				}
-				else if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING)) //SYS_MODE_PREPARING
+				else if (/*(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) || */(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING)) //SYS_MODE_PREPARING
 				{
 					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
 				}
@@ -10385,6 +10513,7 @@ int sendTransactionEventRequest(int gun_index)
 						else
 							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
 
+						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartUserId);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartIdType]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
@@ -10515,6 +10644,7 @@ int sendTransactionEventRequest(int gun_index)
 						else
 							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
 
+						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartUserId);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartIdType]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
@@ -10644,6 +10774,7 @@ int sendTransactionEventRequest(int gun_index)
 						else
 							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
 
+						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartUserId);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartIdType]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
@@ -10766,6 +10897,7 @@ int sendTransactionEventRequest(int gun_index)
 						else
 							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
 
+						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartUserId);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartIdType]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
@@ -10894,6 +11026,7 @@ int sendTransactionEventRequest(int gun_index)
 						else
 							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
 
+						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartUserId);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartIdType]);
 						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
@@ -11373,22 +11506,23 @@ int sendGetCompositeScheduleConfirmation(char *uuid, char *payload, int connecto
 	json_object_object_add(GetCompositeSchedule, "status", json_object_new_string(payload));
 
   	CompositeScheduleIndex = (connectorIdInt > 0) ?(connectorIdInt -1) : 0;
+  	json_object_object_add(chargingSchedule, "evseId", json_object_new_int(CompositeScheduleIndex));
 	if(nPeriod == 0)
 	{
 		if(strcmp((const char *)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime,"")!=0)
 		{
 			if(strlen((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule))
-				json_object_object_add(chargingSchedule, "startSchedule", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));
+				json_object_object_add(schedule, "scheduleStart", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));
 
 			if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration > 0)
-				json_object_object_add(chargingSchedule, "duration", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration));
+				json_object_object_add(schedule, "duration", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration));
 
-			json_object_object_add(chargingSchedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingRateUnit));
+			json_object_object_add(schedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingRateUnit));
 
-			if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate > 0)
-				json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate));
+			//if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate > 0)
+				//json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate));
 
-			json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.id));
+			//json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.id));
 
 			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod);idxPeriod++)
 			{
@@ -11407,17 +11541,17 @@ int sendGetCompositeScheduleConfirmation(char *uuid, char *payload, int connecto
 					json_object_array_add(chargingSchedulePeriod, Period);
 				}
 			}
-			json_object_object_add(chargingSchedule, "chargingSchedulePeriod", chargingSchedulePeriod);
+			json_object_object_add(schedule, "chargingSchedulePeriod", chargingSchedulePeriod);
 
-			json_object_object_add(schedule, "startDateTime", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime));
-			json_object_object_add(schedule, "chargingSchedule", chargingSchedule);
+			//json_object_object_add(schedule, "startDateTime", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime));
+			//json_object_object_add(schedule, "chargingSchedule", chargingSchedule);
 			json_object_object_add(GetCompositeSchedule, "schedule", schedule);
 		}
 	}
 	else
 	{
 		if(strlen((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule))
-			json_object_object_add(chargingSchedule, "startSchedule", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));
+			json_object_object_add(chargingSchedule, "scheduleStart", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));
 
 		if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration > 0)
 			json_object_object_add(chargingSchedule, "duration", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration));
@@ -11648,19 +11782,23 @@ int sendGetVariablesConfirmation(char *uuid, unsigned char variableQuantity)
 		json_object *variable = json_object_new_object();
 		json_object *evse = json_object_new_object();
 
-		json_object_object_add(variableResult, "attributeType", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType));
+		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType) > 0)
+			json_object_object_add(variableResult, "attributeType", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType));
 		json_object_object_add(variableResult, "attributeStatus", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus));
-		json_object_object_add(variableResult, "attributeValue", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));
+		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue) > 0)
+			json_object_object_add(variableResult, "attributeValue", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));
 
 		json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.evse.id));
 		json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.evse.connectorId));
 		json_object_object_add(component, "evse", evse);
 		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.name));
-		json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.instance));
+		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.instance) > 0)
+			json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.instance));
 		json_object_object_add(variableResult, "component", component);
 
 		json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.name));
-		json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.instance));
+		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.instance) > 0)
+			json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.instance));
 		json_object_object_add(variableResult, "variable", variable);
 
 		json_object_array_add(getVariableResults, variableResult);
@@ -11813,10 +11951,12 @@ int sendResetConfirmation(char *uuid)
 	if(strcmp((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Accepted]) == 0)
 	{
 		DB_updateBootType(BootReasonEnumType_RemoteReset);
+		DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
 	}
 	else if(strcmp((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Scheduled]) == 0)
 	{
 		DB_updateBootType(BootReasonEnumType_ScheduledReset);
+		DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
 	}
 
 	result = TRUE;
@@ -11830,6 +11970,7 @@ int sendSendLocalListConfirmation(char *uuid)
 	int result = FAIL;
 	char message[4096]={0};
 	json_object *SendLocalList = json_object_new_object();
+	DEBUG_INFO("sendSendLocalListConfirmation...\n");
 
 	json_object_object_add(SendLocalList, "status", json_object_new_string((char*)ShmOCPP20Data->SendLocalList.Response_status));
 
@@ -11974,7 +12115,7 @@ int sendSetVariableMonitoringConfirmation(char *uuid, unsigned char variableQuan
 
 		json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.id));
 		json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.connectorId));
-		json_object_object_add(component, "component", evse);
+		json_object_object_add(component, "evse", evse);
 		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.name));
 		json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.instance));
 		json_object_object_add(variableMonitorResult, "component", component);
@@ -13661,6 +13802,7 @@ int handleCustomerInformationRequest(char *uuid, char *payload)
 			}
 		}
 		strcpy((char*)ShmOCPP20Data->CustomerInformation.Response_status, CustomerInformationStatusEnumTypeStr[CustomerInformationStatusEnumType_Accepted]);
+		ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq = ON;
 	}
 	else
 		strcpy((char*)ShmOCPP20Data->CustomerInformation.Response_status, CustomerInformationStatusEnumTypeStr[CustomerInformationStatusEnumType_Rejected]);
@@ -14272,10 +14414,16 @@ int handleGetCompositeScheduleRequest(char *uuid, char *payload)
 		memset(&ShmOCPP20Data->GetCompositeSchedule[gun_index], 0, sizeof(struct GetCompositeSchedule_20));
 		memcpy(&ShmOCPP20Data->GetCompositeSchedule[gun_index].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].guid));
 
-		if(strstr(chargingRateUnitStr, "W") != NULL)
+		if(strstr(chargingRateUnitStr, "W") != NULL || strlen(chargingRateUnitStr) == 0)
+		{
+			sprintf((char*)ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingRateUnit, "W");
 			checkCompositeSchedule(connectorIdInt, durationInt, &tmpProfile[0], 0, FALSE);
+		}
 		else
+		{
+			sprintf((char*)ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingRateUnit, "A");
 			checkCompositeSchedule(connectorIdInt, durationInt, &tmpProfile[0], 0, TRUE);
+		}
 
   		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod);idx++)
   		{
@@ -14428,7 +14576,7 @@ int handleGetLocalListVersionRequest(char *uuid, char *payload)
 	if(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "FALSE") == 0)
 	{
 		DEBUG_INFO("LocalAuthListEnabled is FALSE \n");
-		localversion = -1;
+		localversion = 0;
 	}
 	else
 	{
@@ -14879,7 +15027,7 @@ int handleGetMonitoringReportRequest(char *uuid, char *payload)
 
 						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "evse") != NULL)
 						{
-							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "getVariableData"), idx), "component"), "evse"), "id") != NULL)
+							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "evse"), "id") != NULL)
 							{
 								ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "instance"), "id"));
 							}
@@ -14913,7 +15061,7 @@ int handleGetMonitoringReportRequest(char *uuid, char *payload)
 	 * TODO:
 	 * 	1. Response result
 	 */
-	strcpy((char*)ShmOCPP20Data->GetReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
+	strcpy((char*)ShmOCPP20Data->GetMonitoringReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
 	sendGetMonitoringReportConfirmation(uuid);
 
 	return result;
@@ -15040,6 +15188,7 @@ int handleGetVariablesRequest(char *uuid, char *payload)
 {
 	mtrace();
 	int result = FAIL;
+	int isUnknownComponent = TRUE;
 	json_object *GetVariables;
 
 	DEBUG_INFO("handleGetVariablesRequest...\n");
@@ -15117,6 +15266,14 @@ int handleGetVariablesRequest(char *uuid, char *payload)
 						   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.instance, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance) == 0))
 						{
 							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_Accepted]);
+							isUnknownComponent = FALSE;
+
+							if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].attributeType, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type) != 0) &&
+							   (json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "attributeType") != NULL))
+							{
+								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_NotSupportedAttributeType]);
+								break;
+							}
 
 							if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, "ChargingStation") == 0) &&
 							   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, "SystemUptimeSec") == 0))
@@ -15148,10 +15305,20 @@ int handleGetVariablesRequest(char *uuid, char *payload)
 						}
 						else
 						{
-							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownComponent]);
+							if(strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name) != 0)
+							{
+								isUnknownComponent = FALSE;
+							}
+
+							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownVariable]);
 							memset(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, 0x00, ARRAY_SIZE(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));
 						}
 					}
+
+					if(isUnknownComponent == TRUE)
+					{
+						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownComponent]);
+					}
 				}
 			}
 		}
@@ -16451,7 +16618,6 @@ int handleSendLocalListRequest(char *uuid, char *payload)
 {
 	mtrace();
 	int result = FAIL;
-	char updateTypestr[15]={0};
 	int checkState_Faulted = FALSE;
 	json_object *SendLocalList;
 
@@ -16548,27 +16714,26 @@ int handleSendLocalListRequest(char *uuid, char *payload)
 		goto end;
 	}
 
-
 	// Check update type
-	if(strcmp(updateTypestr, UpdateEnumTypeStr[UpdateEnumType_Full]) == 0)
+	if(strcmp((char*)ShmOCPP20Data->SendLocalList.updateType, UpdateEnumTypeStr[UpdateEnumType_Full]) == 0)
 	{
 		//Local list full update
 		DEBUG_INFO("Local list full update.\n");
 
 		DB_getListVerion();
 
-		if(ShmOCPP20Data->SendLocalList.versionNumber < localversion )//if(listVersionInt <= localversion ) for OCTT Case ---remove temporally
+		/*if(ShmOCPP20Data->SendLocalList.versionNumber < localversion )//if(listVersionInt <= localversion ) for OCTT Case ---remove temporally
 		{
 			strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Failed]);
 			goto end;
-		}
+		}*/
 
 		DB_cleanLocalList();
 
 		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->SendLocalList.localAuthorizationList);idx++)
 			DB_addLocalList(ShmOCPP20Data->SendLocalList.versionNumber, &ShmOCPP20Data->SendLocalList.localAuthorizationList[idx]);
 	}
-	else if(strcmp(updateTypestr, UpdateEnumTypeStr[UpdateEnumType_Differential]) == 0)
+	else if(strcmp((char*)ShmOCPP20Data->SendLocalList.updateType, UpdateEnumTypeStr[UpdateEnumType_Differential]) == 0)
 	{
 		//Local list different update
 		DEBUG_INFO("Local list different update.\n");
@@ -17675,10 +17840,10 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 				sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "type")));
 				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, (char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type);
 			}
-
-			if(strlen((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type) == 0)
+			else
 			{
-				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, "Actual");
+				sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type, "Actual");
+				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, (char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type);
 			}
 
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "severity") != NULL)
@@ -17692,55 +17857,58 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].transaction = json_object_get_boolean(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "transaction"));
 			}
 
-			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component") != NULL)
+			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component") != NULL)
 			{
-				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "name") != NULL)
+				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "name") != NULL)
 				{
-					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "name")));
+					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "name")));
 				}
 
-				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "instance") != NULL)
+				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance") != NULL)
 				{
-					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "instance")));
+					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance")));
 				}
 
-				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "evse") != NULL)
+				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse") != NULL)
 				{
-					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "evse"), "id") != NULL)
+					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse"), "id") != NULL)
 					{
-						ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "instance"), "id"));
+						ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance"), "id"));
 					}
 
-					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "evse"), "connectorId") != NULL)
+					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse"), "connectorId") != NULL)
 					{
-						ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "instance"), "connectorId"));
+						ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance"), "connectorId"));
 					}
 				}
 
 				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component, &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component, sizeof(struct ComponentType));
 			}
 
-			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable") != NULL)
+			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable") != NULL)
 			{
-				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "name") != NULL)
+				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "name") != NULL)
 				{
-					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "name")));
+					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "name")));
 				}
 
-				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "instance") != NULL)
+				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "instance") != NULL)
 				{
-					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "instance")));
+					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "instance")));
 				}
 
 				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable , &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable, sizeof(struct VariableType));
 			}
 
+			/*
+			 * TODO
+			 * Set Variables and save to DB
+			 */
 			strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, SetMonitoringStatusEnumTypeStr[SetMonitoringStatusEnumType_Accepted]);
 		}
 	}
 	json_object_put(SetVariableMonitoring);
 
-
 	sendSetVariableMonitoringConfirmation(uuid, variableQuantity);
 
 	return result;
@@ -17750,6 +17918,7 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 {
 	mtrace();
 	int result = FAIL;
+	int isUnknownComponent = TRUE;
 	json_object *SetVariables;
 
 	DEBUG_INFO("handleSetVariablesRequest...\n");
@@ -17830,6 +17999,20 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 						   (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name) != NULL) &&
 						   (strlen((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance) != NULL):TRUE))
 						{
+							isUnknownComponent = FALSE;
+
+							if((strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeType) == NULL) &&
+							   (json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeType") != NULL))
+							{
+								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_NotSupportedAttributeType]);
+								break;
+							}
+
+							if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].mutability, MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]) != NULL)
+							{
+								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Rejected]);
+								break;
+							}
 
 							if(((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL)) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "NetworkConfigurationPriority") != NULL))
 							{
@@ -17939,8 +18122,24 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 								strcpy((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue);
 								DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[idx_var]);
 							}
+
+							break;
+						}
+						else
+						{
+							if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name) != NULL)
+							{
+								isUnknownComponent = FALSE;
+							}
+
+							strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_UnknownVariable]);
 						}
 					}
+
+					if(isUnknownComponent == TRUE)
+					{
+						strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_UnknownComponent]);
+					}
 				}
 			}
 		}
@@ -18706,7 +18905,7 @@ void handleBootNotificationResponse(char *payload, int gun_index)
 		server_sign = TRUE;
 		server_pending =FALSE;
 		DB_updateBootType(BootReasonEnumType_PowerUp);
-		sendSecurityEventNotificationRequest();
+		ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = ON;
 	}
 	else if(strcmp(statusStr, RegistrationStatusEnumTypeStr[RegistrationStatusEnumType_Pending]) == 0)
 	{
@@ -19015,6 +19214,7 @@ void handleSecurityEventNotificationResponse(char *payload, int gun_index)
 	DEBUG_INFO("handleSecurityEventNotificationResponse...\n");
 	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = OFF;
 	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationConf = ON;
+	DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
 }
 
 void handleSignCertificateResponse(char *payload, int gun_index)

+ 22 - 0
EVSE/Modularization/ocpp20/MessageHandler.h

@@ -73,6 +73,28 @@ typedef enum {
 	BootReasonEnumType_Watchdog
 } BootReasonEnumType;
 
+/* SecurityEventEnumType */
+typedef enum {
+	SecurityEventEnumType_FirmwareUpdated,
+	SecurityEventEnumType_FailedToAuthenticateAtCsms,
+	SecurityEventEnumType_CsmsFailedToAuthenticate,
+	SecurityEventEnumType_SettingSystemTime,
+	SecurityEventEnumType_StartupOfTheDevice,
+	SecurityEventEnumType_ResetOrReboot,
+	SecurityEventEnumType_SecurityLogWasCleared,
+	SecurityEventEnumType_ReconfigurationOfSecurityParameters,
+	SecurityEventEnumType_MemoryExhaustion,
+	SecurityEventEnumType_InvalidMessages,
+	SecurityEventEnumType_AttemptedReplayAttacks,
+	SecurityEventEnumType_TamperDetectionActivated,
+	SecurityEventEnumType_InvalidFirmwareSignature,
+	SecurityEventEnumType_InvalidFirmwareSigningCertificate,
+	SecurityEventEnumType_InvalidCsmsCertificate,
+	SecurityEventEnumType_InvalidChargingStationCertificate,
+	SecurityEventEnumType_InvalidTLSVersion,
+	SecurityEventEnumType_InvalidTLSCipherSuite
+} SecurityEventEnumType;
+
 /* CancelReservationStatusEnumType */
 typedef enum {
 	CancelReservationStatusEnumType_Accepted,

+ 2 - 2
EVSE/Modularization/ocpp20/Module_OcppBackend20.c

@@ -341,13 +341,13 @@ static int OCPP20Callback(struct lws *wsi, enum lws_callback_reasons reason, voi
 static struct lws_protocols protocols[] =
 {
 	{
-		"ocpp2.0",
+		"ocpp2.0.1",
 		OCPP20Callback,
 		WEBSOCKET_BUFFER_SIZE,
 		WEBSOCKET_BUFFER_SIZE,
 	},
 	{
-		"ocpp2.0",
+		"ocpp2.0.1",
 		OCPP20Callback,
 		WEBSOCKET_BUFFER_SIZE,
 		WEBSOCKET_BUFFER_SIZE,

+ 2 - 2
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -16601,7 +16601,7 @@ int initialConfigurationTable(void)
 		//ChargeProfileMaxStackLevel
 		ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemName, "ChargeProfileMaxStackLevel");
-		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData, "3" );
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData, "8" );
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","ChargeProfileMaxStackLevel", "true", ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData);
 
@@ -16630,7 +16630,7 @@ int initialConfigurationTable(void)
 		// MaxChargingProfilesInstalled
 		ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemName, "MaxChargingProfilesInstalled");
-		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData, "10" );
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData, "50" );
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","MaxChargingProfilesInstalled", "true", ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData);
 

+ 2 - 2
EVSE/Modularization/ocppph/MessageHandler.c

@@ -16068,7 +16068,7 @@ int initialConfigurationTable(void)
 		//ChargeProfileMaxStackLevel
 		ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemName, "ChargeProfileMaxStackLevel");
-		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData, "3" );
+		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData, "8" );
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","ChargeProfileMaxStackLevel", "true", ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[ChargeProfileMaxStackLevel].ItemData);
 
@@ -16097,7 +16097,7 @@ int initialConfigurationTable(void)
 		// MaxChargingProfilesInstalled
 		ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemName, "MaxChargingProfilesInstalled");
-		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData, "10" );
+		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData, "50" );
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","MaxChargingProfilesInstalled", "true", ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData);
 

+ 190 - 20
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c

@@ -2,9 +2,9 @@
  * Module_LcmControl.c
  *
  * Created on : 2020-10-20
- * Update on : 2022-04-27
+ * Update on : 2022-05-27
  * Author : Folus Wen, Eason Yang
- * Version : V0.28
+ * Version : V0.29
  *
  */
 
@@ -82,6 +82,13 @@ void setConnectionAnimation(uint8_t gun_index, uint8_t system_mode);
 void setPresentChargedEnergy(uint8_t gun_index, uint8_t system_mode);
 void setMarqueeControl(uint16_t address, uint8_t gun_index, uint8_t type);
 
+void setPrechargingTimerToDefault();
+void setPrechargingEnergyToDefault();
+void setPrechargingSessionFeeToDefault();
+void setPrechargingParkingFeeToDefault();
+void setPrechargingCostToDefault();
+void setPrechargingPowerToDefault();
+void setClearPrechargingValueToEmpty();
 //=======================================
 // Declare Timer
 //=======================================
@@ -125,7 +132,7 @@ int Uart1Fd;
 //=======================================
 // Record version and date
 //=======================================
-char *FIRMWARE_UPDATE_IMAGE[3] = {"V0.28", "2022-04-27", "REV.03.00"};
+char *FIRMWARE_UPDATE_IMAGE[3] = {"V0.29", "2022-05-27", "REV.03.00"};
 
 //=======================================
 // Common routine
@@ -339,11 +346,20 @@ void page_booting()
 		DEBUG_INFO("Setting page to booting.\n");
 	}
 	else
-	{}
+	{
+		setClearPrechargingValueToEmpty();
+	}
 }
 
 void page_idle(uint8_t gun_index, uint8_t system_mode)
 {
+	setPrechargingTimerToDefault();
+	setPrechargingEnergyToDefault();
+	setPrechargingSessionFeeToDefault();
+	setPrechargingParkingFeeToDefault();
+	setPrechargingCostToDefault();
+	setPrechargingPowerToDefault();
+
 	if(ocpp_get_isRemoteStartWait())
 	{
 		if((getCurrentPage() != SYSTEM_SCREEN_PREPARING))
@@ -400,17 +416,38 @@ void page_idle(uint8_t gun_index, uint8_t system_mode)
 				}
 				else
 				{
-					if((getCurrentPage() != SYSTEM_SCREEN_IDLE) && (ShmCharger->gun_info[gun_index].resultAuthorization != VALIDATED_RFID))
+					if((ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID && (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE)) &&
+					   (ShmCharger->isCcsEnable) &&
+					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) &&
+					   (ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout == OFF) && 
+					   (ShmCharger->gun_info[gun_index].resultAuthorization != VALIDATED_RFID) &&
+					   (ShmCharger->gun_info[gun_index].isRemoteStartWait != ON) &&
+					   (ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail != YES))
 					{
-						setCurrentPage(SYSTEM_SCREEN_IDLE);
-						setDefaultValue(gun_index, system_mode);
-						DEBUG_INFO("Setting page to idle.\n");
+						if((getCurrentPage() != SYSTEM_SCREEN_PREPARE_FOR_EVSE))
+						{
+							setCurrentPage(SYSTEM_SCREEN_PREPARE_FOR_EVSE);
+							DEBUG_INFO("Setting page to EVCCID. \n");
+						}
+						else
+						{
+							setConnectionAnimation(gun_index, system_mode);
+						}
 					}
 					else
 					{
-						setRfidIcon();
-						setQRCodeIcon();
-						setConnectionAnimation(gun_index, system_mode);
+						if((getCurrentPage() != SYSTEM_SCREEN_IDLE) && (ShmCharger->gun_info[gun_index].resultAuthorization != VALIDATED_RFID))
+						{
+							setCurrentPage(SYSTEM_SCREEN_IDLE);
+							setDefaultValue(gun_index, system_mode);
+							DEBUG_INFO("Setting page to idle.\n");
+						}
+						else
+						{
+							setRfidIcon();
+							setQRCodeIcon();
+							setConnectionAnimation(gun_index, system_mode);
+						}
 					}
 				}
 			}
@@ -459,6 +496,12 @@ void page_preparing(uint8_t gun_index, uint8_t system_mode)
 		}
 		else
 		{
+			setPrechargingTimerToDefault();
+			setPrechargingEnergyToDefault();
+			setPrechargingSessionFeeToDefault();
+			setPrechargingParkingFeeToDefault();
+			setPrechargingCostToDefault();
+			setPrechargingPowerToDefault();
 			setConnectionAnimation(gun_index, system_mode);
 			setPresentChargedEnergy(gun_index, system_mode);
 		}
@@ -496,6 +539,8 @@ void page_charging(uint8_t gun_index, uint8_t system_mode)
 		setConnectionAnimation(gun_index, system_mode);
 		setPresentChargedDuration(gun_index);
 		setPresentChargedgPower(gun_index);
+		setTimeTitle(ON);
+		setEnergyTitle(ON);
 
 		if((ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
 		{
@@ -625,6 +670,8 @@ void page_complete(uint8_t gun_index, uint8_t system_mode)
 
 	setPresentChargedDuration(gun_index);
 	setPresentChargedEnergy(gun_index, system_mode);
+	setTimeTitle(ON);
+	setEnergyTitle(ON);
 
 	if((ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
 	{
@@ -704,6 +751,8 @@ void page_terminating(uint8_t gun_index, uint8_t system_mode)
 		setPresentChargedDuration(gun_index);
 		setPresentChargedEnergy(gun_index, system_mode);
 		setPresentChargedgPower(gun_index);
+		setTimeTitle(ON);
+		setEnergyTitle(ON);
 
 		if((ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
 		{
@@ -1982,11 +2031,13 @@ void setConnectionAnimation(uint8_t gun_index, uint8_t system_mode)
 				if((CONNECTION_LEVEL_STATUS == CONNECTION_LEVEL_0) && (getDiffSecNow(startTime[gun_index][TMR_IDX_CONNECTION]) > (TIME_ANIMATION_CONNECTION)))
 				{
 					setDisplayValue(ICON_PREPARING_ANIMATION, CONNECTION_FLASHING_1);
+					setDisplayValue(ICON_PRECHARGING_ANIMATION, CONNECTION_FLASHING_1);
 					CONNECTION_LEVEL_STATUS = CONNECTION_LEVEL_1;
 				}
 				else if((CONNECTION_LEVEL_STATUS == CONNECTION_LEVEL_1) && (getDiffSecNow(startTime[gun_index][TMR_IDX_CONNECTION]) > (TIME_ANIMATION_CONNECTION*2)))
 				{
 					setDisplayValue(ICON_PREPARING_ANIMATION, CONNECTION_FLASHING_2);
+					setDisplayValue(ICON_PRECHARGING_ANIMATION, CONNECTION_FLASHING_2);
 					CONNECTION_LEVEL_STATUS =  CONNECTION_LEVEL_0;
 					refreshStartTimer(&startTime[gun_index][TMR_IDX_CONNECTION]);
 				}
@@ -2379,13 +2430,13 @@ void setDefaultValue(uint8_t gun_index, uint8_t system_mode)
 //=======================================
 void setTextToEmpty(uint8_t gun_index)
 {
-	uint8_t data[32];
-	uint8_t text_empty[32];
+	uint8_t data[16];
+	uint8_t text_empty[16];
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	memset(text_empty, 0x00, ARRAY_SIZE(text_empty));
 
-	strcpy((char*)text_empty, "    ");
+	strcpy((char*)text_empty, "                ");
 	string2ByteArray(text_empty, data);
 
 	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_TOTAL_COST, data, ARRAY_SIZE(data));
@@ -2462,7 +2513,7 @@ void setTimeTitle(uint8_t isOn)
 		}
 		else
 		{
-			strcpy((char*)text, "                ");
+			strcpy((char*)text, "                               ");
 			string2ByteArray(text, data);
 		}
 		
@@ -2498,7 +2549,7 @@ void setEnergyTitle(uint8_t isOn)
 		}
 		else
 		{
-			strcpy((char*)text, "                ");
+			strcpy((char*)text, "                               ");
 			string2ByteArray(text, data);
 		}
 		
@@ -2534,7 +2585,7 @@ void setSessionFeeTitle(uint8_t isOn)
 		}
 		else
 		{
-			strcpy((char*)text, "                ");
+			strcpy((char*)text, "                               ");
 			string2ByteArray(text, data);
 		}
 		
@@ -2570,7 +2621,7 @@ void setParkingFeeTitle(uint8_t isOn)
 		}
 		else
 		{
-			strcpy((char*)text, "                ");
+			strcpy((char*)text, "                               ");
 			string2ByteArray(text, data);
 		}
 		
@@ -2606,7 +2657,7 @@ void setFinalCostTitle(uint8_t isOn)
 		}
 		else
 		{
-			strcpy((char*)text, "                ");
+			strcpy((char*)text, "                               ");
 			string2ByteArray(text, data);
 		}
 		
@@ -2638,6 +2689,124 @@ void setCsuRootFsFwRev()
 	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CSU_ROOT_FS_FW_REV, data, ARRAY_SIZE(data));
 }
 
+//=======================================
+// Setting Precharging initial to empty
+//=======================================
+void setClearPrechargingValueToEmpty()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	strcpy((char*)text, "                ");
+	string2ByteArray(text, data);
+
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_TIMER, data, ARRAY_SIZE(data));
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_ENERGY, data, ARRAY_SIZE(data));
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_SESSION_FEE, data, ARRAY_SIZE(data));
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_PARKING_FEE, data, ARRAY_SIZE(data));
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_COST, data, ARRAY_SIZE(data));
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_POWER, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging initial to empty
+//=======================================
+void setPrechargingTimerToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s", "00:00:00");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_TIMER, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging energy to default
+//=======================================
+void setPrechargingEnergyToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s kWh", "0000.0000");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_ENERGY, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging session fee to default
+//=======================================
+void setPrechargingSessionFeeToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s", "000.00");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_SESSION_FEE, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging parking fee to default
+//=======================================
+void setPrechargingParkingFeeToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s", "000.00");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_PARKING_FEE, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging cost to default
+//=======================================
+void setPrechargingCostToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s", "000.00");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_COST, data, ARRAY_SIZE(data));
+}
+
+//=======================================
+// Setting Precharging power to default
+//=======================================
+void setPrechargingPowerToDefault()
+{
+	uint8_t data[16];
+	uint8_t text[16];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(text, 0x00, ARRAY_SIZE(text));
+
+	sprintf((char *)text, "%s kW", "0.00");
+	string2ByteArray(text, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_PRECHARGING_POWER, data, ARRAY_SIZE(data));
+}
+
 //=======================================
 // Initial all share memory
 //=======================================
@@ -3112,7 +3281,8 @@ int main(void)
 						page_idle(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
 						break;
 					case SYS_MODE_AUTHORIZING:
-						//page_authorizing(ShmCharger->gun_selectd);
+						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].StartMethod == START_METHOD_EVCCID)
+							page_authorizing(ShmCharger->gun_selectd);
 						break;
 					case SYS_MODE_PREPARING:
 						page_preparing(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);

+ 36 - 15
EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c

@@ -58,7 +58,6 @@ int mystrcmp(char *p1,char *p2);
 void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
 void split(char **arr, char *str, const char *del);
 
-
 int StoreLogMsg(const char *fmt, ...)
 {
 	char Buf[4096+256];
@@ -1960,11 +1959,33 @@ int main(void)
 					DEBUG_INFO("*******************************************\n");
 					DEBUG_INFO("***** High priority polling : Case 2 ******\n");
 					DEBUG_INFO("*******************************************\n");
-					DEBUG_INFO("MCU-%d set relay request : %d\n", gun_index, ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest);
+					DEBUG_INFO("MCU-%d set PWN request : %d\n", gun_index, ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest);
 
 					previousCharger.gun_info[gun_index].legacyRequest.isLegacyRequest = ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest;
 				}
 
+				//==================================================
+				// Case 2: Config primary Relay
+				//==================================================
+				if((previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] != ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0]) ||
+				   (previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] != ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1]) ||
+				   (previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] != ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2]) ||
+				   (previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] != ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3]))
+				{
+					DEBUG_INFO("*******************************************\n");
+					DEBUG_INFO("**** High priority polling : Case 2-X *****\n");
+					DEBUG_INFO("*******************************************\n");
+					DEBUG_INFO("MCU-%d set relay status [0][0] : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0]);
+					DEBUG_INFO("MCU-%d set relay status [0][1] : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1]);
+					DEBUG_INFO("MCU-%d set relay status [0][2] : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2]);
+					DEBUG_INFO("MCU-%d set relay status [0][3] : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3]);
+
+					previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0];
+					previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1];
+					previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2];
+					previousCharger.gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] = ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3];
+				}
+
 				//==================================================
 				// Case 3: Query primary MCU status
 				//==================================================
@@ -1986,9 +2007,9 @@ int main(void)
 					if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)
 					{
 						if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON)
-							DEBUG_INFO("Relay on mode : CHARGING_MODE_SOCKETE. \n");
+							DEBUG_INFO("Relay mode : CHARGING_MODE_SOCKETE. \n");
 						else
-							DEBUG_INFO("Relay on mode : CHARGING_MODE_BS / CHARGING_MODE_HLC. \n");
+							DEBUG_INFO("Relay mode : CHARGING_MODE_BS / CHARGING_MODE_HLC. \n");
 					}
 
 					DEBUG_INFO("MCU-%d get Relay State : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relay_state);
@@ -2119,10 +2140,10 @@ int main(void)
 				//==================================================
 				// Case 10: Query primary MCU power consumption
 				//==================================================
-				if((previousCharger.gun_info[gun_index].powerConsumptionTotal.power_consumption != ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption) ||
-				   (previousCharger.gun_info[gun_index].powerConsumption[0].power_consumption != ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption) ||
-				   (previousCharger.gun_info[gun_index].powerConsumption[1].power_consumption != ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption) ||
-				   (previousCharger.gun_info[gun_index].powerConsumption[2].power_consumption != ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption))
+				if((abs(ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption - previousCharger.gun_info[gun_index].powerConsumptionTotal.power_consumption) > 200) ||
+				   (abs(ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption - previousCharger.gun_info[gun_index].powerConsumption[0].power_consumption) > 200) ||
+				   (abs(ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption - previousCharger.gun_info[gun_index].powerConsumption[1].power_consumption) > 200) ||
+				   (abs(ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption - previousCharger.gun_info[gun_index].powerConsumption[2].power_consumption) > 200))
 				{
 					DEBUG_INFO("*******************************************\n");
 					DEBUG_INFO("***** High priority polling : Case 10 *****\n");
@@ -2144,9 +2165,9 @@ int main(void)
 				//==================================================
 				// Case 11: Query primary Out put current config
 				//==================================================
-				if(((int)previousCharger.gun_info[gun_index].outputCurrent.L1N_L12[0] != (int)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]) ||
-				   ((int)previousCharger.gun_info[gun_index].outputCurrent.L2N_L23[0] != (int)ShmCharger->gun_info[gun_index].outputCurrent.L2N_L23[0]) ||
-				   ((int)previousCharger.gun_info[gun_index].outputCurrent.L3N_L31[0] != (int)ShmCharger->gun_info[gun_index].outputCurrent.L3N_L31[0]))
+				if((abs((int)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0] - (int)previousCharger.gun_info[gun_index].outputCurrent.L1N_L12[0]) >= 2) ||
+				   (abs((int)ShmCharger->gun_info[gun_index].outputCurrent.L2N_L23[0] - (int)previousCharger.gun_info[gun_index].outputCurrent.L2N_L23[0]) >= 2) ||
+				   (abs((int)ShmCharger->gun_info[gun_index].outputCurrent.L3N_L31[0] - (int)previousCharger.gun_info[gun_index].outputCurrent.L3N_L31[0]) >= 2))
 				{
 					DEBUG_INFO("*******************************************\n");
 					DEBUG_INFO("***** High priority polling : Case 11 *****\n");
@@ -2169,9 +2190,9 @@ int main(void)
 				//==================================================
 				// Case 1: Query primary In put voltage
 				//==================================================
-				if(((int)previousCharger.gun_info[gun_index].inputVoltage.L1N_L12 != (int)ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12) ||
-				   ((int)previousCharger.gun_info[gun_index].inputVoltage.L2N_L23 != (int)ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23) ||
-				   ((int)previousCharger.gun_info[gun_index].inputVoltage.L3N_L31 != (int)ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31))
+				if((abs((int)ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12 - (int)previousCharger.gun_info[gun_index].inputVoltage.L1N_L12) >= 2) ||
+				   (abs((int)ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23 - (int)previousCharger.gun_info[gun_index].inputVoltage.L2N_L23) >= 2) ||
+				   (abs((int)ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31 - (int)previousCharger.gun_info[gun_index].inputVoltage.L3N_L31) >= 2))
 				{
 					DEBUG_INFO("===========================================\n");
 					DEBUG_INFO("==== Normal priority polling : Case 1 =====\n");
@@ -2375,7 +2396,7 @@ int main(void)
 				}
 				else
 				{
-					DEBUG_WARN("MCU-%d set request fail...%d\n", gun_index, failCount[gun_index]);
+					DEBUG_WARN("MCU-%d set PWN request fail...%d\n", gun_index, failCount[gun_index]);
 					if(failCount[gun_index]<USHRT_MAX)
 						failCount[gun_index]++;
 					else

+ 216 - 6
EVSE/Projects/AW-CCS/Apps/main.c

@@ -5521,6 +5521,64 @@ int main(void)
 			//==========================================
 			checkUnlocker(gun_index);
 
+			//==========================================
+			// Clean EVCCID timeout flag
+			//==========================================
+			if((ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID && (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE)) &&
+			   (ShmCharger->isCcsEnable) &&
+			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A))
+			{
+				for(int gun_index = 0;gun_index<AC_QUANTITY;gun_index++)
+				{
+					ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout = OFF;
+					ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = NO;
+				}
+			}
+
+			//==========================================
+			// Check EVCCID communcation error
+			//==========================================
+			if(ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout == ON)
+			{
+				if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail == OFF)
+					ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail = ON;
+			}
+			else
+			{
+				if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail == ON)
+					ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail = OFF;
+			}
+
+			//==========================================
+			// Clean isRemoteStartWait flag
+			//==========================================
+			if(ocpp_get_isRemoteStartWait())
+			{
+				if(ShmCharger->gun_info[gun_index].isRemoteStartWait == OFF)
+				{
+					ShmCharger->gun_info[gun_index].isRemoteStartWait = ON;
+					DEBUG_INFO("Remote start without connector id... \n");
+				}
+				
+				refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]);
+			}
+			else
+			{
+				if((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 5))
+				{
+					if(ShmCharger->gun_info[gun_index].isRemoteStartWait == ON)
+					{
+						ShmCharger->gun_info[gun_index].isRemoteStartWait = OFF;
+						DEBUG_INFO("Clean isRemoteStartWait flag... \n");
+					}
+				}
+
+				if((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 10))
+				{
+					refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]);
+				}
+			}
+
 			//==========================================
 			// Connector process
 			//==========================================
@@ -5624,7 +5682,8 @@ int main(void)
 							setChargerMode(gun_index, SYS_MODE_DEBUG);
 						else
 							setChargerMode(gun_index, SYS_MODE_IDLE);
-						
+
+						// The system identifies 1 phase or 3 phases depending on the model name 
 						ShmSysConfigAndInfo->SysConfig.AcPhaseCount = ((ShmSysConfigAndInfo->SysConfig.ModelName[2]=='Y') ||
 																	   (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='D') ||
 																	   (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='W')
@@ -5643,6 +5702,7 @@ int main(void)
 						ShmCharger->gun_info[gun_index].rfidReq = OFF;
 						ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF;
 						ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF;
+						ShmCharger->gun_info[gun_index].isGetEvCCID = OFF;
 						ocpp_set_remotestart(gun_index, OFF);
 						ocpp_set_remotestop(gun_index, OFF);
 
@@ -5711,13 +5771,110 @@ int main(void)
 						}
 					}
 
+					/*
+					 *	TODO:
+					 *	1. Try to get EVCCID if plug first
+					 */
+					if((ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID && (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE)) &&
+					   (ShmCharger->isCcsEnable) &&
+					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) &&
+					   (ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout == OFF) &&
+					   (ShmCharger->gun_info[gun_index].isRemoteStartWait != ON) &&
+					   (ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail != YES))
+					{
+						switch(ShmCharger->gun_info[gun_index].ccsHandshakeState)
+						{
+							case HANDSHAKE_DUTY_5:
+								if(!getRequest(gun_index))
+								{
+									setRequest(gun_index, ON);
+									refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]);
+									DEBUG_INFO("Try to get EVCCID, Set Request On.\n");
+
+									//Let CCS task start to negotiate
+									ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = ON;
+									ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_NONE;
+								}
+
+								// Set CCS 5% PWM duty
+								if(ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_5) //set 5% by SeccComm.c
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5;
+									ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK;
+									ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+									DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK\n");
+								}
+								break;
+							case HANDSHAKE_DUTY_5_CHECK:
+								if((ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF))
+								{
+									//2 secs timeout
+									refreshStartTimer(&startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]);
+									ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CCS;
+									DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS\n");
+								}
+								break;
+							case HANDSHAKE_CCS:
+								if(getDiffSecNow(startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_BS_HLC_HANDSHAKE)
+								{
+									ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout = ON;
+									ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF;
+									ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP;
+									setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL);
+									setSpeaker(ON,SPEAKER_INTERVAL_3COUNT);
+									DEBUG_INFO("Get EVCCID timeout.\n");
+									sleep(3);
+								}
+
+								if((19 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus < 253))
+								{
+									if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+									{
+										sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%s%02X%02X%02X%02X%02X%02X", ShmOCPP16Data->ConfigurationTable.CoreProfile[EVCCID_PREFIX].ItemData,
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[0],
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[1],
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[2],
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[3],
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[4],
+																															ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[5]);
+									}
+									else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+									{
+										sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[0],
+																														  ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[1],
+																														  ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[2],
+																														  ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[3],
+																														  ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[4],
+																														  ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[5]);
+									}
+
+									//sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "F5902677");
+									ShmCharger->gun_info[gun_index].isGetEvCCID = ON;
+
+									DEBUG_INFO("Got EVCCID: %s\n", ShmSysConfigAndInfo->SysConfig.UserId);
+								}
+								break;
+							default:
+								break;
+						}
+					}
+					else
+					{
+						if(getRequest(gun_index))
+						{
+							setRequest(gun_index, OFF);
+						}
+						ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5;
+					}
+
 					if(((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B)) ||
 					   ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) ||
 					   ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON)) ||
 					   (ShmCharger->gun_info[gun_index].rfidReq == ON) ||
 					   (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) ||
 					   (ocpp_get_remotestart(gun_index) == ON) ||
-					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart == ON))
+					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart == ON) ||
+					   (ShmCharger->gun_info[gun_index].isGetEvCCID == ON))
 					{
 						if((ShmCharger->gun_info[gun_index].rfidReq == ON))
 						{
@@ -5741,6 +5898,13 @@ int main(void)
 							setSpeaker(ON, SPEAKER_SHORT);
 							DEBUG_INFO("Start Method : BLE...\n");
 						}
+						else if(ShmCharger->gun_info[gun_index].isGetEvCCID == ON)
+						{
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_EVCCID;
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_MacAddress;
+							setSpeaker(ON, SPEAKER_SHORT);
+							DEBUG_INFO("Start Method : EVCCID...\n");
+						}
 						else
 						{
 							ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_FREE;
@@ -5757,6 +5921,7 @@ int main(void)
 						ShmCharger->gun_info[gun_index].isGunPlugged = NO;
 						ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO;
 						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart = OFF;
+						ShmCharger->gun_info[gun_index].isGetEvCCID = OFF;
 
 						// Get target current
 						ocpp_set_profile_req(gun_index, ON);
@@ -5777,6 +5942,11 @@ int main(void)
 							DEBUG_INFO("Remote start request authorize.\n");
 							ocpp_set_auth_req(ON, "ISO14443");
 						}
+						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_EVCCID))
+						{
+							DEBUG_INFO("EVCCID request authorize.\n");
+							ocpp_set_auth_req(ON, "MacAddress");
+						}
 					}
 
 					if(getDiffSecNow(startTime[gun_index][TMR_IDX_AUTH]) > TIMEOUT_SPEC_AUTH)
@@ -5847,6 +6017,43 @@ int main(void)
 									setChargerMode(gun_index, SYS_MODE_PREPARING);
 								}
 								break;
+							case START_METHOD_EVCCID:
+								ShmCharger->gun_info[gun_index].resultAuthorization = UNKNOW_RFID;
+
+								if(ocpp_get_auth_conf() ||
+								   (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
+								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > 2)))
+								{
+									if(ocpp_get_auth_result(gun_index) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
+									  (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
+									{
+										memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId));
+										
+										ShmCharger->gun_info[gun_index].resultAuthorization = VALIDATED_RFID;
+										DEBUG_INFO("Authorize pass [EVCCID].\n");
+										setSpeaker(ON, SPEAKER_SHORT);
+										setLedMotion(gun_index, LED_ACTION_RFID_PASS);
+										sleep(1);
+										setChargerMode(gun_index, SYS_MODE_PREPARING);
+										ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = NO;
+									}
+									else
+									{
+										ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
+										DEBUG_INFO("Authorize fail [EVCCID].\n");
+										setSpeaker(ON, SPEAKER_INTERVAL_3COUNT);
+										setLedMotion(gun_index, LED_ACTION_RFID_FAIL);
+										sleep(3);
+										setChargerMode(gun_index, SYS_MODE_IDLE);
+										ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = YES;
+										ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF;
+										ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP;
+									}
+
+									ocpp_set_auth_conf(OFF);
+								}
+								break;
 							case START_METHOD_RFID:
 							case START_METHOD_BLE:
 							case START_METHOD_FREE:
@@ -5871,12 +6078,15 @@ int main(void)
 					{
 						refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]);
 						setLedMotion(gun_index,LED_ACTION_AUTHED);
-						ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;												 
+						ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;
 
 						if(ShmCharger->isCcsEnable)
 						{
-							ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5;
-							DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5\n");
+							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod != START_METHOD_EVCCID)
+							{
+								ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5;
+								DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5\n");
+							}
 						}
 						else
 						{
@@ -6232,7 +6442,7 @@ int main(void)
 					// Unplug charging gun to Idle mode
 					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].isGunPlugged == YES))
 					{
-						DEBUG_INFO("Charging gun is plugged before.\n");
+						DEBUG_INFO("The connector was connected to the EV before.\n");
 						//Cancel CCS task negotiating
 						ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF;	
 						ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP;

+ 7 - 2
EVSE/Projects/AW-CCS/Apps/main.h

@@ -174,7 +174,8 @@ enum START_METHOD
 	START_METHOD_FREE=0,
 	START_METHOD_RFID,
 	START_METHOD_BACKEND,
-	START_METHOD_BLE
+	START_METHOD_BLE,
+	START_METHOD_EVCCID
 };
 
 enum HANDSHAKE_STATE
@@ -236,7 +237,7 @@ enum TIMER_IDX
 	TMR_IDX_CHECK_POWER_CONSUMPTION,
 	TMR_IDX_LCM_POWER_CONSUMPTION,
 	TMR_IDX_RESET_WIFI,
-	TMR_IDX_16,
+	TMR_IDX_CLEAN_REMOTE_START_WAIT,
 	TMR_IDX_17,
 	TMR_IDX_18,
 	TMR_IDX_19,
@@ -762,6 +763,10 @@ typedef struct GUN_INFO
 	uint32_t										isCheckPowerConsumption:1;
 	uint32_t										isHandshakeTimerRefresh:1;
 	uint32_t										isEmergencyStopReport:1;
+	uint32_t										isGetEvCCID:1;
+	uint32_t										isGetEvCCIDTimeout:1;
+	uint32_t										isRemoteStartWait:1;
+	uint32_t										isEvCCIDAuthorizeFail:1;
 }Gun_Info;
 
 struct Charger

+ 5 - 2
EVSE/Projects/define.h

@@ -370,7 +370,9 @@ struct WifiConfigData
 {
 	unsigned char		WifiMode;					//0: disable, 1: Infrastructure client, 2: Infrastructure server, 3: Ad-Hoc
 	unsigned char		WifiSsid[256];				//default: Null
-	unsigned char		WifiPassword[256];			//default: Null
+	unsigned char		WifiPassword[224];			//default: Null
+	unsigned char		WifiBroadcastSsid;			//the SSID broadcast configuration, 0: hidden	1: broadcast
+	unsigned char		WifiTargetBssidMac[31];		//Target connect SSID MAC address, default: Null
 	int					WifiRssi;					//dbm
 	unsigned char		WifiDhcpServer;				//0: enable, 1: disable
 	unsigned char		WifiDhcpClient;				//0: enable, 1: disable
@@ -6035,7 +6037,8 @@ struct OCPP20Data
 			unsigned char SecurityEventNotificationConf :1;
 			unsigned char SignCertificateReq :1;
 			unsigned char SignCertificateConf :1;
-			unsigned char :2;
+			unsigned char NotifyCustomerInformationReq :1;	//bit 6
+			unsigned char NotifyCustomerInformationConf :1;	//bit 7
 
 		} bits;
 	} SpMsg;

+ 2 - 1
EVSE/rootfs/etc/inittab

@@ -4,7 +4,8 @@
 #
 # Start an "askfirst" shell on the serial port
 #console::askfirst:-/bin/ash
-ttyS0::respawn:-/bin/ash
+#ttyS0::respawn:-/bin/ash
+ttyS0::respawn:-/sbin/getty -L ttyS0 115200 vt102
 
 # Stuff to do when restarting the init process
 ::restart:/sbin/init