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

2020.06.16 / Folus Wen

Actions:
1. EVSE/Modularization/Module_PhBackend.c add connect PH server module for remote start tmate usage.
2. EVSE/Projects/define.h add struct LED to SysConfigData.
3. EVSE/Modularization/ocppfiles/Module_OcppBackend.c add monitor/start Module_PhBackend.
4. EVSE/Modularization/ocppfiles/MessageHandler.c handleDataTransferRequest() add SetLEDBar message ID.

Files:
1. As follow commit history

Image version: D0.00.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 4 жил өмнө
parent
commit
936b0c684d

+ 9 - 1
EVSE/Modularization/Makefile

@@ -4,7 +4,7 @@ export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)/usr/bin:$PATH
 #define library variable
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
-all: clean Module_RFIDLib Module_Wifi WebServiceLib OcppBackend Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj Module_EventLogging Module_ProduceUtils
+all: clean Module_RFIDLib Module_Wifi WebServiceLib OcppBackend Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj Module_EventLogging Module_ProduceUtils Module_PhBackend
 
 
 clean:
@@ -18,6 +18,7 @@ clean:
 	rm -f libModule_Upgrade.a
 	rm -f libInfypwr_PsuCommObj.a
 	rm -f Module_ProduceUtils
+	rm -f Module_PhBackend
 
 Module_ProduceUtils:
 	rm -f Module_ProduceUtils
@@ -87,3 +88,10 @@ Module_EventLogging:
 	rm -f Module_EventLogging.o
 	mv -f Module_EventLogging ../rootfs/root
 
+Module_PhBackend:
+	rm -f Module_Phbackend
+	$(CC) -D $(Project) -I ../Projects -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PhBackend.o Module_PhBackend.c
+	$(CC) -o Module_PhBackend Module_PhBackend.o
+	rm -f Module_PhBackend.o
+	mv -f Module_PhBackend ../rootfs/root
+

+ 1456 - 0
EVSE/Modularization/Module_PhBackend.c

@@ -0,0 +1,1456 @@
+/*
+ * Module_PhBackend.c
+ *
+ *  Created on: 2020/06/11
+ *      Author: foluswen
+ */
+#include "Module_PhBackend.h"
+
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	va_list args;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	CurrentTime = time(NULL);
+	tm=localtime(&CurrentTime);
+	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d] - %s\" >> /Storage/SystemLog/[%04d.%02d]Module_PhBackend",
+			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
+			buffer,
+			tm->tm_year+1900,tm->tm_mon+1);
+#ifdef SystemLogMessage
+	system(Buf);
+#endif
+
+#ifdef ConsloePrintLog
+	printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer);
+#endif
+
+	return rc;
+}
+
+uint8_t split(char *src, const char *separator, char **dest)
+{
+     char *pNext;
+     int count = 0;
+
+     if (src == NULL || strlen(src) == 0)
+        return count;
+     if (separator == NULL || strlen(separator) == 0)
+        return count;
+     pNext = (char *)strtok(src,separator);
+     while(pNext != NULL)
+     {
+         *dest++ = pNext;
+         ++count;
+         pNext = (char *)strtok(NULL,separator);
+    }
+
+     return count;
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//creat ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
+		#endif
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
+		#endif
+    	result = FAIL;
+   	 }
+    else
+    {}
+
+   	//creat ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
+		#endif
+   		result = FAIL;
+	}
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
+		#endif
+    	result = FAIL;
+   	}
+    else
+    {}
+
+    return result;
+}
+
+uint8_t checksum_valid(struct Message *message)
+{
+	uint8_t chksum = 0;
+
+	for(uint16_t idx=6;idx<(message->buffer[2] | ((uint16_t)message->buffer[3]<<8));idx++)
+		chksum += message->buffer[idx];
+
+	chksum += 11;
+
+	return ((chksum&0xff)==message->buffer[(message->buffer[2] | ((uint16_t)message->buffer[3]<<8))-1]?PASS:FAIL);
+}
+
+uint8_t checksum_cal(struct Message *message)
+{
+	uint8_t chksum = 0;
+
+	for(uint16_t idx=6;idx<(message->size-1);idx++)
+		chksum += message->buffer[idx];
+
+	chksum += 11;
+
+	return (chksum & 0xff);
+}
+
+void showCmdRaw(struct Message *message, uint8_t isTx)
+{
+	if(isTx)
+		DEBUG_INFO("%s -----> Server\n", ShmSysConfigAndInfo->SysConfig.SystemId);
+	else
+		DEBUG_INFO("%s <----- Server\n", ShmSysConfigAndInfo->SysConfig.SystemId);
+
+	DEBUG_INFO("- CMD_%04d ------------------------------------\n", (message->buffer[6] | ((uint16_t)message->buffer[7]<<8)));
+	DEBUG_INFO("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+	DEBUG_INFO("-----------------------------------------------\n");
+
+	for(uint8_t idx=0;idx<((message->size/16)+1);idx++)
+	{
+		DEBUG_INFO("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", message->buffer[idx*16+0],
+																									  message->buffer[idx*16+1],
+																									  message->buffer[idx*16+2],
+																									  message->buffer[idx*16+3],
+																									  message->buffer[idx*16+4],
+																									  message->buffer[idx*16+5],
+																									  message->buffer[idx*16+6],
+																									  message->buffer[idx*16+7],
+																									  message->buffer[idx*16+8],
+																									  message->buffer[idx*16+9],
+																									  message->buffer[idx*16+10],
+																									  message->buffer[idx*16+11],
+																									  message->buffer[idx*16+12],
+																									  message->buffer[idx*16+13],
+																									  message->buffer[idx*16+14],
+																									  message->buffer[idx*16+15]);
+	}
+
+	DEBUG_INFO("-----------------------------------------------\n");
+}
+
+void handle_cmd_1001(struct Message *in, struct Message *out)
+{
+	uint32_t startAddr;
+	uint32_t offset = 0;
+	uint8_t	count;
+	uint32_t value;
+
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	if(in->buffer[12])
+			DEBUG_INFO("CMD Type: Set\n");
+	else
+		DEBUG_INFO("CMD Type: Query\n");
+
+	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
+	count = in->buffer[17];
+
+	if(in->buffer[12])
+	{
+		for(int idx=startAddr;idx<(startAddr+count);idx++)
+		{
+			value = in->buffer[20+(offset*4)] | ((uint32_t)in->buffer[21+(offset*4)]<<8) | ((uint32_t)in->buffer[22+(offset*4)]<<16) | ((uint32_t)in->buffer[23+(offset*4)]<<24);
+
+			switch(idx)
+			{
+				case 1:
+					DEBUG_INFO("Sign in interval: %d\n", value);
+					offset++;
+					break;
+				case 2:
+					DEBUG_INFO("Charger type: %d\n", value);
+					offset++;
+					break;
+				case 3:
+					DEBUG_INFO("Charger gun count: %d\n", value);
+					offset++;
+					break;
+				case 4:
+					DEBUG_INFO("Communication No: %d\n", value);
+					offset++;
+					break;
+				case 5:
+					offset++;
+					break;
+				case 6:
+					offset++;
+					break;
+				case 7:
+					offset++;
+					break;
+				case 8:
+					offset++;
+					break;
+				case 9:
+					offset++;
+					break;
+				case 10:
+					offset++;
+					break;
+				case 11:
+					offset++;
+					break;
+				case 12:
+					offset++;
+					break;
+				case 13:
+					offset++;
+					break;
+				case 14:
+					offset++;
+					break;
+				case 15:
+					offset++;
+					break;
+				case 16:
+					offset++;
+					break;
+				case 17:
+					offset++;
+					break;
+				case 18:
+					offset++;
+					break;
+				case 19:
+					offset++;
+					break;
+				case 20:
+					DEBUG_INFO("Report interval: %d\n", value);
+					offset++;
+					break;
+				case 21:
+					DEBUG_INFO("Heart beat interval: %d\n", value);
+					backend_info.interval_heartbeat = value;
+					offset++;
+					break;
+				case 22:
+					DEBUG_INFO("Heart beat overtime count: %d\n", value);
+					backend_info.retry_heartbeat = value;
+					offset++;
+					break;
+				case 23:
+					DEBUG_INFO("Status report interval: %d\n", value);
+					offset++;
+					break;
+				case 24:
+					offset++;
+					break;
+				case 25:
+					offset++;
+					break;
+				case 26:
+					offset++;
+					break;
+				case 27:
+					DEBUG_INFO("Service price: %.2f\n", (value/100.0));
+					offset++;
+					break;
+				case 28:
+					DEBUG_INFO("Charging price: %.2f\n", (value/100.0));
+					offset++;
+					break;
+				case 29:
+					offset++;
+					break;
+				case 30:
+					offset++;
+					break;
+				case 31:
+					offset++;
+					break;
+				case 32:
+					offset++;
+					break;
+				case 33:
+					offset++;
+					break;
+				case 34:
+					offset++;
+					break;
+				case 35:
+					offset++;
+					break;
+			}
+		}
+	}
+
+	create_Cmd_1002(out, in->buffer[12], startAddr, count);
+}
+
+void handle_cmd_1003(struct Message *in, struct Message *out)
+{
+	uint32_t startAddr;
+	uint8_t data[in->size-11-9];
+	uint8_t *server_info[3];
+
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	if(in->buffer[12])
+		DEBUG_INFO("CMD Type: Set\n");
+	else
+		DEBUG_INFO("CMD Type: Query\n");
+
+	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
+	memcpy(&data[0], &in->buffer[19], ARRAY_SIZE(data));
+
+	switch(startAddr)
+	{
+		case 1:
+			break;
+		case 2:
+			DEBUG_INFO("Server time: %02X%02X-%02X-%02X %02X:%02X:%02X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
+			break;
+		case 3:
+			break;
+		case 4:
+			break;
+		case 5:
+			break;
+		case 6:
+			break;
+		case 7:
+			break;
+		case 8:
+			break;
+		case 9:
+			break;
+		case 10:
+			break;
+		case 11:
+			memset(server_addr, 0x00, ARRAY_SIZE(server_addr));
+			memcpy(&server_addr[0], &in->buffer[19], 128);
+			split((char*)server_addr, ":", (char**)server_info);
+
+			message_header = strtol((char*)server_info[2], NULL, 16);
+			server_port = atoi((char*)server_info[1]);
+			sprintf((char*)server_addr, "%s", (char*)server_info[0]);
+
+			DEBUG_INFO("Server address: %s\n", server_addr);
+			DEBUG_INFO("Server port: %d\n", server_port);
+			DEBUG_INFO("Message header: %04X\n", message_header);
+			break;
+		case 12:
+			DEBUG_INFO("Customer ID: %s\n", data);
+			break;
+	}
+
+	create_Cmd_1004(out, in->buffer[12], startAddr, &data[0], ARRAY_SIZE(data));
+}
+
+void handle_cmd_1005(struct Message *in, struct Message *out)
+{
+	uint32_t startAddr;
+	uint32_t offset = 0;
+	uint8_t	count;
+	uint32_t value;
+	uint8_t	gun_index;
+
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+
+	gun_index = in->buffer[12];
+	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
+	count = in->buffer[17];
+
+	for(int idx=startAddr;idx<(startAddr+count);idx++)
+	{
+		value = in->buffer[20+(offset*4)] | ((uint32_t)in->buffer[21+(offset*4)]<<8) | ((uint32_t)in->buffer[22+(offset*4)]<<16) | ((uint32_t)in->buffer[23+(offset*4)]<<24);
+
+		switch(idx)
+		{
+			case 1:
+				if(value == 0x55)
+				{
+					DEBUG_INFO("Charger start.\n");
+				}
+				offset++;
+				break;
+			case 2:
+				if(value == 0x55)
+				{
+					DEBUG_INFO("Charger stop.\n");
+				}
+				offset++;
+				break;
+
+			case 3:
+				if(value == 0)
+				{
+					DEBUG_INFO("Charge soon.\n");
+				}
+				else if(value ==1)
+				{
+					DEBUG_INFO("Charge reserve.\n");
+				}
+				offset++;
+				break;
+			case 4:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 5:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 6:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 7:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 8:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 9:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 10:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 11:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 12:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 13:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 14:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 15:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 16:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 17:
+				if(value == 0x55)
+				{
+					DEBUG_INFO("Upload log request.\n");
+					system("/usr/bin/run_tmate_restart.sh");
+				}
+				offset++;
+				break;
+
+			case 18:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 19:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+
+			case 20:
+				if(value == 0x55)
+				{
+
+				}
+				offset++;
+				break;
+		}
+	}
+
+	create_Cmd_1006(out, gun_index, startAddr, count, true);
+}
+
+void handle_cmd_1101(struct Message *in)
+{
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	backend_info.sn_heartbeat = (in->buffer[12] | ((uint16_t)in->buffer[13]<<8));
+	backend_info.counter_heartbeat_retry = 0;
+}
+
+void handle_cmd_1103(struct Message *in)
+{
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	DEBUG_INFO("Connector id: %d\n", in->buffer[12]);
+}
+
+void handle_cmd_1105(struct Message *in)
+{
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	DEBUG_INFO("Charger sign in OK.\n");
+	backend_info.isSignin = ON;
+	backend_info.st_hearbeat = time((time_t*)NULL);
+	backend_info.counter_heartbeat_retry = 0;
+	backend_info.interval_heartbeat = 10;
+}
+
+void handle_cmd_2303(struct Message *in, struct Message *out)
+{
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	create_Cmd_2304(out);
+}
+
+void handle_cmd_2305(struct Message *in, struct Message *out)
+{
+	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
+	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
+	create_Cmd_2306(out);
+}
+
+
+
+void create_Cmd_1002(struct Message *out, uint8_t cmd_type, uint32_t address, uint32_t count)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+	out->size = 9 + 43 + (count*4);
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1002>>0) & 0xff;
+	out->buffer[0x07] = (1002>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);
+
+	// Command type (0:Check  1:Set)
+	out->buffer[0x2c] = cmd_type;
+
+	// Start adress
+	out->buffer[0x2d] = (address>>0) & 0xff;
+	out->buffer[0x2e] = (address>>8) & 0xff;
+	out->buffer[0x2f] = (address>>16) & 0xff;
+	out->buffer[0x30] = (address>>24) & 0xff;
+
+	// Count
+	out->buffer[0x31] = count;
+
+	// Result (0:Success  1:Fail)
+	out->buffer[0x31] = 0x00;
+
+	memset(&out->buffer[0x32], 0x00, (count*4));
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+
+}
+
+void create_Cmd_1004(struct Message *out, uint8_t cmd_type, uint32_t address, uint8_t *data, uint8_t data_len)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+	out->size = 9 + 42 + data_len;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1004>>0) & 0xff;
+	out->buffer[0x07] = (1004>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);
+
+	// Command type (0:Check  1:Set)
+	out->buffer[0x2c] = cmd_type;
+
+	// Start adress
+	out->buffer[0x2d] = (address>>0) & 0xff;
+	out->buffer[0x2e] = (address>>8) & 0xff;
+	out->buffer[0x2f] = (address>>16) & 0xff;
+	out->buffer[0x30] = (address>>24) & 0xff;
+
+	// Result (0:Success  1:Fail)
+	out->buffer[0x31] = 0x00;
+
+	// Result data
+	memcpy(&out->buffer[0x32], &data[0], data_len);
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+void create_Cmd_1006(struct Message *out, uint8_t gun_index, uint32_t address, uint8_t count, uint8_t isExecuted)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+	out->size = 0x34;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1006>>0) & 0xff;
+	out->buffer[0x07] = (1006>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);
+
+	// Gun index
+	out->buffer[0x2c] = gun_index;
+
+	// Start adress
+	out->buffer[0x2d] = (address>>0) & 0xff;
+	out->buffer[0x2e] = (address>>8) & 0xff;
+	out->buffer[0x2f] = (address>>16) & 0xff;
+	out->buffer[0x30] = (address>>24) & 0xff;
+
+	// Command count
+	out->buffer[0x31] = count;
+
+	// Command execute result;
+	out->buffer[0x32] = isExecuted;
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+void create_Cmd_1102(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 0x2f;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1102>>0) & 0xff;
+	out->buffer[0x07] = (1102>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);
+
+	// Heart beat sn
+	out->buffer[0x2c] = (backend_info.sn_heartbeat>>0) & 0xff;
+	out->buffer[0x2d] = (backend_info.sn_heartbeat>>8) & 0xff;
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+void create_Cmd_1104(struct Message *out, uint8_t gun_index)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 0xd7;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1102>>0) & 0xff;
+	out->buffer[0x07] = (1102>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 0x20);
+
+	// Charger connector quantity
+	out->buffer[0x2c] = AC_QUANTITY + CCS_QUANTITY + GB_QUANTITY + CHAdeMO_QUANTITY;
+
+	// Connector id
+	out->buffer[0x2d] = gun_index;
+
+	// Charger model type (1: DC, 2: AC)
+	out->buffer[0x2e] = (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D'?1:2);
+
+	// Connector status
+	switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
+	{
+		case '1' ... '9':
+			if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_UPDATE))
+				out->buffer[0x2f] = 7;
+			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_IDLE)
+				out->buffer[0x2f] = 0;
+			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_PREPARING))
+				out->buffer[0x2f] = 1;
+			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_TERMINATING))
+				out->buffer[0x2f] = 2;
+			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_COMPLETE)
+				out->buffer[0x2f] = 3;
+			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_FAULT))
+				out->buffer[0x2f] = 6;
+			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_RESERVATION)
+				out->buffer[0x2f] = 5;
+			else
+				out->buffer[0x2f] = 0;
+			break;
+		case 'J':
+			if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
+				out->buffer[0x2f] = 7;
+			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
+				out->buffer[0x2f] = 0;
+			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
+				out->buffer[0x2f] = 1;
+			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
+				out->buffer[0x2f] = 2;
+			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
+				out->buffer[0x2f] = 3;
+			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
+				out->buffer[0x2f] = 6;
+			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
+				out->buffer[0x2f] = 5;
+			else
+				out->buffer[0x2f] = 0;
+			break;
+		case 'U':
+		case 'E':
+			if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
+				out->buffer[0x2f] = 7;
+			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
+				out->buffer[0x2f] = 0;
+			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
+				out->buffer[0x2f] = 1;
+			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
+				out->buffer[0x2f] = 2;
+			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
+				out->buffer[0x2f] = 3;
+			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
+				out->buffer[0x2f] = 6;
+			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
+				out->buffer[0x2f] = 5;
+			else
+				out->buffer[0x2f] = 0;
+			break;
+		case 'G':
+			if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
+				out->buffer[0x2f] = 7;
+			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
+				out->buffer[0x2f] = 0;
+			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
+				out->buffer[0x2f] = 1;
+			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
+				out->buffer[0x2f] = 2;
+			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
+				out->buffer[0x2f] = 3;
+			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
+				out->buffer[0x2f] = 6;
+			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
+				out->buffer[0x2f] = 5;
+			else
+				out->buffer[0x2f] = 0;
+			break;
+		default:
+			break;
+	}
+
+	// SOC
+	out->buffer[0x30] = 0x00;
+
+	// Alarm code
+	out->buffer[0x31] = 0x00;
+	out->buffer[0x32] = 0x00;
+	out->buffer[0x33] = 0x00;
+	out->buffer[0x34] = 0x00;
+
+	// Connect status
+	out->buffer[0x35] = 0x00;
+
+	// Charging amount
+	out->buffer[0x36] = 0x00;
+	out->buffer[0x37] = 0x00;
+	out->buffer[0x38] = 0x00;
+	out->buffer[0x39] = 0x00;
+
+	// Charging temperature
+	out->buffer[0x3a] = 0x00;
+	out->buffer[0x3b] = 0x00;
+	out->buffer[0x3c] = 0x00;
+	out->buffer[0x3d] = 0x00;
+
+	// Total power consumption
+	out->buffer[0x3e] = 0x00;
+	out->buffer[0x3f] = 0x00;
+	out->buffer[0x40] = 0x00;
+	out->buffer[0x41] = 0x00;
+
+	// DC voltage
+	out->buffer[0x42] = 0x00;
+	out->buffer[0x43] = 0x00;
+
+	// DC current
+	out->buffer[0x44] = 0x00;
+	out->buffer[0x45] = 0x00;
+
+	// BMS voltage request
+	out->buffer[0x46] = 0x00;
+	out->buffer[0x47] = 0x00;
+
+	// BMS current request
+	out->buffer[0x48] = 0x00;
+	out->buffer[0x49] = 0x00;
+
+	// BMS charging mode
+	out->buffer[0x4a] = 0x00;
+
+	// AC L1 voltage
+	out->buffer[0x4b] = 0x00;
+	out->buffer[0x4c] = 0x00;
+
+	// AC L2 voltage
+	out->buffer[0x4d] = 0x00;
+	out->buffer[0x4e] = 0x00;
+
+	// AC L3 voltage
+	out->buffer[0x4f] = 0x00;
+	out->buffer[0x50] = 0x00;
+
+	// AC L1 current
+	out->buffer[0x51] = 0x00;
+	out->buffer[0x52] = 0x00;
+
+	// AC L2 current
+	out->buffer[0x53] = 0x00;
+	out->buffer[0x54] = 0x00;
+
+	// AC L3 current
+	out->buffer[0x55] = 0x00;
+	out->buffer[0x56] = 0x00;
+
+	// Charging remind time
+	out->buffer[0x57] = 0x00;
+	out->buffer[0x58] = 0x00;
+
+	// Charging time
+	out->buffer[0x59] = 0x00;
+	out->buffer[0x5a] = 0x00;
+	out->buffer[0x5b] = 0x00;
+	out->buffer[0x5c] = 0x00;
+
+	// Charging power consumption
+	out->buffer[0x5d] = 0x00;
+	out->buffer[0x5e] = 0x00;
+	out->buffer[0x5f] = 0x00;
+	out->buffer[0x60] = 0x00;
+
+	// Before charging meter value
+	out->buffer[0x61] = 0x00;
+	out->buffer[0x62] = 0x00;
+	out->buffer[0x63] = 0x00;
+	out->buffer[0x64] = 0x00;
+
+	// After charging meter value
+	out->buffer[0x65] = 0x00;
+	out->buffer[0x66] = 0x00;
+	out->buffer[0x67] = 0x00;
+	out->buffer[0x68] = 0x00;
+
+	// Start method
+	out->buffer[0x69] = 0x00;
+
+	// Charging strategy
+	out->buffer[0x6a] = 0x00;
+
+	// Charging parameter
+	out->buffer[0x6b] = 0x00;
+	out->buffer[0x6c] = 0x00;
+	out->buffer[0x6d] = 0x00;
+	out->buffer[0x6e] = 0x00;
+
+	// Reservation flag
+	out->buffer[0x6f] = 0x00;
+
+	// User
+	memset(&out->buffer[0x70], 0x00, 0x24);
+
+	// Reservation over time
+	out->buffer[0x94] = 0x00;
+
+	// Start time
+	memset(&out->buffer[0x95], 0x00, 0x08);
+
+	// Surplus
+	memset(&out->buffer[0x9d], 0x00, 0x04);
+
+	// System variable reserve
+	memset(&out->buffer[0xa1], 0x00, 0x14);
+
+	// RFID/Member flag
+	out->buffer[0xb5] = 0x00;
+
+	// Order No.
+	memset(&out->buffer[0xb6], 0x00, 0x20);
+
+	// SN
+	memset(&out->buffer[0xd6], 0x00, 0x10);
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+void create_Cmd_1106(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 0x63;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (1106>>0) & 0xff;
+	out->buffer[0x07] = (1106>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Charger ID
+	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);
+
+	// Charger type  (0:Normal  1:none polar  2:polling)
+	out->buffer[0x2c] = 0x00;
+
+	// Software version
+	out->buffer[0x2d] = 0x01;
+	out->buffer[0x2e] = 0x00;
+	out->buffer[0x2f] = 0x00;
+	out->buffer[0x30] = 0x00;
+
+	// Charger item type
+	out->buffer[0x31] = 0x00;
+	out->buffer[0x32] = 0x00;
+
+	// Start count
+	out->buffer[0x33] = 0x00;
+	out->buffer[0x34] = 0x00;
+	out->buffer[0x35] = 0x00;
+	out->buffer[0x36] = 0x00;
+
+	// Data upload type  (1:Handshake  2:Report)
+	out->buffer[0x37] = 0x02;
+
+	// Register time  (Minute)
+	out->buffer[0x38] = 0x00;
+	out->buffer[0x39] = 0x00;
+
+	// Spare
+	out->buffer[0x3a] = 0x00;
+
+	// Charge gun count
+	out->buffer[0x3b] = 0x01;
+
+	// Heart beat upload cycle
+	out->buffer[0x3c] = 0x98;
+
+	// Heart beat overtime count
+	out->buffer[0x3d] = 0x00;
+
+	// Charge record count
+	out->buffer[0x3e] = 0x00;
+	out->buffer[0x3f] = 0x00;
+	out->buffer[0x40] = 0x00;
+	out->buffer[0x41] = 0x00;
+
+	// Current system time
+	out->buffer[0x42] = 0x20;
+	out->buffer[0x43] = 0x20;
+	out->buffer[0x44] = 0x06;
+	out->buffer[0x45] = 0x11;
+	out->buffer[0x46] = 0x11;
+	out->buffer[0x47] = 0x02;
+	out->buffer[0x48] = 0x18;
+	out->buffer[0x49] = 0xff;
+
+	// Latest charge time
+	out->buffer[0x4a] = 0x20;
+	out->buffer[0x4b] = 0x20;
+	out->buffer[0x4c] = 0x06;
+	out->buffer[0x4d] = 0x11;
+	out->buffer[0x4e] = 0x11;
+	out->buffer[0x4f] = 0x01;
+	out->buffer[0x50] = 0x52;
+	out->buffer[0x51] = 0xff;
+
+	// Latest start time
+	out->buffer[0x52] = 0x20;
+	out->buffer[0x53] = 0x20;
+	out->buffer[0x54] = 0x06;
+	out->buffer[0x55] = 0x11;
+	out->buffer[0x56] = 0x11;
+	out->buffer[0x57] = 0x01;
+	out->buffer[0x58] = 0x52;
+	out->buffer[0x59] = 0xff;
+
+	// Latest register time
+	out->buffer[0x5a] = 0x20;
+	out->buffer[0x5b] = 0x20;
+	out->buffer[0x5c] = 0x06;
+	out->buffer[0x5d] = 0x11;
+	out->buffer[0x5e] = 0x11;
+	out->buffer[0x5f] = 0x02;
+	out->buffer[0x60] = 0x08;
+	out->buffer[0x61] = 0xff;
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+void create_Cmd_2304(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 0x0e;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (2304>>0) & 0xff;
+	out->buffer[0x07] = (2304>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Result (0:Success  1:Fail)
+	out->buffer[0x0c] = 0x00;
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+
+}
+
+void create_Cmd_2306(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 0x11;
+
+	// Message header
+	out->buffer[0x00] = (message_header>>8) & 0xff;
+	out->buffer[0x01] = (message_header>>0) & 0xff;
+
+	// Message length
+	out->buffer[0x02] = (out->size>>0) & 0xff;
+	out->buffer[0x03] = (out->size>>8) & 0xff;
+
+	// Message protocol version
+	out->buffer[0x04] = PROTOCOL_VER;
+
+	// Message server command serial number
+	out->buffer[0x05] = server_cmd_sn & 0xff;
+
+	// Message command
+	out->buffer[0x06] = (2306>>0) & 0xff;
+	out->buffer[0x07] = (2306>>8) & 0xff;
+
+	// Message user id
+	out->buffer[0x08] = (server_user_id>>0) & 0xff;
+	out->buffer[0x09] = (server_user_id>>8) & 0xff;
+
+	// Message server command serial number
+	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
+	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;
+
+	// Result (0:Success  1:Fail)
+	out->buffer[0x0c] = 0x00;
+	out->buffer[0x0d] = 0x00;
+	out->buffer[0x0e] = 0x00;
+	out->buffer[0x0f] = 0x00;
+
+	// Checksum
+	out->buffer[out->size-1] = checksum_cal(out);
+
+	showCmdRaw(out, true);
+}
+
+int main(void)
+{
+	int 				sockfd;
+	struct sockaddr_in 	info;
+	struct hostent 		*ghbn;
+	struct timeval 		tv;
+	uint8_t 			socketEnable;
+
+	struct Message		input;
+	struct Message		intputBuf;
+	struct Message		output;
+
+	sprintf((char*)server_addr, "evsocket.phihong.com.tw");
+	server_port = 9999;
+
+	if(InitShareMemory() == FAIL)
+	{
+		DEBUG_ERROR("InitShareMemory NG\n");
+
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
+		}
+		sleep(5);
+		return 0;
+	}
+
+	for(;;)
+	{
+		bzero(&info,sizeof(info));
+		ghbn = gethostbyname((char*)server_addr);
+		info.sin_family = PF_INET;
+		info.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]));
+		info.sin_port = htons(server_port);
+		DEBUG_INFO("Connecto to %s:%d\n", inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]), server_port);
+
+		sockfd = socket(AF_INET, SOCK_STREAM, 0);
+		if (sockfd == -1)
+		{
+			DEBUG_ERROR("Fail to create a socket.");
+			return 0;
+		}
+
+		if(connect(sockfd, (struct sockaddr *)&info,sizeof(info)) ==-1)
+		{
+			DEBUG_ERROR("Connection error");
+		}
+		else
+		{
+			DEBUG_INFO("Connect success.\n");
+			tv.tv_sec = 0;
+			tv.tv_usec = 500000;
+			setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
+			socketEnable = ON;
+		}
+
+		while(socketEnable)
+		{
+			memset(input.buffer, 0, ARRAY_SIZE(input.buffer));
+			if((input.size = recv(sockfd, input.buffer, ARRAY_SIZE(input.buffer), 0)) > 0)
+			{
+				if(input.size < ARRAY_SIZE(input.buffer))
+				{
+					//DEBUG_INFO("Receive size: %d.\n", input.size);
+					for(uint16_t idx=0;idx<input.size;idx++)
+					{
+						if((input.buffer[idx] == ((message_header>>8) & 0xff)) && (input.buffer[idx+1] == ((message_header>>0) & 0xff)))
+						{
+							//DEBUG_INFO("idx: %d\n", idx);
+							memset(&intputBuf.buffer[0], 0x00, ARRAY_SIZE(intputBuf.buffer));
+							memcpy(&intputBuf.buffer[0], &input.buffer[idx], input.buffer[idx+2] | ((uint16_t)input.buffer[idx+3]<<8));
+							intputBuf.size = input.buffer[idx+2] | ((uint16_t)input.buffer[idx+3]<<8);
+							idx += (input.buffer[idx+2] | (uint16_t)input.buffer[idx+3]) -1;
+							server_cmd_sn = intputBuf.buffer[10] | ((uint16_t)intputBuf.buffer[11]<<8);
+
+							if(!checksum_valid(&intputBuf))
+								DEBUG_INFO("Message checksum wrong.\n");
+							else
+							{
+								showCmdRaw(&intputBuf, OFF);
+								switch(intputBuf.buffer[6] | ((uint16_t)intputBuf.buffer[7]<<8))
+								{
+									case 1001:
+										handle_cmd_1001(&intputBuf, &output);
+										send(sockfd, output.buffer, output.size, 0);
+										break;
+									case 1003:
+										handle_cmd_1003(&intputBuf, &output);
+										send(sockfd, output.buffer, output.size, 0);
+										break;
+									case 1005:
+										handle_cmd_1005(&intputBuf, &output);
+										send(sockfd, output.buffer, output.size, 0);
+										break;
+									case 1101:
+										handle_cmd_1101(&intputBuf);
+										break;
+									case 1103:
+										handle_cmd_1103(&intputBuf);
+										break;
+									case 1105:
+										handle_cmd_1105(&intputBuf);
+										break;
+									case 2303:
+										handle_cmd_2303(&intputBuf, &output);
+										send(sockfd, output.buffer, output.size, 0);
+										break;
+									case 2305:
+										handle_cmd_2305(&intputBuf, &output);
+										send(sockfd, output.buffer, output.size, 0);
+										break;
+								}
+							}
+						}
+					}
+				}
+			}
+			else if(input.size == 0)
+			{
+				DEBUG_INFO("Disconnected.\n");
+				fflush(stdout);
+				backend_info.isSignin = OFF;
+				socketEnable = OFF;
+			}
+			else if(input.size == -1)
+			{
+				// Sign in reqyest
+				if(!backend_info.isSignin)
+				{
+					create_Cmd_1106(&output);
+					send(sockfd, output.buffer, output.size, 0);
+				}
+
+				// Heart beat request
+				if(backend_info.isSignin && (difftime(time((time_t*)NULL), backend_info.st_hearbeat) > backend_info.interval_heartbeat))
+				{
+					create_Cmd_1102(&output);
+					send(sockfd, output.buffer, output.size, 0);
+					backend_info.st_hearbeat = time((time_t*)NULL);
+					backend_info.counter_heartbeat_retry++;
+				}
+
+				// Heart beat retry fail
+				if(backend_info.isSignin &&  (backend_info.counter_heartbeat_retry > backend_info.retry_heartbeat))
+				{
+					fflush(stdout);
+					backend_info.isSignin = OFF;
+					socketEnable = OFF;
+					DEBUG_ERROR("Heart beat retry over count.\n");
+				}
+			}
+			usleep(100000);
+		}
+		close(sockfd);
+		sleep(5);
+	}
+
+	return 0;
+}

+ 108 - 0
EVSE/Modularization/Module_PhBackend.h

@@ -0,0 +1,108 @@
+/*
+ * Module_PhBackend.h
+ *
+ *  Created on: 2020/6/11
+ *      Author: foluswen
+ */
+
+#ifndef MODULE_PHBACKEND_H_
+#define MODULE_PHBACKEND_H_
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include 	<errno.h>
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<sys/types.h>
+#include 	<sys/socket.h>
+#include 	<netinet/in.h>
+#include 	<netdb.h>
+#include 	<error.h>
+#include 	"define.h"
+
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+
+#define ARRAY_SIZE(A)				(sizeof(A) / sizeof(A[0]))
+#define PASS						1
+#define FAIL			   			-1
+#define ON							1
+#define OFF							0
+#define true			    		1
+#define false						0
+
+#define PROTOCOL_VER				0x00
+
+struct Message
+{
+	int			size;
+	uint8_t		buffer[2048];
+};
+
+struct PH_Backend_Info
+{
+	uint32_t	st_hearbeat;
+	uint32_t	st_status;
+
+	uint32_t	interval_heartbeat;
+	uint32_t	interval_status;
+
+	uint8_t		retry_heartbeat;
+
+	uint16_t	sn_heartbeat;
+
+	uint8_t		counter_heartbeat_retry;
+	uint8_t		isSignin:1;
+}backend_info;
+
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+
+uint16_t			message_header		= 0xffff;
+uint8_t				server_addr[512];
+uint16_t			server_port;
+uint16_t 			server_cmd_sn		= 0x0000;;
+uint16_t 			server_user_id		= 0xffff;
+
+extern void handle_cmd_1001(struct Message *in, struct Message *out);
+extern void handle_cmd_1003(struct Message *in, struct Message *out);
+extern void handle_cmd_1005(struct Message *in, struct Message *out);
+extern void handle_cmd_1101(struct Message *in);
+extern void handle_cmd_1103(struct Message *in);
+extern void handle_cmd_1105(struct Message *in);
+extern void handle_cmd_2303(struct Message *in, struct Message *out);
+extern void handle_cmd_2305(struct Message *in, struct Message *out);
+
+extern void create_Cmd_1002(struct Message *out,  uint8_t cmd_type, uint32_t address, uint32_t count);
+extern void create_Cmd_1004(struct Message *out, uint8_t cmd_type, uint32_t address, uint8_t *data, uint8_t data_len);
+extern void create_Cmd_1006(struct Message *out, uint8_t gun_index, uint32_t address, uint8_t count, uint8_t isExecuted);
+extern void create_Cmd_1102(struct Message *out);
+extern void create_Cmd_1104(struct Message *out, uint8_t gun_index);
+extern void create_Cmd_1106(struct Message *out);
+extern void create_Cmd_2304(struct Message *out);
+extern void create_Cmd_2306(struct Message *out);
+#endif /* MODULE_PHBACKEND_H_ */

+ 25 - 1
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -7088,7 +7088,7 @@ int handleDataTransferRequest(char *uuid, char *payload)
 	int result = FAIL;
 	char tempvendorId[255]={0};
 	char tempmessageId[50]={0};
-	char tempdata[50]={0};
+	char tempdata[512]={0};
 	char message[2048]={0};
 
 	DEBUG_INFO("handleDataTransferRequest...\n");
@@ -7122,6 +7122,30 @@ int handleDataTransferRequest(char *uuid, char *payload)
 			json_object_object_add(response, "data", json_object_new_string((char*)ShmOCPP16Data->DataTransfer[0].Data));
 			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string(response));
 		}
+		else if(strstr(tempmessageId, "SetLEDBar") != NULL)
+		{
+			json_object *data;
+			data = json_tokener_parse(tempdata);
+			if(!is_error(data))
+			{
+				for(uint8_t idx=0;idx<json_object_array_length(data);idx++)
+				{
+					ShmSysConfigAndInfo->SysConfig.LedInfo[json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Id"))].Intensity = json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Intensity"));
+					ShmSysConfigAndInfo->SysConfig.LedInfo[json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Id"))].Red = json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Red"));
+					ShmSysConfigAndInfo->SysConfig.LedInfo[json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Id"))].Green = json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Green"));
+					ShmSysConfigAndInfo->SysConfig.LedInfo[json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Id"))].Blue = json_object_get_int(json_object_object_get(json_object_array_get_idx(data, idx), "Blue"));
+				}
+				json_object_object_add(response, "status", json_object_new_string("Accepted"));
+			}
+			else
+			{
+				json_object_object_add(response, "status", json_object_new_string("Rejected"));
+				json_object_object_add(response, "data", json_object_new_string("Configuration content something wrong."));
+			}
+			json_object_put(data);
+
+			sprintf(message,"[%d,\"%s\",%s]",MESSAGE_TYPE_CALLRESULT, uuid, json_object_to_json_string(response));
+		}
 		else
 		{
 			// Can not find valid message id

+ 7 - 0
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -1150,6 +1150,13 @@ void* processWatchdog()
 
 			startTimeDog = time((time_t*)NULL);
 		}
+		
+		if(system("pidof -s Module_PhBackend > /dev/null") != 0)
+		{
+			DEBUG_INFO("Module_PhBackend not running, restart it.\r\n");
+			system("/root/Module_PhBackend &");
+		}
+
 		sleep(1);
 	}
 	pthread_exit(NULL); //

+ 10 - 1
EVSE/Projects/define.h

@@ -306,6 +306,14 @@ struct BillingConfigData
 	float 				Cur_fee;					// display current fee
 };
 
+struct LED
+{
+	uint8_t 			Intensity;					// LED bar intensity	0: Darkest	1: Medium	2: Brightest
+	uint8_t				Red;						// Red color	0~100
+	uint8_t				Green;						// Green color	0~100
+	uint8_t				Blue;						// Blue color	0~100
+};
+
 struct SysConfigData
 {
 	/**************System***************/
@@ -360,8 +368,9 @@ struct SysConfigData
 	unsigned short	   		OfflineMaxChargeDuration;	//0: same as MaxChargeDuration, 1 ~ 65535 minutes
 	unsigned char 			OcppServerURL[512];			//http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
 	unsigned char 			ChargeBoxId[128];
-	unsigned char			chargePointVendor[20];			//the Vendor of the ChargePoint
+	unsigned char			chargePointVendor[20];		//the Vendor of the ChargePoint
 	unsigned int 			Checksum;					//4 bytes checksum
+	struct LED				LedInfo[3];					// LED info maximum support 3 connector
 };
 
 struct ChargingInfoData

BIN
EVSE/rootfs/root/Module_PhBackend