浏览代码

2021.05.11 / Jerry Wang

Actions:
1. merge master conflict fixed.

Files:
1. As follow as commit history.
Jerry_Wang 4 年之前
父节点
当前提交
d9bfb84908
共有 30 个文件被更改,包括 2230 次插入443 次删除
  1. 11 3
      EVSE/Modularization/Makefile
  2. 1094 0
      EVSE/Modularization/Module_Payment.c
  3. 190 0
      EVSE/Modularization/Module_Payment.h
  4. 8 0
      EVSE/Modularization/WebService.c
  5. 2 2
      EVSE/Modularization/ocpp20/JsonParser.c
  6. 278 82
      EVSE/Modularization/ocpp20/MessageHandler.c
  7. 3 3
      EVSE/Modularization/ocpp20/MessageHandler.h
  8. 1 0
      EVSE/Modularization/ocpp20/Module_OcppBackend20.c
  9. 49 27
      EVSE/Modularization/ocppfiles/MessageHandler.c
  10. 1 0
      EVSE/Modularization/ocppfiles/Module_OcppBackend.c
  11. 189 215
      EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c
  12. 2 2
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h
  13. 5 0
      EVSE/Projects/AW-CCS/Apps/Module_AlarmDetect.c
  14. 39 2
      EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c
  15. 122 38
      EVSE/Projects/AW-CCS/Apps/main.c
  16. 二进制
      EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin
  17. 二进制
      EVSE/Projects/AW-CCS/Images/ramdisk.gz
  18. 79 19
      EVSE/Projects/AW-ChargeLab/Apps/main.c
  19. 二进制
      EVSE/Projects/AW-ChargeLab/Images/FactoryDefaultConfig.bin
  20. 二进制
      EVSE/Projects/AW-ChargeLab/Images/ramdisk.gz
  21. 79 19
      EVSE/Projects/AW-Regular/Apps/main.c
  22. 21 5
      EVSE/Projects/Noodoe/Apps/main.c
  23. 34 25
      EVSE/Projects/define.h
  24. 9 0
      EVSE/rootfs/etc/init.d/rcS
  25. 1 0
      EVSE/rootfs/root/.gitignore
  26. 二进制
      EVSE/rootfs/root/Module_Payment
  27. 二进制
      EVSE/rootfs/root/OcppBackend20
  28. 1 1
      EVSE/rootfs/var/www/head.php
  29. 8 0
      EVSE/rootfs/var/www/set_charging.php
  30. 4 0
      EVSE/rootfs/var/www/set_charging_action.php

+ 11 - 3
EVSE/Modularization/Makefile

@@ -5,9 +5,10 @@ export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)/usr/bin:$PATH
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
 
 all: clean Module_RFIDLib Module_Wifi WebServiceLib Ocpp16 \
 all: clean Module_RFIDLib Module_Wifi WebServiceLib Ocpp16 \
-		Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj \
-			Module_EventLogging Module_ProduceUtils Module_PhBackend \
-				Ocpp20 Module_InitUpgrade Module_RatedCurrentLib
+     Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj \
+     Module_EventLogging Module_ProduceUtils Module_PhBackend \
+     Ocpp20 Module_InitUpgrade Module_RatedCurrentLib Module_Payment
+
 
 
 
 
 clean:
 clean:
@@ -118,3 +119,10 @@ Module_InitUpgrade:
 	$(CC) -o Module_InitUpgrade Module_InitUpgrade.o
 	$(CC) -o Module_InitUpgrade Module_InitUpgrade.o
 	rm -f Module_InitUpgrade.o
 	rm -f Module_InitUpgrade.o
 	mv -f Module_InitUpgrade ../rootfs/root
 	mv -f Module_InitUpgrade ../rootfs/root
+
+Module_Payment:
+	rm -f Module_Payment
+	$(CC) -D $(Project) -I ../Projects -O0 -g3 -Wall -c -fmessage-length=0 -o Module_Payment.o Module_Payment.c
+	$(CC) -o Module_Payment Module_Payment.o
+	rm -f Module_Payment.o
+	mv -f Module_Payment ../rootfs/root

+ 1094 - 0
EVSE/Modularization/Module_Payment.c

@@ -0,0 +1,1094 @@
+/*
+ * Module_Payment.c
+ *
+ *  Created on: 2021/03/24
+ *      Author: Henry Yeh
+ */
+
+#include	"Module_Payment.h"
+unsigned char version[]					= {'D', '0', '.', '0', '3'};
+unsigned char BLP_CMD_CARD_DETECT[]		= {0x09, 0, 0x07, 'M','F','1','4','1','2','1', 0x32};				// Enable payment, MIFARE, 15693 card; Detect Payment Card First;  Enable ApplePay VAS
+unsigned char BLP_CMD_USI2[]     		= {0x09, 0, 0x03, 'P', 'C', '0', 0x29};								// Configure protocol to USI2
+unsigned char BLP_CMD_SET_BAUD[] 		= {0x09, 0, 0x03, 'B', 'R', '7', 0x2d};								// Configure module baud rate to 115200
+unsigned char BLP_CMD_RESTORE_DEFAULT[]	= {0x09, 0, 0x03, 'D', 'F', 0, 0x08 };								// Restore module configuration to default setting
+unsigned char BLP_CMD_TLV_ENABLE[]		= {0x09, 0, 0x03, 'A', 'A', 'E', 'O'};								// Enable TLV command to support EMV transaction
+unsigned char BLP_CMD_SET_AID[]			= {0x09, 0, 0x04, 'A', 'D', '0', 0, 0x38};							// Set AID type, 0x00: user defined AID		0x01: Default AID
+unsigned char BLP_CMD_LED_IND[]			= {0x09, 0, 0x05, 'R', 'I', 'E', 0x01, 0x01, 'R'};					// Reader LED indicator
+unsigned char BLP_CMD_CA_PKEY[]			= {0x09, 0, 0x03, 'C', 'K', 0x01, 0x03};							// Enable user CA Key
+unsigned char BLP_CMD_SOFTCARD_DISABLE[]= {0x09, 0, 0x03, 'I', 'S', 'D', 'T'};								// Disable soft card wallet application
+unsigned char BLP_CMD_ERR_BEEP_STYLE[] 	= {0x09, 0, 0x03, 'B', 'D', 0, 0x0c};								// Error beep style configure 2 beeps
+unsigned char BLP_CMD_ERR_BEEP[]		= {0x09, 0, 0x03, 'B', 'T', 'D', 'X'};								// Error beep give sound
+unsigned char BLP_CMD_LRC_ENABLE[]		= {0x09, 0, 0x03, 'L', 'C', 'E', '@'};								// Enable LRC character of track data
+unsigned char BLP_CMD_TX_TRACK[]		= {0x09, 0, 0x03, 'T', 'K', '3', '&'};								// Configure output track data 1&2
+
+unsigned char USI_CMD_WARM_RESET[]		= {0x01, 0x00, 0x00, 0x01, 0x7f, 0x7f};								// Payment module warm reset
+unsigned char USI_CMD_MODULE_STATUS[]	= {0x01, 0x00, 0x00, 0x01, 0x24, 0x24};			   					// Deactivate reader
+unsigned char USI_CMD_C8_DEACTIVAVE[]	= {0x01, 0x00, 0x00, 0x02, 0xc8, 0x00, 0x00};   					// Deactivate reader
+unsigned char USI_CMD_C8_POLL[]			= {0x01, 0x00, 0x00, 0x2b,											// STX, address, command length high byte, command length low byte
+										   0xc8, 0x01,														// Activate the reader
+										   0x9f, 0x02, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,			// Amount, Authorized, sample: 100.00 dollar
+										   0x5f, 0x2a, 0x02, 0x08, 0x40,									// Transaction Currency Code follow ISO-4217, sample: 0840(USD)
+										   0x5f, 0x36, 0x01, 0x02,											// Transaction Currency Exponent, Identifies the decimal point position from the right of the transaction amount according to ISO 4217
+	                         	   	   	   0x9c, 0x01, 0x00,												// Transaction Type, sample: 00
+										   0x9a, 0x03, 0x21, 0x03, 0x24,									// Transaction Date, sample: 2021/03/24
+										   0x9f, 0x21, 0x03, 0x13, 0x36, 0x10,								// Transaction Time, sample: 13:36:10
+										   0xff, 0xff, 0x82, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00,			// Command timeout unit is million second, sample: umlimit
+										   0x00};															// Checksum
+unsigned char USI_CMD_HALT_CARD[]		= {0x01, 0x00, 0x00, 0x01, 'x', 0x78};								// Halt card
+unsigned char USI_CMD_SET_DATE[]		= {0x01, 0, 0, 0x07, '5', '4', 0x14, 0x15, 0x05, 0x02, 0x01, 0x18};
+unsigned char USI_CMD_SET_TIME[]		= {0x01, 0, 0, 0x07, '5', '5', 0x0f, 0x1e, 0x20, 0, 0, 0x37};
+unsigned char USI_CMD_ARM_DISABLE[]		= {0x01, 0, 0, 0x02, 'H', '0', '{'};
+unsigned char USI_CMD_NFC_POLL[]		= {0x01, 0, 0, 0x05, 'N', ' ', '3', 0x02, 0x01, 'Z'};				// Polling FELICA(NFC Type 3, 414kbps)
+
+
+int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx);
+int USI2_Parse(unsigned char* rx, unsigned char* rx_data);
+
+struct C9_RESULT
+{
+	unsigned char result_data[512];			// C9 response data without header & checksum
+	
+	unsigned char status;					// C9 response status
+	unsigned char pos_entry;				// C9 response pos entry
+	unsigned char u_id[20];					// Card SN
+	unsigned char tkData[4][128];			// Card TK data for credit card
+	unsigned char isCardPreset:1;			// Card is presented on module, 0: removed	1: presented
+	unsigned char isCommandError:1;			// Polling command result, 0: normal	1: error
+} C9_Result;
+
+//==========================================
+// Common routine
+//==========================================
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[65536+256];
+	char buffer[65536];
+	//char Buf[4096+256];
+	//char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	struct timeval tv;
+	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);
+	gettimeofday(&tv, NULL); // get microseconds, 10^-6
+
+	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >>  /Storage/SystemLog/[%04d.%02d]PaymentLog",
+			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
+			buffer,
+			tm->tm_year+1900,tm->tm_mon+1);
+	system((const char*)Buf);
+
+#ifdef ConsloePrintLog
+	printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
+#endif
+
+	return rc;
+}
+/**
+ * Execute shell command
+ * @param cmd: shell command string
+ * @return shell command execution result
+ */
+int runShellCmd(const char*cmd)
+{
+	int result = FAIL;
+	char buf[256];
+	FILE *fp;
+
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			DEBUG_INFO("%s\n", buf);
+		}
+
+		result = PASS;
+	}
+	pclose(fp);
+
+	return result;
+}
+
+/**
+ * Calculate time differential
+ * @param ST: start time
+ * @param ET: end time
+ * @return time differential in million seconds
+ */
+int DiffTimeb(struct timeb ST, struct timeb ET)
+{
+	//return milli-second
+	unsigned int StartTime,StopTime;
+
+	StartTime=(unsigned int)ST.time;
+	StopTime=(unsigned int)ET.time;
+	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
+}
+
+/**
+ * Show communication raw data to debug info
+ * @param data: raw data
+ * @param len: data length
+ * @param isRX: is receive data
+ */
+void show_raw(uint8_t *data, uint16_t len, uint8_t isRX)
+{
+	uint8_t output[8192];
+
+	memset(output, 0x00, ARRAY_SIZE(output));
+	sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
+	for(uint16_t idx = 0;idx<len;idx++)
+	{
+		sprintf((char*)output, "%s%02x ", output, data[idx]);
+	}
+
+	DEBUG_INFO("%s\n", output);
+}
+
+
+/**
+ * Show data to debug info
+ * @param dat: data content
+ * @param len: data length
+ */
+void show_data(unsigned char *dat, unsigned int len)
+{
+	uint8_t output[8192];
+
+	memset(output, 0x00, ARRAY_SIZE(output));
+	sprintf((char*)output, "Data: ");
+	for(uint16_t idx = 0;idx<len;idx++)
+	{
+		if(dat[idx] > 31 && dat[idx] < 128 )
+			sprintf((char*)output, "%s%c", output, dat[idx]);
+		else
+			sprintf((char*)output, "%s<%x>", output, dat[idx]);
+	}
+
+	DEBUG_INFO("%s\n", output);
+}
+
+/**
+ * Get sentinel quantity in data array
+ * @param data: message array address
+ * @param dataLen: array seek size
+ * @return how many sentinel flag found
+ */
+int getSentinelQuantity(unsigned char *data, unsigned int dataLen)
+{
+	int result = 0;
+
+	for(uint16_t idx=0;idx<dataLen;idx++)
+	{
+		if(data[idx] == '?')
+			result++;
+	}
+
+	return result;
+}
+
+/**
+ * Get sentinel position in array
+ * @param data: message array address
+ * @param dataLen: array seek size
+ * @param idxSentinel: which sentinel idx want to find, since 0 start
+ * @return sentinel position in array
+ */
+int getSentinelPosition(unsigned char *data, unsigned int dataLen, unsigned char idxSentinel)
+{
+	int result = -1;
+	int foundCnt = -1;
+
+	for(uint16_t idx=0;idx<dataLen;idx++)
+	{
+		if(data[idx] == '?')
+			foundCnt++;
+
+		if(foundCnt == idxSentinel)
+		{
+			result = idx;
+			break;
+		}
+	}
+
+	return result;
+}
+
+/**
+ *
+ * @param dec: number in dec
+ * @return number in bcd
+ */
+int decTobcd(int dec)
+{
+	return (dec/10 * 16)+ (dec%10);
+}
+
+/**
+ *
+ * @param data: message array
+ * @param dataLen: command & data field length in array
+ * @return check sum result
+ */
+int calChksum(unsigned char *data, unsigned int dataLen)
+{
+	int result = 0;
+
+	for(uint16_t idx=0;idx<dataLen-1;idx++)
+	{
+		result ^= data[idx];
+	}
+
+	return (result&0xff);
+}
+
+//==========================================
+// Init share memory
+//==========================================
+/**
+ * Share memory initialization
+ * @return function result
+ */
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+#ifndef X86
+	//init ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
+    	result = FAIL;
+   	 }
+    else
+    {}
+
+	//init ShmStatusCodeData
+	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
+		result = FAIL;
+	}
+	else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
+		result = FAIL;
+	}
+	else
+	{}
+#endif
+
+   	return result;
+}
+
+//==========================================
+// Init com port
+//==========================================
+/**
+ * TTY port initialization
+ * @return port initial result
+ */
+int InitComPort()
+{
+	int fd;
+	struct termios tios;
+#ifndef X86
+	fd = open("/dev/ttyS3", O_RDWR);
+#else
+	fd = open("/dev/ttyUSB3", O_RDWR);
+#endif
+	if(fd<=0)
+	{
+		return FAIL;
+	}
+	ioctl (fd, TCGETS, &tios);
+	tios.c_cflag = B9600| CS8 | CLOCAL | CREAD;
+	tios.c_lflag = 0;
+	tios.c_iflag = 0;
+	tios.c_oflag = 0;
+	tios.c_cc[VMIN]=0;						// data length threshold, 0 bytes
+	tios.c_cc[VTIME]=(unsigned char)5;		// timeout threshold, 0.5 seconds
+	tios.c_lflag=0;
+	tcflush(fd, TCIFLUSH);
+	ioctl (fd, TCSETS, &tios);
+
+	return fd;
+}
+
+/**
+ * Send command to UIC680fg module.
+ * @param uart: port handle
+ * @param cmd: command buffer
+ * @param cmd_len: command length
+ * @param rx: receive buffer
+ * @return receive data length
+ */
+int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx)
+{
+	int rx_len = 0;
+
+	tcflush(uart,TCIOFLUSH);
+	//show_raw(cmd, cmd_len, NO);
+	if(write(uart, cmd, cmd_len) > 0)
+	{
+		usleep(100000);
+		rx_len = read(uart, rx, 512);
+
+		//show_raw(rx, rx_len, YES);
+	}
+	else
+	{
+		  DEBUG_ERROR("system command write fail.\n");
+	}
+
+	return rx_len;
+}
+
+/**
+ * Parsing raw data to USI data
+ * @param rx: raw data
+ * @param rx_data: parsing result data
+ * @return parsing result data length
+ */
+int USI2_Parse(unsigned char* rx, unsigned char* rx_data)
+{
+	int result = -1;
+	unsigned int data_len =0;
+	unsigned int chksum = 0;
+	
+	if(rx[0] == SOH)	// SOH = 0x01
+	{
+		data_len = (unsigned int)rx[2] <<8;
+		data_len |= rx[3];
+		
+		for(int idx=0;idx<(data_len+4);idx++)
+        {
+        	chksum ^= rx[idx];
+        }
+        
+        if((chksum&0xff) == rx[(data_len+4)])
+        {
+			memcpy(rx_data, &rx[4], data_len);
+			result = data_len;
+		}
+        else
+        	DEBUG_WARN("USI2 message checksum error.\n");
+	}
+	else 
+	{
+		DEBUG_WARN("USI2 message header is not <01>.\n");
+	}
+
+	return result;
+}
+
+//==========================================
+// Main loop
+//==========================================
+int main(void)
+{
+	int UartFd;
+	uint16_t failCount = 0;
+	unsigned char rx_Array[512]={0}, rx_Data[512]={0};
+	char C8_Polling = true;
+	char Wait_C9 = false;
+	int rx_len = 0;
+	int data_len = 0;
+	time_t CurrentTime;
+	struct tm *tm;
+
+	DEBUG_INFO("Task version: %s\n", version);
+	//===============================================
+	// Initialization
+	//===============================================
+#ifndef X86
+	if(InitShareMemory() == FAIL)
+	{
+		DEBUG_ERROR("InitShareMemory NG\n");
+
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
+		}
+		sleep(5);
+		return FAIL;
+	}
+#endif
+	UartFd=InitComPort();
+	if(UartFd<0)
+	{
+		DEBUG_ERROR("InitComPort NG\n");
+		if(ShmStatusCodeData!=NULL)
+		{
+#ifndef X86
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
+#endif
+		}
+		sleep(5);
+		return FAIL;
+	}
+	else
+	{
+		DEBUG_INFO("ttyS3 port open success.\n");
+	}
+
+	//===============================================
+	// Payment module configuration set to default (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_RESTORE_DEFAULT, ARRAY_SIZE(BLP_CMD_RESTORE_DEFAULT), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set to the default success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set to the default fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set to the default fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len != 1));
+
+	//===============================================
+	// set to protocol_2 (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len =system_command(UartFd, BLP_CMD_USI2, ARRAY_SIZE(BLP_CMD_USI2), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set protocol to USI2 success.\n");
+			DEBUG_INFO("Wait for payment module warm-reset.\n");
+			sleep(10);
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set protocol to USI2 fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set protocol to USI2 fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Disable self-arm mode (USI2 Protocol)
+	//===============================================
+	do
+	{
+		USI_CMD_ARM_DISABLE[ARRAY_SIZE(USI_CMD_ARM_DISABLE)-1] = calChksum(USI_CMD_ARM_DISABLE, ARRAY_SIZE(USI_CMD_ARM_DISABLE));
+		system_command(UartFd, USI_CMD_ARM_DISABLE, ARRAY_SIZE(USI_CMD_ARM_DISABLE), rx_Array);
+		rx_len = USI2_Parse(rx_Array, rx_Data);
+		if((rx_Data[0] == ACK) && (rx_len >= 0))
+		{
+			DEBUG_INFO("Set disable self-arm mode success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set disable self-arm mode fail (<%02x>).\n", rx_Data[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set disable self-arm mode fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Data[0] != ACK) || (rx_len < 0));
+
+	//===============================================
+	// Enable TLV command (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_TLV_ENABLE, ARRAY_SIZE(BLP_CMD_TLV_ENABLE), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set enable TLV command success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set enable TLV command fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set enable TLV command fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len != 1));
+
+	//===============================================
+	// Set AID type (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_SET_AID, ARRAY_SIZE(BLP_CMD_SET_AID), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set AID type success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set AID type fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set AID type fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len != 1));
+
+	//===============================================
+	// Set LED indicator (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_LED_IND, ARRAY_SIZE(BLP_CMD_LED_IND), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set LED indicator success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set LED indicator fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set LED indicator over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len != 1));
+
+	//===============================================
+	// Set CA public key type (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_CA_PKEY, ARRAY_SIZE(BLP_CMD_CA_PKEY), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set CA public key type success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set CA public key type fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set CA public key type over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len != 1));
+
+	//===============================================
+	// Set payment card detect type (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_CARD_DETECT, ARRAY_SIZE(BLP_CMD_CARD_DETECT), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set payment card type success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set payment card type fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set payment card type fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Disable soft card wallet application (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_SOFTCARD_DISABLE, ARRAY_SIZE(BLP_CMD_SOFTCARD_DISABLE), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set disable soft card success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set disable soft card fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set disable soft card fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Set error beep style (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_ERR_BEEP_STYLE, ARRAY_SIZE(BLP_CMD_ERR_BEEP_STYLE), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set error beep style success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set error beep style fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set error beep style fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Set error beep (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_ERR_BEEP, ARRAY_SIZE(BLP_CMD_ERR_BEEP), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set error beep success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set error beep fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set error beep fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Set enable LRC (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_LRC_ENABLE, ARRAY_SIZE(BLP_CMD_LRC_ENABLE), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set enable LRC success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set enable LRC fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set enable LRC fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+
+	//===============================================
+	// Set TX data tracks (BLP Protocol)
+	//===============================================
+	do
+	{
+		rx_len = system_command(UartFd, BLP_CMD_TX_TRACK, ARRAY_SIZE(BLP_CMD_TX_TRACK), rx_Array);
+		if((rx_Array[0] == ACK) && (rx_len ==1))
+		{
+			DEBUG_INFO("Set TX data tracks success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set TX data tracks fail (<%02x>).\n", rx_Array[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set TX data tracks over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Array[0] != ACK) || (rx_len !=1));
+	
+	//===============================================
+	// Set module RTC date (USI2 Protocol)
+	//===============================================
+	do
+	{
+		CurrentTime = time(NULL);
+		tm=localtime(&CurrentTime);
+		USI_CMD_SET_DATE[6] = ((tm->tm_year+1900)/100);
+		USI_CMD_SET_DATE[7] = ((tm->tm_year+1900)%100);
+		USI_CMD_SET_DATE[8] = (tm->tm_mon+1);
+		USI_CMD_SET_DATE[9] = tm->tm_mday;
+		USI_CMD_SET_DATE[10] = tm->tm_wday==0?0x07:tm->tm_wday;
+		USI_CMD_SET_DATE[ARRAY_SIZE(USI_CMD_SET_DATE)-1] = calChksum(USI_CMD_SET_DATE, ARRAY_SIZE(USI_CMD_SET_DATE));
+		system_command(UartFd, USI_CMD_SET_DATE, ARRAY_SIZE(USI_CMD_SET_DATE), rx_Array);
+		rx_len = USI2_Parse(rx_Array, rx_Data);
+		if((rx_Data[0] == ACK) && (rx_len >= 0))
+		{
+			DEBUG_INFO("Set module RTC date success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set module RTC date fail (<%02x>).\n", rx_Data[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set module RTC date fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Data[0] != ACK) || (rx_len < 0));
+
+	//===============================================
+	// Set module RTC time (USI2 Protocol)
+	//===============================================
+	do
+	{
+		CurrentTime = time(NULL);
+		tm=localtime(&CurrentTime);
+		USI_CMD_SET_TIME[6] = tm->tm_hour;
+		USI_CMD_SET_TIME[7] = tm->tm_min;
+		USI_CMD_SET_TIME[8] = tm->tm_sec;
+		USI_CMD_SET_TIME[ARRAY_SIZE(USI_CMD_SET_TIME)-1] = calChksum(USI_CMD_SET_TIME, ARRAY_SIZE(USI_CMD_SET_TIME));
+		system_command(UartFd, USI_CMD_SET_TIME, ARRAY_SIZE(USI_CMD_SET_TIME), rx_Array);
+		rx_len = USI2_Parse(rx_Array, rx_Data);
+		if((rx_Data[0] == ACK) && (rx_len >= 0))
+		{
+			DEBUG_INFO("Set module RTC time success.\n");
+			failCount = 0;
+		}
+		else
+		{
+			DEBUG_WARN("Set module RTC time fail (<%02x>).\n", rx_Data[0]);
+			failCount++;
+		}
+
+		if(failCount > RETRY_LIMIT)
+		{
+			DEBUG_ERROR("Set module RTC time fail over retry limit.\n");
+			return FAIL;
+		}
+	}while((rx_Data[0] != ACK) || (rx_len < 0));
+
+	//===============================================
+	// Main loop
+	//===============================================
+	for(;;)
+	{
+		if(C8_Polling == true)
+		{
+			Wait_C9 = false;
+			CurrentTime = time(NULL);
+			tm=localtime(&CurrentTime);
+
+			USI_CMD_C8_DEACTIVAVE[ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE)-1] = calChksum(USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE));
+			if(system_command(UartFd, USI_CMD_C8_DEACTIVAVE, ARRAY_SIZE(USI_CMD_C8_DEACTIVAVE), rx_Array) > 0)
+			{
+				rx_len = USI2_Parse(rx_Array, rx_Data);
+				if((rx_Data[0] == ACK) && (rx_len >= 0))
+				{
+					DEBUG_INFO("C8 deactivate command success.\n");
+					failCount = 0;
+
+					USI_CMD_C8_POLL[9]  = decTobcd((1000/10000000000)%100);
+					USI_CMD_C8_POLL[10] = decTobcd((1000/100000000)%100);
+					USI_CMD_C8_POLL[11] = decTobcd((1000/1000000)%100);
+					USI_CMD_C8_POLL[12] = decTobcd((1000/10000)%100);
+					USI_CMD_C8_POLL[13] = decTobcd((1000/100)%100);
+					USI_CMD_C8_POLL[14] = decTobcd((1000/1)%100);
+					USI_CMD_C8_POLL[18] = (CURRENCY_USD>>0x08)&0xff;
+					USI_CMD_C8_POLL[19] = (CURRENCY_USD>>0x00)&0xff;
+					USI_CMD_C8_POLL[29] = decTobcd((tm->tm_year+1900)-2000);
+					USI_CMD_C8_POLL[30] = decTobcd(tm->tm_mon+1);
+					USI_CMD_C8_POLL[31] = decTobcd(tm->tm_mday);
+					USI_CMD_C8_POLL[35] = decTobcd(tm->tm_hour);
+					USI_CMD_C8_POLL[36] = decTobcd(tm->tm_min);
+					USI_CMD_C8_POLL[37] = decTobcd(tm->tm_sec);
+					USI_CMD_C8_POLL[ARRAY_SIZE(USI_CMD_C8_POLL)-1] = calChksum(USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL));
+
+					if(system_command(UartFd, USI_CMD_C8_POLL, ARRAY_SIZE(USI_CMD_C8_POLL), rx_Array) > 0)
+					{
+						rx_len = USI2_Parse(rx_Array, rx_Data);
+						if((rx_Data[0] == ACK) && (rx_len >= 0))
+						{
+							DEBUG_INFO("C8 polling command success.\n");
+							Wait_C9 = true;
+							failCount = 0;
+							C9_Result.isCommandError = OFF;
+						}
+						else
+						{
+							DEBUG_INFO("C8 polling command fail (<%02x>).\n", rx_Data[0]);
+							C9_Result.isCommandError = ON;
+						}
+					}
+				}
+				else
+				{
+					DEBUG_INFO("C8 deactivate command fail.\n");
+					C9_Result.isCommandError = ON;
+				}
+			}
+
+			if(Wait_C9 == true)
+			{
+				//=============================================
+				// wait card to attach the reader and wait C9
+				//=============================================
+				tcflush(UartFd,TCIOFLUSH);
+				memset(rx_Array, 0x00, ARRAY_SIZE(rx_Array));
+				rx_len = 0;
+
+				do
+				{
+					DEBUG_INFO("C9 response reading...\n");
+					usleep(2000000);
+					rx_len = read(UartFd, rx_Array, ARRAY_SIZE(rx_Array)); // read response if data count match 512 or timeout.
+					failCount++;
+				} while ((rx_len == 0) && (failCount < RETRY_LIMIT));
+
+				//=============================================
+				// Parse rx_Array to rx_Data
+				//=============================================
+				if((rx_len > 3)  && (failCount < RETRY_LIMIT))
+				{
+					// print this raw data before parse it.
+					//show_data(rx_Array, rx_len);
+
+					if((rx_len = USI2_Parse( rx_Array, rx_Data)) > 0)
+					{
+						// debug the input data message
+						//show_data(rx_Data, rx_len);
+
+						// Copy RAW data to structure
+						memcpy(&C9_Result.result_data, rx_Data, rx_len);
+						C9_Result.status = C9_Result.result_data[1];
+						C9_Result.pos_entry = C9_Result.result_data[2];
+
+						switch(C9_Result.pos_entry)
+						{
+							case VISA_qVSDC:
+							case VISA_MSD:
+							case MASTER_MChip:
+							case Master_MagStripe:
+							case AMEX_EMV:
+							case AMEX_MSD:
+								memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
+								memcpy(C9_Result.u_id, &C9_Result.result_data[5], 16);
+								DEBUG_INFO("Credit card SN:\n");
+								show_data(C9_Result.u_id, 16);
+
+								for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
+								{
+									memset(C9_Result.tkData[idx], 0x00, ARRAY_SIZE(C9_Result.tkData[idx]));
+									memcpy(C9_Result.tkData[idx],
+										   &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
+										   (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
+
+									DEBUG_INFO("TK[%d]: \n", idx);
+									show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
+								}
+								break;
+							case Mifare:
+								data_len = C9_Result.result_data[6];
+								memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
+								memcpy(C9_Result.u_id, &C9_Result.result_data[7], data_len);
+
+								switch(C9_Result.result_data[3])
+								{
+									case MIFARE_ULTRALIGHT:
+										DEBUG_INFO("MIFARE Ultralight, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
+										break;
+									case MIFARE_CLASSIC_1K:
+										DEBUG_INFO("MIFARE Classic 1K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
+										break;
+									case MIFARE_CLASSIC_4K:
+										DEBUG_INFO("MIFARE Classic 4K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
+										break;
+									case MIFARE_DESFIRE:
+										DEBUG_INFO("MIFARE DESFire, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
+										break;
+									case MIFARE_PLUS_2K:
+										DEBUG_INFO("MIFARE Plus 2k, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
+										break;
+									case MIFARE_MINI:
+										DEBUG_INFO("MIFARE Mini, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
+										break;
+									case MIFARE_RESERVE:
+										DEBUG_INFO("MIFARE Reserve, UID: \n");
+										break;
+									case MIFARE_JEWEL:
+										DEBUG_INFO("MIFARE Jewel, UID: \n");
+										break;
+									case MIFARE_JCOP31:
+										DEBUG_INFO("MIFARE JCOP31, UID: \n");
+										break;
+								}
+								break;
+							case ISO_15693:
+								data_len =(C9_Result.result_data[5]<<8) | C9_Result.result_data[6];
+								memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
+								memcpy(C9_Result.u_id, &C9_Result.result_data[4+data_len-8], 8);
+
+								DEBUG_INFO("ISO_15693, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6], C9_Result.u_id[7]);
+								break;
+							case Apple_Pay:
+								DEBUG_INFO("Apple_Pay VAS only.\n");
+								for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
+								{
+									memcpy(C9_Result.tkData[idx],
+										   &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
+										   (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
+
+									DEBUG_INFO("TK[%d]: \n", idx);
+									show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
+								}
+								break;
+							case No_Data:
+								DEBUG_INFO("No any data.\n");
+								break;
+							default:
+								DEBUG_WARN("Unknown pos entry.\n");
+								if(C9_Result.status == C9_RES_C8_CMD_TIMEOUT)
+									DEBUG_WARN("C8 command timeout.\n");
+								else if(C9_Result.status == C9_RES_CMD_EXECUTING)
+									DEBUG_WARN("Command executing or Wait Card to be Removed.\n");
+
+								break;
+						}
+						failCount = 0;
+
+						// Wait card removed
+						do
+						{
+							system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
+							rx_len = USI2_Parse(rx_Array, rx_Data);
+							if(!(rx_Data[0]&0x02) && (rx_len >= 0))
+							{
+								DEBUG_INFO("Card removed.\n");
+								C9_Result.isCardPreset = OFF;
+								failCount = 0;
+							}
+							else if((rx_Data[0]&0x02) && (rx_len >= 0))
+							{
+								//DEBUG_INFO("Card seated.\n");
+								C9_Result.isCardPreset = ON;
+								failCount = 0;
+							}
+							else
+							{
+								DEBUG_WARN("Module status read fail (<%02x>).\n", rx_Data[0]);
+								failCount++;
+							}
+
+							if(failCount > RETRY_LIMIT)
+							{
+								C9_Result.isCardPreset = OFF;
+								DEBUG_ERROR("Module status read fail over retry limit.\n");
+							}
+						}while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
+					}
+					else
+					{
+						DEBUG_INFO("C9 Parsing result fail.\n");
+						C9_Result.isCommandError = ON;
+						// Wait card removed
+						do
+						{
+							usleep(500000);
+							system_command(UartFd, USI_CMD_MODULE_STATUS, ARRAY_SIZE(USI_CMD_MODULE_STATUS), rx_Array);
+							rx_len = USI2_Parse(rx_Array, rx_Data);
+							if(!(rx_Data[0]&0x02) && (rx_len >= 0))
+							{
+								DEBUG_INFO("Card removed.\n");
+								C9_Result.isCardPreset = OFF;
+								C9_Result.isCommandError = OFF;
+								failCount = 0;
+							}
+							else if((rx_Data[0]&0x02) && (rx_len >= 0))
+							{
+								//DEBUG_INFO("Card seated.\n");
+								C9_Result.isCardPreset = ON;
+								failCount = 0;
+							}
+							else
+							{
+								DEBUG_WARN("Module status read fail (<%02x>).\n", rx_Data[0]);
+								failCount++;
+							}
+
+							if(failCount > RETRY_LIMIT)
+							{
+								C9_Result.isCardPreset = OFF;
+								DEBUG_ERROR("Module status read fail over retry limit.\n");
+							}
+						}while(((rx_Data[0]&0x02) || (rx_len < 0)) && (failCount < RETRY_LIMIT));
+					}
+				}
+				else
+				{
+					DEBUG_WARN("C9 Response timeout: %d \n", failCount);
+				}
+			}
+		}
+
+		usleep(1000000);
+	}
+
+	return FAIL;
+}

+ 190 - 0
EVSE/Modularization/Module_Payment.h

@@ -0,0 +1,190 @@
+/*
+ * Module_Payment.h
+ *
+ *  Created on: 2021/03/24
+ *      Author: Henry
+ */
+
+#ifndef MODULE_PAYMENT_H_
+#define MODULE_PAYMENT_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 	<math.h>
+#include	<limits.h>
+#include	<stdint.h>
+#include	"define.h"
+
+//#define	X86
+
+#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 is_error(ptr) 				((unsigned long)ptr > (unsigned long)-4000L)
+#define ARRAY_SIZE(A)				(sizeof(A) / sizeof(A[0]))
+#define PASS						1
+#define FAIL			   			-1
+#define ON							1
+#define OFF							0
+#define YES							1
+#define NO							0
+
+#define ACK							'^'
+#define NoExecute					'*'
+#define BadParameter				'!'
+#define SOH							0x01	// Protocol_2
+#define STX							0x02	// Protocol_1
+#define ETX							0x03	// Protocol_1	
+#define HT							0x09	// configure command
+
+
+#define RETRY_LIMIT					10
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+
+enum Boolean
+{
+	false=0,
+	true
+};
+
+enum CARD_TYPE_CODE
+{
+	VISA_qVSDC = 1,
+	VISA_MSD,
+	MASTER_MChip,
+	Master_MagStripe,
+	AMEX_EMV,
+	AMEX_MSD,
+	Android_Pay = 0x0A,
+	Apple_Pay = 0x0C,
+	UnionPay = 0x0D,
+	Mifare = 0x10,
+	ISO_15693 = 0x20,
+	No_Data	= 0x80,
+	Felica = 0xf0
+};
+
+enum C9_RES_CODE
+{
+	C9_RES_ONLINE_REQUIRED=0,
+	C9_RES_OFFLINE_APPROVED,
+	C9_RES_OFFLINE_DECLINED,
+	C9_RES_CARD_NOT_SUPPORT,
+	C9_RES_INITIATION_ERROR,
+	C9_RES_C8_CMD_CANCEL,
+	C9_RES_EMPTY_CANDIDATE_LIST,
+	C9_RES_C8_CMD_TIMEOUT,
+	C9_RES_CARD_BLOCK,
+	C9_RES_TRANSACTION_ERROR=0x0b,
+	C9_RES_AUTHENTICATION_ERROR,
+	C9_RES_MORE_CARD,
+	C9_RES_TIMEOUT_ONLINE_REQUIRED=0x0f,
+	C9_RES_TRY_AGAIN=0x12,
+	C9_RES_CMD_EXECUTING,
+	C9_RES_SEE_PHONE=0x20,
+	C9_RES_TRANSACTION_TERMINATE=0x39,
+	C9_RES_TRY_OTHER_INTERFACE=0x86,
+	C9_RES_TRY_OTHER_CARD=0x8e,
+};
+
+enum MIFARE_TYPE
+{
+	MIFARE_ULTRALIGHT=0x01,
+	MIFARE_CLASSIC_1K,
+	MIFARE_CLASSIC_4K,
+	MIFARE_DESFIRE,
+	MIFARE_PLUS_2K,
+	MIFARE_MINI,
+	MIFARE_RESERVE,
+	MIFARE_JEWEL,
+	MIFARE_JCOP31
+};
+
+enum CURRENCY_CODE
+{
+	CURRENCY_AED=0x0784,
+	CURRENCY_ARS=0x0032,
+	CURRENCY_AUD=0x0036,
+	CURRENCY_BGN=0x0975,
+	CURRENCY_BHD=0x0048,
+	CURRENCY_BND=0x0096,
+	CURRENCY_BRL=0x0986,
+	CURRENCY_BWP=0x0072,
+	CURRENCY_CAD=0x0124,
+	CURRENCY_CHF=0x0756,
+	CURRENCY_CLP=0x0152,
+	CURRENCY_CNY=0x0156,
+	CURRENCY_COP=0x0170,
+	CURRENCY_CZK=0x0203,
+	CURRENCY_DKK=0x0208,
+	CURRENCY_EUR=0x0978,
+	CURRENCY_GBP=0x0826,
+	CURRENCY_HKD=0x0344,
+	CURRENCY_HRK=0x0191,
+	CURRENCY_HUF=0x0348,
+	CURRENCY_IDR=0x0360,
+	CURRENCY_ILS=0x0376,
+	CURRENCY_INR=0x0356,
+	CURRENCY_IRR=0x0364,
+	CURRENCY_ISK=0x0352,
+	CURRENCY_JPY=0x0392,
+	CURRENCY_KRW=0x0410,
+	CURRENCY_KWD=0x0414,
+	CURRENCY_KZT=0x0398,
+	CURRENCY_LKR=0x0144,
+	CURRENCY_LYD=0x0434,
+	CURRENCY_MUR=0x0480,
+	CURRENCY_MXN=0x0484,
+	CURRENCY_MYR=0x0458,
+	CURRENCY_NOK=0x0578,
+	CURRENCY_NPR=0x0524,
+	CURRENCY_NZD=0x0554,
+	CURRENCY_OMR=0x0512,
+	CURRENCY_PHP=0x0608,
+	CURRENCY_PKR=0x0586,
+	CURRENCY_PLN=0x0985,
+	CURRENCY_QAR=0x0634,
+	CURRENCY_RON=0x0946,
+	CURRENCY_RUB=0x0643,
+	CURRENCY_SAR=0x0682,
+	CURRENCY_SEK=0x0752,
+	CURRENCY_SGD=0x0702,
+	CURRENCY_THB=0x0764,
+	CURRENCY_TRY=0x0949,
+	CURRENCY_TTD=0x0780,
+	CURRENCY_TWD=0x0901,
+	CURRENCY_USD=0x0840,
+	CURRENCY_VEF=0x0937,
+	CURRENCY_ZAR=0x0710,
+};
+
+#endif /* MODULE_PAYMENT_H_ */

+ 8 - 0
EVSE/Modularization/WebService.c

@@ -668,6 +668,7 @@ int main(int argc, char *argv[]) {
 			int MaxChargingCurrent = 0;
 			int MaxChargingCurrent = 0;
 			int AcMaxChargingCurrent = 0;
 			int AcMaxChargingCurrent = 0;
 			int MaxChargingDuration = 0;
 			int MaxChargingDuration = 0;
+			int StopChargingByButton = 0;
 			char *LocalWhiteCard0 = NULL;
 			char *LocalWhiteCard0 = NULL;
 			char *LocalWhiteCard1 = NULL;
 			char *LocalWhiteCard1 = NULL;
 			char *LocalWhiteCard2 = NULL;
 			char *LocalWhiteCard2 = NULL;
@@ -725,6 +726,10 @@ int main(int argc, char *argv[]) {
 				MaxChargingDuration = json_object_get_int(val_obj);
 				MaxChargingDuration = json_object_get_int(val_obj);
 				ShmSysConfigAndInfo->SysConfig.MaxChargingDuration = MaxChargingDuration;
 				ShmSysConfigAndInfo->SysConfig.MaxChargingDuration = MaxChargingDuration;
 			}
 			}
+			if( json_object_object_get_ex(jobj, "StopChargingByButton", &val_obj) ) {
+				StopChargingByButton = json_object_get_int(val_obj);
+				ShmSysConfigAndInfo->SysConfig.StopChargingByButton = StopChargingByButton;
+			}
 			if( json_object_object_get_ex(jobj, "LocalWhiteCard0", &val_obj) ) {
 			if( json_object_object_get_ex(jobj, "LocalWhiteCard0", &val_obj) ) {
 				LocalWhiteCard0 = (char*)json_object_get_string(val_obj);
 				LocalWhiteCard0 = (char*)json_object_get_string(val_obj);
 				strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0],LocalWhiteCard0);
 				strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0],LocalWhiteCard0);
@@ -1459,6 +1464,7 @@ int main(int argc, char *argv[]) {
 		struct json_object *MaxChargingCurrent;
 		struct json_object *MaxChargingCurrent;
 		struct json_object *AcMaxChargingCurrent;
 		struct json_object *AcMaxChargingCurrent;
 		struct json_object *MaxChargingDuration;
 		struct json_object *MaxChargingDuration;
+		struct json_object *StopChargingByButton;
 		struct json_object *LocalWhiteCard[10];
 		struct json_object *LocalWhiteCard[10];
 		struct json_object *LocalWhiteCardArr= json_object_new_array();
 		struct json_object *LocalWhiteCardArr= json_object_new_array();
 		struct json_object *isBilling;
 		struct json_object *isBilling;
@@ -1699,6 +1705,7 @@ int main(int argc, char *argv[]) {
 		MaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
 		MaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
 		AcMaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent);
 		AcMaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent);
 		MaxChargingDuration = json_object_new_int(ShmSysConfigAndInfo->SysConfig.MaxChargingDuration);
 		MaxChargingDuration = json_object_new_int(ShmSysConfigAndInfo->SysConfig.MaxChargingDuration);
+		StopChargingByButton = json_object_new_int(ShmSysConfigAndInfo->SysConfig.StopChargingByButton);
 		LocalWhiteCard[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0]);
 		LocalWhiteCard[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0]);
 		LocalWhiteCard[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[1]);
 		LocalWhiteCard[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[1]);
 		LocalWhiteCard[2] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[2]);
 		LocalWhiteCard[2] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[2]);
@@ -2215,6 +2222,7 @@ int main(int argc, char *argv[]) {
 		json_object_object_add(jobj2,"MaxChargingCurrent",MaxChargingCurrent);
 		json_object_object_add(jobj2,"MaxChargingCurrent",MaxChargingCurrent);
 		json_object_object_add(jobj2,"AcMaxChargingCurrent",AcMaxChargingCurrent);
 		json_object_object_add(jobj2,"AcMaxChargingCurrent",AcMaxChargingCurrent);
 		json_object_object_add(jobj2,"MaxChargingDuration",MaxChargingDuration);
 		json_object_object_add(jobj2,"MaxChargingDuration",MaxChargingDuration);
+		json_object_object_add(jobj2,"StopChargingByButton",StopChargingByButton);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[0]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[0]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[1]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[1]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[2]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[2]);

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

@@ -41,7 +41,7 @@ static char *requestNames[] = { "CancelReservation",
 								"Reset",
 								"Reset",
 								"SendLocalList",
 								"SendLocalList",
 								"SetChargingProfile",
 								"SetChargingProfile",
-								"SetDisplayMessage",
+								"SetDisplayMessages",
 								"SetMonitoringBase",
 								"SetMonitoringBase",
 								"SetMonitoringLevel",
 								"SetMonitoringLevel",
 								"SetNetworkProfile",
 								"SetNetworkProfile",
@@ -135,7 +135,7 @@ static FunCallPtr funcalls[] = {handleCancelReservationRequest,
 								handleResetRequest,
 								handleResetRequest,
 								handleSendLocalListRequest,
 								handleSendLocalListRequest,
 								handleSetChargingProfileRequest,
 								handleSetChargingProfileRequest,
-								handleSetDisplayMessageRequest,
+								handleSetDisplayMessagesRequest,
 								handleSetMonitoringBaseRequest,
 								handleSetMonitoringBaseRequest,
 								handleSetMonitoringLevelRequest,
 								handleSetMonitoringLevelRequest,
 								handleSetNetworkProfileRequest,
 								handleSetNetworkProfileRequest,

+ 278 - 82
EVSE/Modularization/ocpp20/MessageHandler.c

@@ -1347,6 +1347,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].component.name, "AlignedDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].component.name, "AlignedDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variable.name, "Measurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variable.name, "Measurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
+		ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
 		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
@@ -1384,6 +1385,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].component.name, "AlignedDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].component.name, "AlignedDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
+		ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
 		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
@@ -1488,7 +1490,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].component.name, "AuthCacheCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].component.name, "AuthCacheCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variable.name, "Storage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variable.name, "Storage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.maxLimit = (1024*100);
+		ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.maxLimit = (1024*10);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].value, "TRUE");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].value, "TRUE");
@@ -1721,9 +1723,10 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].component.name, "DisplayMessageCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].component.name, "DisplayMessageCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variable.name, "DisplayMessages");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variable.name, "DisplayMessages");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
+		ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableCharacteristics.maxLimit = 1;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].value, "%s", "0");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].value, "%s", "1");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages]);
 
 
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].component.name, "DisplayMessageCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].component.name, "DisplayMessageCtrlr");
@@ -1787,6 +1790,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		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_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].value, "5000");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].value, "5000");
@@ -1821,7 +1825,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].component.name, "LocalAuthListCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variable.name, "Storage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variable.name, "Storage");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.maxLimit = 1024*1024;
+		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.maxLimit = (1024*10);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].value, "5000");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].value, "5000");
@@ -2063,9 +2067,14 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
+		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, " ");
+		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
+			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,Energy.Active.Import.Interval,Power.Active.Import,Voltage,SOC");
+		else
+			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,Energy.Active.Import.Interval,Power.Active.Import,Voltage");
+
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands]);
 
 
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].component.name, "SampledDataCtrlr");
@@ -2080,6 +2089,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variable.name, "TxStartedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variable.name, "TxStartedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
+		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].value, " ");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].value, " ");
@@ -2088,9 +2098,13 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variable.name, "TxUpdatedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variable.name, "TxUpdatedMeasurands");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
+		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, " ");
+		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
+			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, "Current.Import,Energy.Active.Import.Register,Energy.Active.Import.Interval,Power.Active.Import,Voltage,SOC");
+		else
+			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, "Current.Import,Energy.Active.Import.Register,Energy.Active.Import.Interval,Power.Active.Import,Voltage");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands]);
 
 
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].component.name, "SampledDataCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].component.name, "SampledDataCtrlr");
@@ -2109,7 +2123,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
 		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.maxLimit = 40;
 		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.maxLimit = 40;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, " ");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, " ");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword]);
 
 
@@ -2133,8 +2147,9 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].component.name, "SecurityCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].component.name, "SecurityCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variable.name, "CertificateEntries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variable.name, "CertificateEntries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
+		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableCharacteristics.maxLimit = 1;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].value, "1");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].value, "1");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries]);
 
 
@@ -2154,6 +2169,15 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableAttribute[0].value, "FALSE");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableAttribute[0].value, "FALSE");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck]);
 
 
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].component.name, "SecurityCtrlr");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variable.name, "MaxCertificateChainSize");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
+		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableCharacteristics.maxLimit = 10000;
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].value, "10000");
+		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize]);
+
 		/* SmartChargingCtrlr Required item */
 		/* SmartChargingCtrlr Required item */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
@@ -2230,9 +2254,10 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
+		ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableCharacteristics.maxLimit = 10;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].value, "3");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].value, "10");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries]);
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries]);
 
 
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].component.name, "SmartChargingCtrlr");
@@ -2699,6 +2724,9 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].component.name, "SecurityCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].component.name, "SecurityCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variable.name, "AdditionalRootCertificateCheck");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variable.name, "AdditionalRootCertificateCheck");
 
 
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].component.name, "SecurityCtrlr");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variable.name, "MaxCertificateChainSize");
+
 		/* SmartChargingCtrlr Required item */
 		/* SmartChargingCtrlr Required item */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
@@ -5190,6 +5218,46 @@ void CheckSystemValue(void)
 		sendAuthorizeRequest(0);
 		sendAuthorizeRequest(0);
 	}
 	}
 
 
+
+	if(isWebsocketSendable &&
+		   (server_sign == TRUE) &&
+		   (ShmOCPP20Data->GetMonitoringReport.requestId > 0))
+	{
+		for(uint8_t idxCriterion=0;idxCriterion<ARRAY_SIZE(ShmOCPP20Data->GetMonitoringReport.monitoringCriteria);idxCriterion++)
+		{
+			if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion],  MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_ThresholdMonitoring]) == 0)
+			{
+				/*
+				 * TODO:
+				 * 	1. Report component that are ThresholdMonitoring
+				 */
+			}
+			else if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion], MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_DeltaMonitoring]) == 0)
+			{
+				/*
+				 * TODO:
+				 * 	1. Report component that are DeltaMonitoring
+				 */
+			}
+			else if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion], MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_PeriodicMonitoring]) == 0)
+			{
+				/*
+				 * TODO:
+				 * 	1. Report component that are PeriodicMonitoring
+				 */
+			}
+			else
+			{
+				/*
+				 * TODO:
+				 * 	1. Process unknown criteria condition
+				 */
+			}
+		}
+
+		ShmOCPP20Data->GetMonitoringReport.requestId = 0;
+	}
+
 	if(isWebsocketSendable &&
 	if(isWebsocketSendable &&
 	   (server_sign == TRUE) &&
 	   (server_sign == TRUE) &&
 	   (ShmOCPP20Data->GetReport.requestId > 0))
 	   (ShmOCPP20Data->GetReport.requestId > 0))
@@ -5339,15 +5407,24 @@ void CheckSystemValue(void)
 	{
 	{
 		if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Install]) == 0)
 		if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Install]) == 0)
 		{
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 		}
 		else if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Update]) == 0)
 		else if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Update]) == 0)
 		{
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 		}
 		else
 		else
 		{
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 		}
 
 
 		sendGet15118EVCertificateRequest();
 		sendGet15118EVCertificateRequest();
@@ -5355,8 +5432,6 @@ void CheckSystemValue(void)
 	}
 	}
 
 
 
 
-
-
 	//===============================
 	//===============================
 	// Each connector operation check
 	// Each connector operation check
 	//===============================
 	//===============================
@@ -6006,7 +6081,14 @@ void CheckSystemValue(void)
 		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf == ON))
 		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf == ON))
 		{
 		{
 			sendReserveNowConfirmation((char *)ShmOCPP20Data->ReserveNow[gun_index].guid, gun_index);
 			sendReserveNowConfirmation((char *)ShmOCPP20Data->ReserveNow[gun_index].guid, gun_index);
+		}
 
 
+		//==========================================
+		// csu trigger ReserveNowConf
+		//==========================================
+		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq == ON))
+		{
+			sendReservationStatusUpdateRequest(gun_index);
 		}
 		}
 
 
 		//==========================================
 		//==========================================
@@ -6016,6 +6098,23 @@ void CheckSystemValue(void)
 		{
 		{
 			sendLogStatusNotificationRequest((char *)ShmOCPP20Data->LogStatusNotification.status);
 			sendLogStatusNotificationRequest((char *)ShmOCPP20Data->LogStatusNotification.status);
 		}
 		}
+
+		//==========================================
+		// csu trigger SignCertificateReq
+		//==========================================
+		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->SpMsg.bits.SignCertificateReq == ON))
+		{
+			if((access("/Storage/OCPP/certCP.csr",F_OK) != -1) &&
+			   (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) == 0) )
+			{
+				sendSignCertificateRequest(CertificateSignedStatusEnumType_ChargingStationCertificate);
+			}
+			else if((access("/Storage/OCPP/certV2G.csr",F_OK) != -1) &&
+				  (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[CertificateSignedStatusEnumType_V2GCertificate]) == 0))
+			{
+				sendSignCertificateRequest(CertificateSignedStatusEnumType_V2GCertificate);
+			}
+		}
 	}
 	}
 }
 }
 
 
@@ -7904,6 +8003,8 @@ int sendReservationStatusUpdateRequest(int gun_index)
 	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
 	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
 	{
 	{
 		result = PASS;
 		result = PASS;
+
+		ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = OFF;
 	}
 	}
 	return result;
 	return result;
 }
 }
@@ -7935,7 +8036,7 @@ int sendSecurityEventNotificationRequest()
 	return result;
 	return result;
 }
 }
 
 
-int sendSignCertificateRequest()
+int sendSignCertificateRequest(CertificateSigningUseEnumType certType)
 {
 {
 	mtrace();
 	mtrace();
 	int result = FAIL;
 	int result = FAIL;
@@ -7945,7 +8046,23 @@ int sendSignCertificateRequest()
 	json_object *SignCertificate = json_object_new_object();
 	json_object *SignCertificate = json_object_new_object();
 	DEBUG_INFO("sendSignCertificateRequest...\n");
 	DEBUG_INFO("sendSignCertificateRequest...\n");
 
 
+	// Read csr file content
+	memset(ShmOCPP20Data->SignCertificate.csr, 0x00, ARRAY_SIZE(ShmOCPP20Data->SignCertificate.csr));
+	FILE *fp=fopen(((certType == CertificateSignedStatusEnumType_V2GCertificate)?"/Storage/OCPP/certV2G.csr":"/Storage/OCPP/certCP.csr"),"r");
+	char *line = NULL;
+	size_t len = 0;
+	while(getline(&line, &len, fp) != -1)
+	{
+		if((strstr(line, "BEGIN CERTIFICATE REQUEST") == NULL) && (strstr(line, "END CERTIFICATE REQUEST") == NULL))
+		{
+			memcpy(&ShmOCPP20Data->SignCertificate.csr[strlen((char*)ShmOCPP20Data->SignCertificate.csr)], line, (strlen(line)-1));
+		}
+	}
+	fclose(fp);
+
 	json_object_object_add(SignCertificate, "csr", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.csr));
 	json_object_object_add(SignCertificate, "csr", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.csr));
+
+	sprintf((char*)ShmOCPP20Data->SignCertificate.certificateType, CertificateSigningUseEnumTypeStr[certType]);
 	json_object_object_add(SignCertificate, "certificateType", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.certificateType));
 	json_object_object_add(SignCertificate, "certificateType", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.certificateType));
 
 
 	random_uuid(guid);
 	random_uuid(guid);
@@ -9096,11 +9213,21 @@ int sendCertificateSignedConfirmation(char *uuid)
 	int result = FAIL;
 	int result = FAIL;
 	char message[4096]={0};
 	char message[4096]={0};
 	json_object *CertificateSigned = json_object_new_object();
 	json_object *CertificateSigned = json_object_new_object();
+	json_object *statusInfo = json_object_new_object();
 
 
 	DEBUG_INFO("sendCertificateSignedConfirmation...\n");
 	DEBUG_INFO("sendCertificateSignedConfirmation...\n");
 
 
 	json_object_object_add(CertificateSigned, "status", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_status));
 	json_object_object_add(CertificateSigned, "status", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_status));
 
 
+	if(strlen((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.reasonCode) > 0)
+	{
+		json_object_object_add(statusInfo, "reasonCode", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.reasonCode));
+
+		if(strlen((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.additionalInfo) > 0)
+			json_object_object_add(statusInfo, "statadditionalInfous", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.additionalInfo));
+	}
+	json_object_object_add(CertificateSigned, "statusInfo", statusInfo);
+
 	sprintf(message,"[%d,\"%s\",%s]"
 	sprintf(message,"[%d,\"%s\",%s]"
 								,MESSAGE_TYPE_CALLRESULT
 								,MESSAGE_TYPE_CALLRESULT
 								,uuid
 								,uuid
@@ -9850,7 +9977,7 @@ int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index)
 	return result;
 	return result;
 }
 }
 
 
-int sendSetDisplayMessageConfirmation(char *uuid)
+int sendSetDisplayMessagesConfirmation(char *uuid)
 {
 {
 	mtrace();
 	mtrace();
 	int result = FAIL;
 	int result = FAIL;
@@ -10293,18 +10420,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 		memset(&ShmOCPP20Data->CertificateSigned, 0, sizeof(struct CertificateSigned_20));
 		memset(&ShmOCPP20Data->CertificateSigned, 0, sizeof(struct CertificateSigned_20));
 		memcpy(&ShmOCPP20Data->CertificateSigned.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.guid));
 		memcpy(&ShmOCPP20Data->CertificateSigned.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.guid));
 		// Required data
 		// Required data
-		if(json_object_array_length(json_object_object_get(CertificateSigned, "certificate")) <= ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.certificate))
-		{
-			for(int idx=0;idx<json_object_array_length(json_object_object_get(CertificateSigned, "certificate"));idx++)
-			{
-				sprintf((char*)ShmOCPP20Data->CertificateSigned.certificate[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(CertificateSigned, "certificateType"), idx)));
-
-				/*
-				 * TODO:
-				 * 	1. Certificate install response
-				 */
-			}
-		}
+		sprintf((char*)ShmOCPP20Data->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_object_get(CertificateSigned, "certificateChain")));
 
 
 		// Optional data
 		// Optional data
 		if(json_object_object_get(CertificateSigned, "certificateType") != NULL)
 		if(json_object_object_get(CertificateSigned, "certificateType") != NULL)
@@ -10313,17 +10429,28 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 
 
 			if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_ChargingStationCertificate]) == 0)
 			if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_ChargingStationCertificate]) == 0)
 			{
 			{
-
+				FILE *fp = fopen("/Storage/OCPP/certCP.crt", "w");
+				fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
+				fclose(fp);
 			}
 			}
 			else if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_V2GCertificate]) == 0)
 			else if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_V2GCertificate]) == 0)
 			{
 			{
-
+				FILE *fp = fopen("/Storage/OCPP/certV2G.crt", "w");
+				fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
+				fclose(fp);
 			}
 			}
-			else
-			{
+		}
+		else
+		{
+			FILE *fp = fopen("/Storage/OCPP/certCP.crt", "w");
+			fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
+			fclose(fp);
 
 
-			}
+			fp = fopen("/Storage/OCPP/certV2G.crt", "w");
+			fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
+			fclose(fp);
 		}
 		}
+		system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
 
 
 		strcpy((char*)ShmOCPP20Data->CertificateSigned.Response_status, CertificateSignedStatusEnumTypeStr[CertificateSignedStatusEnumType_Accepted]);
 		strcpy((char*)ShmOCPP20Data->CertificateSigned.Response_status, CertificateSignedStatusEnumTypeStr[CertificateSignedStatusEnumType_Accepted]);
 	}
 	}
@@ -12089,10 +12216,11 @@ int handleGetDisplayMessagesRequest(char *uuid, char *payload)
 			{
 			{
 				ShmOCPP20Data->GetDisplayMessages.id[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(GetDisplayMessages, "id"), idx));
 				ShmOCPP20Data->GetDisplayMessages.id[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(GetDisplayMessages, "id"), idx));
 			}
 			}
-			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
+			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
+			ShmOCPP20Data->MsMsg.bits.GetDisplayMessagesReq = ON;
 		}
 		}
 		else
 		else
-			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Unknown]);
+			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Unknown]);
 	}
 	}
 	json_object_put(GetDisplayMessages);
 	json_object_put(GetDisplayMessages);
 
 
@@ -14406,7 +14534,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	return result;
 	return result;
 }
 }
 
 
-int handleSetDisplayMessageRequest(char *uuid, char *payload)
+int handleSetDisplayMessagesRequest(char *uuid, char *payload)
 {
 {
 	mtrace();
 	mtrace();
 	int result = FAIL;
 	int result = FAIL;
@@ -14473,9 +14601,9 @@ int handleSetDisplayMessageRequest(char *uuid, char *payload)
 	json_object_put(SetDisplayMessage);
 	json_object_put(SetDisplayMessage);
 
 
 	strcpy((char*)ShmOCPP20Data->SetDisplayMessage.Response_status, DisplayMessageStatusEnumTypeStr[DisplayMessageStatusEnumType_Accepted]);
 	strcpy((char*)ShmOCPP20Data->SetDisplayMessage.Response_status, DisplayMessageStatusEnumTypeStr[DisplayMessageStatusEnumType_Accepted]);
-	sendSetMonitoringBaseConfirmation(uuid);
+	sendSetDisplayMessagesConfirmation(uuid);
 
 
-	// Anouce CSU there is display request come from server
+	// Announce CSU there is display request come from server
 	ShmOCPP20Data->MsMsg.bits.SetDisplayMessageReq = ON;
 	ShmOCPP20Data->MsMsg.bits.SetDisplayMessageReq = ON;
 
 
 	return result;
 	return result;
@@ -14768,6 +14896,7 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 	mtrace();
 	mtrace();
 	int result = FAIL;
 	int result = FAIL;
 	json_object *SetVariableMonitoring;
 	json_object *SetVariableMonitoring;
+	uint8_t variableQuantity = 0;
 
 
 	DEBUG_INFO("handleSetVariableMonitoringRequest...\n");
 	DEBUG_INFO("handleSetVariableMonitoringRequest...\n");
 	SetVariableMonitoring = json_tokener_parse(payload);
 	SetVariableMonitoring = json_tokener_parse(payload);
@@ -14778,6 +14907,7 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 		// Required data
 		// Required data
 		for(int idx=0;idx<json_object_array_length(json_object_object_get(SetVariableMonitoring, "setMonitoringData"));idx++)
 		for(int idx=0;idx<json_object_array_length(json_object_object_get(SetVariableMonitoring, "setMonitoringData"));idx++)
 		{
 		{
+			variableQuantity++;
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id") != NULL)
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id") != NULL)
 			{
 			{
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].id = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id"));
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].id = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id"));
@@ -14787,11 +14917,6 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value") != NULL)
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value") != NULL)
 			{
 			{
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].value = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value"));
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].value = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value"));
-				/*
-				 * TODO:
-				 * 	1. Check monitor value status
-				 */
-				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, MonitorEnumTypeStr[MonitorEnumType_Delta]);
 			}
 			}
 
 
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "type") != NULL)
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "type") != NULL)
@@ -14853,10 +14978,15 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 
 
 				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable , &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable, sizeof(struct VariableType));
 				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable , &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable, sizeof(struct VariableType));
 			}
 			}
+
+			strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, SetMonitoringStatusEnumTypeStr[SetMonitoringStatusEnumType_Accepted]);
 		}
 		}
 	}
 	}
 	json_object_put(SetVariableMonitoring);
 	json_object_put(SetVariableMonitoring);
 
 
+
+	sendSetVariableMonitoringConfirmation(uuid, variableQuantity);
+
 	return result;
 	return result;
 }
 }
 
 
@@ -14967,7 +15097,6 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 	int result = FAIL;
 	int result = FAIL;
 	int connectorIdIsNULL = FALSE;
 	int connectorIdIsNULL = FALSE;
 	int connectorIdInt =0;
 	int connectorIdInt =0;
-	char requestedMessagestr[40]={0};
 	json_object *TriggerMessage;
 	json_object *TriggerMessage;
 
 
 	DEBUG_INFO("handleTriggerMessageRequest\n");
 	DEBUG_INFO("handleTriggerMessageRequest\n");
@@ -15002,17 +15131,17 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 
 
 	if((connectorIdIsNULL == TRUE) || ((connectorIdIsNULL == FALSE) && ((connectorIdInt > 0)  && (connectorIdInt <= gunTotalNumber /*(CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)*/ ))) )
 	if((connectorIdIsNULL == TRUE) || ((connectorIdIsNULL == FALSE) && ((connectorIdInt > 0)  && (connectorIdInt <= gunTotalNumber /*(CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)*/ ))) )
 	{
 	{
-		if((strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) != 0) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) != 0) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) != 0) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) != 0) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) != 0 ) &&
-			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_PublishFirmwareStatusNotification]) != 0 ))
+		if((strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) != 0) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) != 0) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) != 0) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) != 0) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) != 0 ) &&
+			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_PublishFirmwareStatusNotification]) != 0 ))
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TriggerMessage.Response_status, "%s",TriggerMessageStatusEnumTypeStr[TriggerMessageStatusEnumType_NotImplemented] );
 			sprintf((char*)ShmOCPP20Data->TriggerMessage.Response_status, "%s",TriggerMessageStatusEnumTypeStr[TriggerMessageStatusEnumType_NotImplemented] );
 			sendTriggerMessageConfirmation(uuid);
 			sendTriggerMessageConfirmation(uuid);
@@ -15034,7 +15163,7 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 	//==========================
 	//==========================
 	// Trigger message
 	// Trigger message
 	//==========================
 	//==========================
-	if( strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) == 0)
+	if( strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) == 0)
 	{
 	{
 		if((strlen((char*)ShmOCPP20Data->FirmwareStatusNotification.status) == 0) ||
 		if((strlen((char*)ShmOCPP20Data->FirmwareStatusNotification.status) == 0) ||
 		   ((FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloading) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloaded) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Idle) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Installing)))
 		   ((FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloading) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloaded) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Idle) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Installing)))
@@ -15044,22 +15173,22 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 
 
 		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 	}
 	}
-	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) == 0 )
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) == 0 )
 	{
 	{
 		if(strlen((char*)ShmOCPP20Data->LogStatusNotification.status) == 0)
 		if(strlen((char*)ShmOCPP20Data->LogStatusNotification.status) == 0)
 			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Idle]);
 			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Idle]);
 		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
 		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
 	}
 	}
-	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) == 0 )
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) == 0 )
 	{
 	{
 		if(DB_updateBootType(BootReasonEnumType_Triggered))
 		if(DB_updateBootType(BootReasonEnumType_Triggered))
 			server_sign = FALSE;
 			server_sign = FALSE;
 	}
 	}
-	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) == 0 )
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) == 0 )
 	{
 	{
 		clientTime.Heartbeat = time((time_t*)NULL) - (ShmOCPP20Data->BootNotification.Response_interval);
 		clientTime.Heartbeat = time((time_t*)NULL) - (ShmOCPP20Data->BootNotification.Response_interval);
 	}
 	}
-	else if (strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
+	else if (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
 	{
 	{
 		if(connectorIdIsNULL == FALSE)
 		if(connectorIdIsNULL == FALSE)
 		{
 		{
@@ -15078,7 +15207,7 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 			}
 			}
 		}
 		}
 	}
 	}
-	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) == 0 )
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) == 0 )
 	{
 	{
 		if(connectorIdIsNULL == FALSE)
 		if(connectorIdIsNULL == FALSE)
 		{
 		{
@@ -15093,6 +15222,57 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 				cpinitateMsg.bits[idx].StatusNotificationReq = ON;
 				cpinitateMsg.bits[idx].StatusNotificationReq = ON;
 		}
 		}
 	}
 	}
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) == 0 )
+	{
+		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;
+
+		if(access("/Storage/OCPP/certCP.csr",F_OK) == -1)
+		{
+			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certCP.csr -nodes -keyout /Storage/OCPP/certCP.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
+		}
+	}
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) == 0 )
+	{
+		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;
+
+		if(access("/Storage/OCPP/certV2G.csr",F_OK) == -1)
+		{
+			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certV2G.csr -nodes -keyout /Storage/OCPP/certV2G.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
+		}
+	}
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) == 0 )
+	{
+		if(connectorIdIsNULL == FALSE)
+		{
+			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
+			{
+				cpinitateMsg.bits[connectorIdInt -1].TransactionEventReq = ON;
+			}
+		}
+		else
+		{
+			for(int idx=0;idx< gunTotalNumber;idx++)
+				cpinitateMsg.bits[idx].TransactionEventReq = ON;
+		}
+	}
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) == 0 )
+	{
+		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;
+
+		if(access("/Storage/OCPP/certCP.csr",F_OK) == -1)
+		{
+			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certCP.csr -nodes -keyout /Storage/OCPP/certCP.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
+		}
+
+		if(access("/Storage/OCPP/certV2G.csr",F_OK) == -1)
+		{
+			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certV2G.csr -nodes -keyout /Storage/OCPP/certV2G.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
+		}
+	}
+	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_PublishFirmwareStatusNotification]) == 0 )
+	{
+		ShmOCPP20Data->MsMsg.bits.PublishFirmwareReq = ON;
+	}
 
 
 	return result;
 	return result;
 }
 }
@@ -15283,9 +15463,9 @@ void *UpdateFirmwareProcess(void *data)
 	int retriesInt =0, retryIntervalInt=0;
 	int retriesInt =0, retryIntervalInt=0;
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	int port=0;
 	int port=0;
-	char locationstr[160]={0}, retrieveDatestr[30]={0};
+	char locationstr[512]={0}, retrieveDatestr[36]={0};
 	int isSuccess = 0;
 	int isSuccess = 0;
-	char ftpbuf[200];
+	char ftpbuf[512];
 	char temp[100];
 	char temp[100];
 	char * pch;
 	char * pch;
 
 
@@ -15315,17 +15495,25 @@ void *UpdateFirmwareProcess(void *data)
 	}
 	}
 	json_object_put(UpdateFirmware);
 	json_object_put(UpdateFirmware);
 
 
-
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	memset(path, 0, ARRAY_SIZE(path));
 	memset(path, 0, ARRAY_SIZE(path));
 
 
+	// Wait retrieveData
+	if(strlen(retrieveDatestr) > 10)
+	{
+		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadScheduled]);
+		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
+		do
+		{
+			sleep(1);
+		}while(!isOvertNow((uint8_t*)retrieveDatestr));
+	}
+
 	system("rm -f /mnt/*");
 	system("rm -f /mnt/*");
 	if(strncmp(locationstr,"http", 4) == 0)
 	if(strncmp(locationstr,"http", 4) == 0)
 	{
 	{
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 
 
-	    //sscanf(locationstr,"%[^:]:%*2[/]%[^:]:%[^@]@%[^/]%199[^\n]",
-		    	    	//	         protocol, user, password, host, path);
 		sprintf(ftppath,"/%s", path);
 		sprintf(ftppath,"/%s", path);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("protocol: %s\n",protocol);
 		DEBUG_INFO("protocol: %s\n",protocol);
@@ -15362,21 +15550,24 @@ void *UpdateFirmwareProcess(void *data)
 			{
 			{
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
-				sleep(retryIntervalInt);
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
+				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 			}
 			}
 			else
 			else
 			{
 			{
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 			}
 			}
-		}while((isSuccess == 0)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((isSuccess == 0)&&(retriesInt >= 0));
 	}
 	}
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
 	{
 	{
     	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
     	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
     	memset(temp, 0, ARRAY_SIZE(temp));
     	memset(temp, 0, ARRAY_SIZE(temp));
-    	//DEBUG_INFO("locationstr=%s\n",locationstr);
-    	strcpy(ftpbuf, locationstr/*"ftp://ipc_ui:pht2016@ftp.phihong.com.tw/DC/log/DemoDC1_2018-07-13_185011_PSULog.zip"*/ );
+
+    	strcpy(ftpbuf, locationstr);
     	int ftppathlen=strlen(ftpbuf);
     	int ftppathlen=strlen(ftpbuf);
     	int i=1;
     	int i=1;
     	char filenametemp[50];
     	char filenametemp[50];
@@ -15414,16 +15605,6 @@ void *UpdateFirmwareProcess(void *data)
     	sscanf(host,"%[^/]%s",host1, path1);
     	sscanf(host,"%[^/]%s",host1, path1);
     	sprintf(ftppath,"%s", path1);
     	sprintf(ftppath,"%s", path1);
 
 
-    	//DEBUG_INFO("protocol =%s\n",protocol);
-    	//DEBUG_INFO("user =%s\n",user);
-    	//DEBUG_INFO("password =%s\n",password);
-    	//DEBUG_INFO("host1 =%s\n",host1);
-    	//DEBUG_INFO("port =%d\n",port);
-    	//DEBUG_INFO("path1 =%s\n",path1);
-    	//DEBUG_INFO("ftppath=%s\n",ftppath);
-
-		//ftpFile(host, user, password, port, ftppath, fname);
-		//download firmware pthred
     	if(port == 0)
     	if(port == 0)
     	{
     	{
     		port = 21;
     		port = 21;
@@ -15442,7 +15623,9 @@ void *UpdateFirmwareProcess(void *data)
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
-				sleep(retryIntervalInt);
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
+				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 			}
 			}
 			else
 			else
 			{
 			{
@@ -15450,15 +15633,19 @@ void *UpdateFirmwareProcess(void *data)
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 
 
 			}
 			}
-		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
 	}
 	}
     else
     else
     {
     {
 		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
+		sleep(1);
+		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
+		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
     }
     }
 
 
-	ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = ON;
+	if(strstr((char*)ShmOCPP20Data->FirmwareStatusNotification.status, FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]) != NULL)ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = ON;
 	pthread_exit(NULL);
 	pthread_exit(NULL);
 
 
 }
 }
@@ -15915,6 +16102,15 @@ void hanldeSignCertificateResponse(char *payload, int gun_index)
 		// Required data
 		// Required data
 		if(json_object_object_get(SignCertificate,"status") != NULL)
 		if(json_object_object_get(SignCertificate,"status") != NULL)
 			sprintf((char*)ShmOCPP20Data->SignCertificate.Response_status, json_object_get_string(json_object_object_get(SignCertificate,"status")));
 			sprintf((char*)ShmOCPP20Data->SignCertificate.Response_status, json_object_get_string(json_object_object_get(SignCertificate,"status")));
+
+		// Optional data
+		if(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "reasonCode") != NULL)
+		{
+			sprintf((char*)ShmOCPP20Data->SignCertificate.Response_statusInfo.reasonCode, json_object_get_string(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "reasonCode")));
+
+			if(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "additionalInfo") != NULL)
+				sprintf((char*)ShmOCPP20Data->SignCertificate.Response_statusInfo.additionalInfo, json_object_get_string(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "additionalInfo")));
+		}
 	}
 	}
 	json_object_put(SignCertificate);
 	json_object_put(SignCertificate);
 
 

+ 3 - 3
EVSE/Modularization/ocpp20/MessageHandler.h

@@ -871,7 +871,7 @@ int sendDeleteCertificateConfirmation(char *uuid);
 int sendGetBaseReportConfirmation(char *uuid);
 int sendGetBaseReportConfirmation(char *uuid);
 int sendGetChargingProfilesConfirmation(char *uuid, unsigned char gun_index);
 int sendGetChargingProfilesConfirmation(char *uuid, unsigned char gun_index);
 int sendGetCompositeScheduleConfirmation(char *uuid,char *payload, int connectorIdInt,int nPeriod);
 int sendGetCompositeScheduleConfirmation(char *uuid,char *payload, int connectorIdInt,int nPeriod);
-int sendGetGetDisplayMessagesConfirmation(char *uuid);
+int sendGetDisplayMessagesConfirmation(char *uuid);
 int sendGetInstalledCertificateIdsConfirmation(char *uuid, unsigned char certQuantity);
 int sendGetInstalledCertificateIdsConfirmation(char *uuid, unsigned char certQuantity);
 int sendGetLocalListVersionConfirmation(char *uuid);
 int sendGetLocalListVersionConfirmation(char *uuid);
 int sendGetLogConfirmation(char *uuid);
 int sendGetLogConfirmation(char *uuid);
@@ -887,7 +887,7 @@ int sendReserveNowConfirmation(char *uuid, unsigned char gun_index);
 int sendResetConfirmation(char *uuid);
 int sendResetConfirmation(char *uuid);
 int sendSendLocalListConfirmation(char *uuid);
 int sendSendLocalListConfirmation(char *uuid);
 int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index);
 int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index);
-int sendSetDisplayMessageConfirmation(char *uuid);
+int sendSetDisplayMessagesConfirmation(char *uuid);
 int sendSetMonitoringBaseConfirmation(char *uuid);
 int sendSetMonitoringBaseConfirmation(char *uuid);
 int sendSetMonitoringLevelConfirmation(char *uuid);
 int sendSetMonitoringLevelConfirmation(char *uuid);
 int sendSetNetworkProfileConfirmation(char *uuid);
 int sendSetNetworkProfileConfirmation(char *uuid);
@@ -937,7 +937,7 @@ int handleReserveNowRequest(char *uuid, char *payload);
 int handleResetRequest(char *uuid, char *payload);
 int handleResetRequest(char *uuid, char *payload);
 int handleSendLocalListRequest(char *uuid, char *payload);
 int handleSendLocalListRequest(char *uuid, char *payload);
 int handleSetChargingProfileRequest(char *uuid, char *payload);
 int handleSetChargingProfileRequest(char *uuid, char *payload);
-int handleSetDisplayMessageRequest(char *uuid, char *payload);
+int handleSetDisplayMessagesRequest(char *uuid, char *payload);
 int handleSetMonitoringBaseRequest(char *uuid, char *payload);
 int handleSetMonitoringBaseRequest(char *uuid, char *payload);
 int handleSetMonitoringLevelRequest(char *uuid, char *payload);
 int handleSetMonitoringLevelRequest(char *uuid, char *payload);
 int handleSetNetworkProfileRequest(char *uuid, char *payload);
 int handleSetNetworkProfileRequest(char *uuid, char *payload);

+ 1 - 0
EVSE/Modularization/ocpp20/Module_OcppBackend20.c

@@ -329,6 +329,7 @@ static int OCPP20Callback(struct lws *wsi, enum lws_callback_reasons reason, voi
 			break;
 			break;
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
+			DEBUG_OCPPMESSAGE_INFO("<==== Get PONG packet.\n");
 			break;
 			break;
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 			DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");
 			DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");

+ 49 - 27
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -84,9 +84,9 @@ static int TempMeterValueInterval 															= 0;
 static struct OCPPAuthLocalElemet
 static struct OCPPAuthLocalElemet
 {
 {
 	int listVersionInt;
 	int listVersionInt;
-	char idTagstr[20];
-	char parentIdTag[20];
-	char expiryDate[30];
+	char idTagstr[21];
+	char parentIdTag[21];
+	char expiryDate[36];
 	char idTagstatus[16];
 	char idTagstatus[16];
 }idTagQuery;
 }idTagQuery;
 
 
@@ -3472,7 +3472,7 @@ void CheckSystemValue(void)
 			ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = 0;
 			ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = 0;
 		}
 		}
 
 
-		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP16Data->SpMsg.bits.SignCertificateReq == 1) && (access("/Storage/OCPP/cert.csr",F_OK) != -1))
+		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP16Data->SpMsg.bits.SignCertificateReq == 1) && (access("/Storage/OCPP/certCP.csr",F_OK) != -1))
 		{
 		{
 			sendSignCertificateRequest();
 			sendSignCertificateRequest();
 		}
 		}
@@ -3534,8 +3534,8 @@ int sendAuthorizeRequest(int gun_index)
 			}
 			}
 
 
 			DEBUG_INFO("off-line Local Authorization Fail !!!!\n");
 			DEBUG_INFO("off-line Local Authorization Fail !!!!\n");
-			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ExpiryDate, "");
-			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (const char *)ShmSysConfigAndInfo->SysConfig.UserId);
+			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ExpiryDate, idTagQuery.expiryDate);
+			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, idTagQuery.parentIdTag);
 			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Invalid");
 			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Invalid");
 			DEBUG_INFO("ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status);
 			DEBUG_INFO("ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status);
 			ShmOCPP16Data->SpMsg.bits.AuthorizeReq = 0;
 			ShmOCPP16Data->SpMsg.bits.AuthorizeReq = 0;
@@ -3547,7 +3547,7 @@ int sendAuthorizeRequest(int gun_index)
 		{
 		{
 			DEBUG_INFO("off-line Local Authorization get result !!!!\n");
 			DEBUG_INFO("off-line Local Authorization get result !!!!\n");
 			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ExpiryDate, idTagQuery.expiryDate);
 			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ExpiryDate, idTagQuery.expiryDate);
-			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (const char *)ShmSysConfigAndInfo->SysConfig.UserId);
+			strcpy((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, idTagQuery.parentIdTag);
 
 
 			if(isOvertNow((uint8_t*)&idTagQuery.expiryDate[0]))
 			if(isOvertNow((uint8_t*)&idTagQuery.expiryDate[0]))
 				sprintf((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Expired");
 				sprintf((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Expired");
@@ -4333,10 +4333,12 @@ S_FAULT                 =12
 	}
 	}
 
 
 	//it's option
 	//it's option
-	if(strstr((char *)ShmOCPP16Data->StatusNotification[gun_index].Status, ChargePointStatusStr[currentStatus]) != NULL)
+	if((strstr((char *)ShmOCPP16Data->StatusNotification[gun_index].Status, ChargePointStatusStr[currentStatus]) != NULL) &&
+		!ShmOCPP16Data->CsMsg.bits[gun_index].TriggerMessageReq)
 	{
 	{
 		isStateChanged = FALSE;
 		isStateChanged = FALSE;
 	}
 	}
+	ShmOCPP16Data->CsMsg.bits[gun_index].TriggerMessageReq = 0;
 
 
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].Timestamp, buf);
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].Timestamp, buf);
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].VendorId, (char*)ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].VendorId, (char*)ShmSysConfigAndInfo->SysConfig.chargePointVendor);
@@ -6311,7 +6313,7 @@ int sendSignCertificateRequest()
 
 
 	// Read csr file content
 	// Read csr file content
 	memset(ShmOCPP16Data->SignCertificate.csr, 0x00, ARRAY_SIZE(ShmOCPP16Data->SignCertificate.csr));
 	memset(ShmOCPP16Data->SignCertificate.csr, 0x00, ARRAY_SIZE(ShmOCPP16Data->SignCertificate.csr));
-	FILE *fp=fopen("/Storage/OCPP/cert.csr","r");
+	FILE *fp=fopen("/Storage/OCPP/certCP.csr","r");
 	char *line = NULL;
 	char *line = NULL;
 	size_t len = 0;
 	size_t len = 0;
 	while(getline(&line, &len, fp) != -1)
 	while(getline(&line, &len, fp) != -1)
@@ -9061,8 +9063,10 @@ void* GetDiagnosticsProcess(void* data)
 	}
 	}
 
 
 end:
 end:
-	DiagnosticsStatusNotificationStatus = DIAGNOSTIC_STATUS_IDLE;
 	system("rm -f /mnt/*");
 	system("rm -f /mnt/*");
+	sleep(5);
+	sprintf((char*)ShmOCPP16Data->DiagnosticsStatusNotification.Status, "%s", DiagnosticsStatusStr[DiagnosticsStatus_Idle]);
+	ShmOCPP16Data->SpMsg.bits.DiagnosticsStatusNotificationReq = 1;
 	pthread_exit(NULL);
 	pthread_exit(NULL);
 }
 }
 
 
@@ -11555,13 +11559,17 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 		{
 		{
 			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
 			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
 			{
 			{
+				ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].TriggerMessageReq = 1;
 				cpinitateMsg.bits[connectorIdInt -1].StatusNotificationReq = 1;
 				cpinitateMsg.bits[connectorIdInt -1].StatusNotificationReq = 1;
 			}
 			}
 		}
 		}
 		else
 		else
 		{
 		{
 			for(int idx=0;idx< gunTotalNumber;idx++)
 			for(int idx=0;idx< gunTotalNumber;idx++)
+			{
+				ShmOCPP16Data->CsMsg.bits[idx].TriggerMessageReq = 1;
 				cpinitateMsg.bits[idx].StatusNotificationReq = 1;
 				cpinitateMsg.bits[idx].StatusNotificationReq = 1;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -11742,13 +11750,12 @@ void *UpdateFirmwareProcess(void *data)
 	int retriesInt =0, retryIntervalInt=0;
 	int retriesInt =0, retryIntervalInt=0;
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	int port=0;
 	int port=0;
-	char locationstr[160]={0}, retrieveDatestr[30]={0};
+	char locationstr[512]={0}, retrieveDatestr[36]={0};
 	int isSuccess = 0;
 	int isSuccess = 0;
-	char ftpbuf[200];
+	char ftpbuf[512];
 	char temp[100];
 	char temp[100];
 	char * pch;
 	char * pch;
 
 
-
 	DEBUG_INFO("handleUpdateFirmwareRequest ...\n");
 	DEBUG_INFO("handleUpdateFirmwareRequest ...\n");
 	json_object *UpdateFirmware;
 	json_object *UpdateFirmware;
 	UpdateFirmware = json_tokener_parse(UpdateFirmwarepayloadData);
 	UpdateFirmware = json_tokener_parse(UpdateFirmwarepayloadData);
@@ -11774,17 +11781,24 @@ void *UpdateFirmwareProcess(void *data)
 	}
 	}
 	json_object_put(UpdateFirmware);
 	json_object_put(UpdateFirmware);
 
 
-
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	memset(path, 0, ARRAY_SIZE(path));
 	memset(path, 0, ARRAY_SIZE(path));
 
 
+	// Wait retrieveData
+	if(strlen(retrieveDatestr) > 10)
+	{
+		do
+		{
+			sleep(1);
+		}while(!isOvertNow((uint8_t*)retrieveDatestr));
+	}
+
+	// Ready to download
 	system("rm -f /mnt/*");
 	system("rm -f /mnt/*");
 	if(strncmp(locationstr,"http", 4) == 0)
 	if(strncmp(locationstr,"http", 4) == 0)
 	{
 	{
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 
 
-	    //sscanf(locationstr,"%[^:]:%*2[/]%[^:]:%[^@]@%[^/]%199[^\n]",
-		    	    	//	         protocol, user, password, host, path);
 		sprintf(ftppath,"/%s", path);
 		sprintf(ftppath,"/%s", path);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("protocol: %s\n",protocol);
 		DEBUG_INFO("protocol: %s\n",protocol);
@@ -11814,21 +11828,24 @@ void *UpdateFirmwareProcess(void *data)
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-			sleep(3);
+			sleep(1);
 
 
 			isSuccess = httpDownLoadFile(host, ftppath, filenametemp, locationstr);
 			isSuccess = httpDownLoadFile(host, ftppath, filenametemp, locationstr);
 			if(!isSuccess)
 			if(!isSuccess)
 			{
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-				sleep(retryIntervalInt);
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Idle]);
+				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			}
 			}
 			else
 			else
 			{
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			}
 			}
-		}while((isSuccess == 0)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((isSuccess == 0)&&(retriesInt >= 0));
 	}
 	}
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
 	{
 	{
@@ -11892,7 +11909,7 @@ void *UpdateFirmwareProcess(void *data)
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-			sleep(3);
+			sleep(1);
 
 
 			isSuccess = ftpDownLoadFile(host1, user, password, port, ftppath, filenametemp, locationstr);
 			isSuccess = ftpDownLoadFile(host1, user, password, port, ftppath, filenametemp, locationstr);
 			if(!isSuccess)
 			if(!isSuccess)
@@ -11901,24 +11918,29 @@ void *UpdateFirmwareProcess(void *data)
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-				sleep(retryIntervalInt);
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Idle]);
+				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			}
 			}
 			else
 			else
 			{
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			}
 			}
-		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
 	}
 	}
     else
     else
     {
     {
 		sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 		sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 		ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 		ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+		sleep(1);
+		sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Idle]);
+		ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
     }
     }
 
 
-	ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = 1;
+	if(strstr((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, FirmwareStatusStr[FirmwareStatus_Downloaded]) != NULL)ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = 1;
 	pthread_exit(NULL);
 	pthread_exit(NULL);
-
 }
 }
 
 
 int handleCertificateSignedRequest(char *uuid, char *payload)
 int handleCertificateSignedRequest(char *uuid, char *payload)
@@ -11935,7 +11957,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 	}
 	}
 	json_object_put(CertificateSigned);
 	json_object_put(CertificateSigned);
 
 
-	FILE *fp = fopen("/Storage/OCPP/cert.crt", "w");
+	FILE *fp = fopen("/Storage/OCPP/certCP.crt", "w");
 	fprintf(fp, "%s", ShmOCPP16Data->CertificateSigned.certificateChain);
 	fprintf(fp, "%s", ShmOCPP16Data->CertificateSigned.certificateChain);
 	fclose(fp);
 	fclose(fp);
 	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
 	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
@@ -12077,9 +12099,9 @@ int handleExtendedTriggerMessageRequest(char *uuid, char *payload)
 	{
 	{
 		ShmOCPP16Data->SpMsg.bits.SignCertificateReq = 1;
 		ShmOCPP16Data->SpMsg.bits.SignCertificateReq = 1;
 
 
-		if(access("/Storage/OCPP/cert.csr",F_OK) == -1)
+		if(access("/Storage/OCPP/certCP.csr",F_OK) == -1)
 		{
 		{
-			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/cert.csr -nodes -keyout /Storage/OCPP/cert.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
+			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certCP.csr -nodes -keyout /Storage/OCPP/certCP.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
 		}
 		}
 	}
 	}
 	else if(strcmp((char*)ShmOCPP16Data->ExtendedTriggerMessage.requestedMessage, MessageTriggerStr[StatusNotification]) == 0 )
 	else if(strcmp((char*)ShmOCPP16Data->ExtendedTriggerMessage.requestedMessage, MessageTriggerStr[StatusNotification]) == 0 )

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

@@ -374,6 +374,7 @@ static int OCPP16Callback(struct lws *wsi, enum lws_callback_reasons reason, voi
 			break;
 			break;
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
+			DEBUG_OCPPMESSAGE_INFO("<===== Get PONG packet.\n");
 			break;
 			break;
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 			DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");
 			DEBUG_INFO("LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION\n");

文件差异内容过多而无法显示
+ 189 - 215
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c


+ 2 - 2
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h

@@ -141,9 +141,9 @@
 #define BATTERY_SOC_80						0x05
 #define BATTERY_SOC_80						0x05
 #define BATTERY_SOC_100						0x06
 #define BATTERY_SOC_100						0x06
 #define CONNECTION_COMPLETE_MARK			0x01
 #define CONNECTION_COMPLETE_MARK			0x01
-#define QRCODE_DISABLE						0x01
+#define QRCODE_BANDED						0x01
 #define QRCODE_ENABLE 						0x02
 #define QRCODE_ENABLE 						0x02
-#define QRCODE_BANDED						0x03
+#define QRCODE_DISABLE						0x03
 
 
 //=======================================
 //=======================================
 // Icon variable address start from 1000
 // Icon variable address start from 1000

+ 5 - 0
EVSE/Projects/AW-CCS/Apps/Module_AlarmDetect.c

@@ -1105,6 +1105,11 @@ int main(void)
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayDriveFault");
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayDriveFault");
 			}
 			}
+			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)
+			{
+				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "MeterCommTimeout");
+			}
 			else
 			else
 			{
 			{
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError");
 				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError");

+ 39 - 2
EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c

@@ -2147,7 +2147,12 @@ int main(void)
 					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3 == 0x01)
 					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3 == 0x01)
 						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<27;
 						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<27;
 					else
 					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<27);							
+						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<27);
+
+					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_comm_timeout == 0x01)
+						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<28;
+					else
+						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<28);
 
 
 					failCount[gun_index] = 0;
 					failCount[gun_index] = 0;
 					
 					
@@ -2265,7 +2270,23 @@ int main(void)
 					else
 					else
 						failCount[gun_index] = FAIL_SPEC_COMM;
 						failCount[gun_index] = FAIL_SPEC_COMM;
 				}
 				}
-
+				
+				//===============================
+				// Case 10 : Query primary MCU power consumption
+				//===============================
+				if(Query_Power_Consumption(Uart1Fd, (gun_index>0?ADDR_AC_PRIMARY_2:ADDR_AC_PRIMARY_1), &ShmCharger->gun_info[gun_index].powerConsumptionTotal, &ShmCharger->gun_info[gun_index].powerConsumption[0], &ShmCharger->gun_info[gun_index].powerConsumption[1], &ShmCharger->gun_info[gun_index].powerConsumption[2]))
+				{
+					failCount[gun_index] = 0;
+				}
+				else
+				{
+					DEBUG_WARN("MCU-%d get power consumption fail...%d\n", gun_index, failCount[gun_index]);
+					if(failCount[gun_index]<USHRT_MAX)
+						failCount[gun_index]++;
+					else
+						failCount[gun_index] = FAIL_SPEC_COMM;
+				}
+				
 				//==========================================================
 				//==========================================================
 				// High priority polling log print out
 				// High priority polling log print out
 				//==========================================================
 				//==========================================================
@@ -2354,6 +2375,7 @@ int main(void)
 							DEBUG_INFO("MCU-%d get short_circuit_L3 : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3);
 							DEBUG_INFO("MCU-%d get short_circuit_L3 : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3);
 						}
 						}
 						DEBUG_INFO("MCU-%d get relay_drive_fault : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_drive_fault);
 						DEBUG_INFO("MCU-%d get relay_drive_fault : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_drive_fault);
+						DEBUG_INFO("MCU-%d get meter_comm_timeout : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_comm_timeout);
 						DEBUG_INFO("MCU-%d get InputAlarmCode : %x\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode);
 						DEBUG_INFO("MCU-%d get InputAlarmCode : %x\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode);
 					}
 					}
 
 
@@ -2380,6 +2402,17 @@ int main(void)
 						DEBUG_INFO("*******************************************\n");
 						DEBUG_INFO("*******************************************\n");
 						DEBUG_INFO("MCU-%d get ble central id : %s\n", gun_index, ShmCharger->gun_info[gun_index].bleLoginCentralId.id);
 						DEBUG_INFO("MCU-%d get ble central id : %s\n", gun_index, ShmCharger->gun_info[gun_index].bleLoginCentralId.id);
 					}
 					}
+					
+					DEBUG_INFO("===========================================\n");
+					DEBUG_INFO("==== High priority polling : Case 10 ====\n");
+					DEBUG_INFO("===========================================\n");
+					DEBUG_INFO("MCU-%d get total power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100));
+					DEBUG_INFO("MCU-%d get L1N_L12 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/100));
+					if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3)
+					{
+						DEBUG_INFO("MCU-%d get L2N_L23 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/100));
+						DEBUG_INFO("MCU-%d get L3N_L31 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/100));
+					}
 				}
 				}
 			}
 			}
 			else
 			else
@@ -2554,6 +2587,7 @@ int main(void)
 						//===============================
 						//===============================
 						// Query primary MCU power consumption
 						// Query primary MCU power consumption
 						//===============================
 						//===============================
+						/*
 						if(Query_Power_Consumption(Uart1Fd, (gun_index>0?ADDR_AC_PRIMARY_2:ADDR_AC_PRIMARY_1), &ShmCharger->gun_info[gun_index].powerConsumptionTotal, &ShmCharger->gun_info[gun_index].powerConsumption[0], &ShmCharger->gun_info[gun_index].powerConsumption[1], &ShmCharger->gun_info[gun_index].powerConsumption[2]))
 						if(Query_Power_Consumption(Uart1Fd, (gun_index>0?ADDR_AC_PRIMARY_2:ADDR_AC_PRIMARY_1), &ShmCharger->gun_info[gun_index].powerConsumptionTotal, &ShmCharger->gun_info[gun_index].powerConsumption[0], &ShmCharger->gun_info[gun_index].powerConsumption[1], &ShmCharger->gun_info[gun_index].powerConsumption[2]))
 						{
 						{
 							failCount[gun_index] = 0;
 							failCount[gun_index] = 0;
@@ -2566,6 +2600,7 @@ int main(void)
 							else
 							else
 								failCount[gun_index] = FAIL_SPEC_COMM;
 								failCount[gun_index] = FAIL_SPEC_COMM;
 						}
 						}
+						*/
 						break;
 						break;
 					case 13:
 					case 13:
 						//===============================
 						//===============================
@@ -2810,6 +2845,7 @@ int main(void)
 							}
 							}
 							break;
 							break;
 						case 6:
 						case 6:
+							/*
 							DEBUG_INFO("===========================================\n");
 							DEBUG_INFO("===========================================\n");
 							DEBUG_INFO("==== Normal priority polling : Case 13 ====\n");
 							DEBUG_INFO("==== Normal priority polling : Case 13 ====\n");
 							DEBUG_INFO("===========================================\n");
 							DEBUG_INFO("===========================================\n");
@@ -2820,6 +2856,7 @@ int main(void)
 								DEBUG_INFO("MCU-%d get L2N_L23 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/100));
 								DEBUG_INFO("MCU-%d get L2N_L23 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/100));
 								DEBUG_INFO("MCU-%d get L3N_L31 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/100));
 								DEBUG_INFO("MCU-%d get L3N_L31 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/100));
 							}
 							}
+							*/
 							break;
 							break;
 						case 7:
 						case 7:
 							if(ShmCharger->gun_info[gun_index].isSetBreatheLedTiming == ON)
 							if(ShmCharger->gun_info[gun_index].isSetBreatheLedTiming == ON)

+ 122 - 38
EVSE/Projects/AW-CCS/Apps/main.c

@@ -1,6 +1,7 @@
 #include	"define.h"
 #include	"define.h"
 #include 	"main.h"
 #include 	"main.h"
 
 
+
 //==========================
 //==========================
 // System basic sample constant
 // System basic sample constant
 //==========================
 //==========================
@@ -567,21 +568,59 @@ uint8_t ocpp_get_auth_conf()
 	return result;
 	return result;
 }
 }
 
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 {
 	uint8_t result = OFF;
 	uint8_t result = OFF;
 
 
-	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+	switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)
 	{
 	{
-		if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
-			result = PASS;
-	}
-	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
-	{
-		if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
-			result = PASS;
+		case SYS_MODE_AUTHORIZING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
+					result = PASS;
+			}
+
+			break;
+		case SYS_MODE_CHARGING:
+		case SYS_MODE_TERMINATING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 1.6 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.ResponseIdTagInfo.ParentIdTag : %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag);
+				DEBUG_INFO("StartTransaction[%d].ResponseIdTagInfo.ParentIdTag : %s \n", gun_index ,ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag);
+
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 2.0 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.Response_idTokenInfo.groupIdToken.idToken : %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken);
+				DEBUG_INFO("TransactionEvent[%d].Response_idTokenInfo.groupIdToken.idToken : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken);
+
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken)==0))
+					result = PASS;
+			}
+
+			break;
+		default:
+			break;
 	}
 	}
 
 
+	DEBUG_INFO("Authorize result : %s \n", ((result == PASS)?"Pass":"Fail"));
+
 	return result;
 	return result;
 }
 }
 
 
@@ -2220,7 +2259,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 
 	// Get CSU root file system version
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.49.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.50.00.0000.00");
 
 
 	// Get AC connector type from model name
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
 	for(uint8_t idx=0;idx<3;idx++)
@@ -3451,6 +3490,7 @@ void checkStopReason(uint8_t gun_index)
 {
 {
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
@@ -3473,6 +3513,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
+			
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+
+			DEBUG_INFO("Gun-%d [ IdTag ] : %s \n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag);
 		}
 		}
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		{
 		{
@@ -3488,12 +3539,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
 
-		memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 	{
+		memset(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
@@ -3520,6 +3571,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
+			
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
+			}
+
+			DEBUG_INFO("Gun-%d [ idToken ] : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken);
 		}
 		}
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) ||
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) ||
 				(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) ||
 				(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) ||
@@ -3541,7 +3603,6 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 
 
-		memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
 	}
@@ -3782,7 +3843,7 @@ int main(void)
 				if(ShmCharger->isLcdOn == ON)
 				if(ShmCharger->isLcdOn == ON)
 				{
 				{
 					//if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]) < (TIMEOUT_SPEC_POWERSAVING_LCD+600))
 					//if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]) < (TIMEOUT_SPEC_POWERSAVING_LCD+600))
-						DEBUG_INFO("LCD into power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]));
+					DEBUG_INFO("LCD into power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]));
 					ShmCharger->isLcdOn = OFF;
 					ShmCharger->isLcdOn = OFF;
 				}
 				}
 			}
 			}
@@ -3791,7 +3852,7 @@ int main(void)
 				if(ShmCharger->isLcdOn == OFF)
 				if(ShmCharger->isLcdOn == OFF)
 				{
 				{
 					//if((0 < DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD])) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]) < 600))
 					//if((0 < DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD])) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]) < 600))
-						DEBUG_INFO("LCD exit power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]));
+					DEBUG_INFO("LCD exit power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]));
 					ShmCharger->isLcdOn = ON;
 					ShmCharger->isLcdOn = ON;
 				}
 				}
 			}
 			}
@@ -3843,10 +3904,26 @@ int main(void)
 			//==========================================
 			//==========================================
 			// Synchronize present charging power
 			// Synchronize present charging power
 			//==========================================
 			//==========================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)
-				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (ShmSysConfigAndInfo->SysInfo.InputVoltageR* ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000;
+			if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1)
+			{
+				if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltage*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000;
+				else
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0;
+			}
 			else
 			else
-				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0;
+			{
+				if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)
+				{
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltage*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000) +
+																								   ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL2*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL2)/1000) +
+																								   ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL3*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL3)/1000));
+				}
+				else
+				{
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0;
+				}
+			}
 
 
 			//==========================================
 			//==========================================
 			// Check initialization "PASS" or "FAIL"
 			// Check initialization "PASS" or "FAIL"
@@ -4184,7 +4261,7 @@ int main(void)
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0))
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0))
 								  )
 								  )
 								{
 								{
-									if(ocpp_get_auth_result() ||
+									if(ocpp_get_auth_result(gun_index) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									{
 									{
@@ -4200,7 +4277,6 @@ int main(void)
 									else
 									else
 									{
 									{
 										ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
 										ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
-																				 
 										DEBUG_INFO("Authorize fail.\n");
 										DEBUG_INFO("Authorize fail.\n");
 										setSpeaker(ON,SPEAKER_INTERVAL_3COUNT);
 										setSpeaker(ON,SPEAKER_INTERVAL_3COUNT);
 										setLedMotion(gun_index,LED_ACTION_RFID_FAIL);
 										setLedMotion(gun_index,LED_ACTION_RFID_FAIL);
@@ -4376,6 +4452,7 @@ int main(void)
 									memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId));
 									memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId));
 									ocpp_copy_userid_to_starttransaction(gun_index);
 									ocpp_copy_userid_to_starttransaction(gun_index);
 									ocpp_set_starttransaction_req(gun_index, ON);
 									ocpp_set_starttransaction_req(gun_index, ON);
+									ftime(&startChargingTime[gun_index]);
 
 
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
 								}
 								}
@@ -4478,6 +4555,7 @@ int main(void)
 									ocpp_set_starttransaction_req(gun_index, ON);
 									ocpp_set_starttransaction_req(gun_index, ON);
 									ShmCharger->gun_info[gun_index].isCCSStartTransation = OFF;
 									ShmCharger->gun_info[gun_index].isCCSStartTransation = OFF;
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
+									ftime(&startChargingTime[gun_index]);
 									ftime(&startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]);
 									ftime(&startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]);
 								}
 								}
 
 
@@ -4518,7 +4596,7 @@ int main(void)
 							setRelay(gun_index,ON);
 							setRelay(gun_index,ON);
 						ocpp_copy_userid_to_starttransaction(gun_index);
 						ocpp_copy_userid_to_starttransaction(gun_index);
 						ocpp_set_starttransaction_req(gun_index, ON);
 						ocpp_set_starttransaction_req(gun_index, ON);
-
+						ftime(&startChargingTime[gun_index]);
 						setChargerMode(gun_index, SYS_MODE_CHARGING);
 						setChargerMode(gun_index, SYS_MODE_CHARGING);
 					}
 					}
 
 
@@ -4580,7 +4658,7 @@ int main(void)
 					if(isModeChange(gun_index))
 					if(isModeChange(gun_index))
 					{
 					{
 						ShmCharger->gun_info[gun_index].rfidReq = OFF;
 						ShmCharger->gun_info[gun_index].rfidReq = OFF;
-						ftime(&startChargingTime[gun_index]);
+						//ftime(&startChargingTime[gun_index]);
 						ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]);
 						ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]);
 						ftime(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]);
 						ftime(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]);
 						ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]);
 						ftime(&startTime[gun_index][TMR_IDX_PWN_CHANGE]);
@@ -4727,7 +4805,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4736,6 +4814,7 @@ int main(void)
 										}
 										}
 										else
 										else
 										{
 										{
+											ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
 											ShmCharger->gun_info[gun_index].rfidReq = OFF;
 											ShmCharger->gun_info[gun_index].rfidReq = OFF;
 											ocpp_set_auth_req(OFF);
 											ocpp_set_auth_req(OFF);
 											DEBUG_INFO("Authorize fail.\n");
 											DEBUG_INFO("Authorize fail.\n");
@@ -4989,11 +5068,6 @@ int main(void)
 				case SYS_MODE_TERMINATING:
 				case SYS_MODE_TERMINATING:
 					if(isModeChange(gun_index))
 					if(isModeChange(gun_index))
 					{
 					{
-						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration != 0)
-						{
-							ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000;
-						}
-
 						if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state)
 						if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state)
 						{
 						{
 							setLedMotion(gun_index, LED_ACTION_STOP);
 							setLedMotion(gun_index, LED_ACTION_STOP);
@@ -5005,6 +5079,12 @@ int main(void)
 						ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;
 						ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;
 					}
 					}
 
 
+					ftime(&endChargingTime[gun_index]);
+					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration != 0)
+					{
+						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index])/1000;
+					}
+
 					// End authorize pass
 					// End authorize pass
 					if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) ||
 					if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) ||
 					   (ShmCharger->gun_info[gun_index].isAuthPassEnd) ||
 					   (ShmCharger->gun_info[gun_index].isAuthPassEnd) ||
@@ -5172,7 +5252,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -5238,19 +5318,23 @@ int main(void)
 						setLedMotion(gun_index, LED_ACTION_STOP);
 						setLedMotion(gun_index, LED_ACTION_STOP);
 						setRelay(gun_index, OFF);
 						setRelay(gun_index, OFF);
 						setRequest(gun_index, OFF);
 						setRequest(gun_index, OFF);
-						sleep(5);
+						sleep(15);
 					}
 					}
+					
+					if(((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)) ||
+					   ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && (!ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn)))
+					{
+						ShmCharger->gun_info[gun_index].rfidReq = OFF;
+						ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF;
+						ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF;
+						ocpp_set_remotestop(gun_index, OFF);
+						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop = OFF;
 
 
-					ShmCharger->gun_info[gun_index].rfidReq = OFF;
-					ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF;
-					ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF;
-					ocpp_set_remotestop(gun_index, OFF);
-					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop = OFF;
-
-					DB_Insert_Record(localDb, gun_index);
-					setChargerMode(gun_index, SYS_MODE_IDLE);
+						DB_Insert_Record(localDb, gun_index);
+						setChargerMode(gun_index, SYS_MODE_IDLE);
+					}
+					
 					break;
 					break;
-
 				case SYS_MODE_ALARM:
 				case SYS_MODE_ALARM:
 					setLedMotion(gun_index,LED_ACTION_ALARM);
 					setLedMotion(gun_index,LED_ACTION_ALARM);
 
 

二进制
EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin


二进制
EVSE/Projects/AW-CCS/Images/ramdisk.gz


+ 79 - 19
EVSE/Projects/AW-ChargeLab/Apps/main.c

@@ -551,21 +551,59 @@ uint8_t ocpp_get_auth_conf()
 	return result;
 	return result;
 }
 }
 
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 {
 	uint8_t result = OFF;
 	uint8_t result = OFF;
 
 
-	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
-	{
-		if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
-			result = PASS;
-	}
-	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+	switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)
 	{
 	{
-		if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
-			result = PASS;
+		case SYS_MODE_AUTHORIZING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
+					result = PASS;
+			}
+
+			break;
+		case SYS_MODE_CHARGING:
+		case SYS_MODE_TERMINATING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 1.6 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.ResponseIdTagInfo.ParentIdTag : %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag);
+				DEBUG_INFO("StartTransaction[%d].ResponseIdTagInfo.ParentIdTag : %s \n", gun_index ,ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag);
+
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 2.0 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.Response_idTokenInfo.groupIdToken.idToken : %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken);
+				DEBUG_INFO("TransactionEvent[%d].Response_idTokenInfo.groupIdToken.idToken : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken);
+
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken)==0))
+					result = PASS;
+			}
+
+			break;
+		default:
+			break;
 	}
 	}
 
 
+	DEBUG_INFO("Authorize result : %s \n", ((result == PASS)?"Pass":"Fail"));
+
 	return result;
 	return result;
 }
 }
 
 
@@ -688,7 +726,7 @@ uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 	{
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
-		{			
+		{
 			if((strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked")==0) ||
 			if((strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) ||
@@ -2880,7 +2918,7 @@ void checkTask()
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
 				system("pkill OcppBackend");
 			}
 			}
-			
+
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			{
 			{
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
@@ -2895,7 +2933,7 @@ void checkTask()
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
 				system("pkill OcppBackend20");
 			}
 			}
-			
+
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			{
 			{
 				DEBUG_INFO("OcppBackend20 not running, restart it.\n");
 				DEBUG_INFO("OcppBackend20 not running, restart it.\n");
@@ -3243,6 +3281,7 @@ void checkStopReason(uint8_t gun_index)
 {
 {
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
@@ -3265,6 +3304,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
+
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+
+			DEBUG_INFO("Gun-%d [ IdTag ] : %s \n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag);
 		}
 		}
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		{
 		{
@@ -3280,12 +3330,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
 
-		memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 	{
+		memset(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
@@ -3312,6 +3362,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
+
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
+			}
+
+			DEBUG_INFO("Gun-%d [ idToken ] : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken);
 		}
 		}
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT))
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT))
 		{
 		{
@@ -3331,7 +3392,6 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 
 
-		memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
 	}
@@ -3633,7 +3693,7 @@ int main(void)
 						// Set max current to rating current
 						// Set max current to rating current
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 						
 						
-						// Default Ethernet / Wifi / 4G to 1:disconnected 
+						// Default Ethernet / Wifi / 4G to 1:disconnected
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON;
@@ -3826,7 +3886,7 @@ int main(void)
 								   (!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_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
 								{
 								{
-									if(ocpp_get_auth_result() ||
+									if(ocpp_get_auth_result(gun_index) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									{
 									{
@@ -4049,7 +4109,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4386,7 +4446,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4551,7 +4611,7 @@ int main(void)
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								DEBUG_WARN("Firmware upgrade fail.\n");
 								DEBUG_WARN("Firmware upgrade fail.\n");
-								
+
 								sleep(5);
 								sleep(5);
 								system("rm -rvf /mnt/* ");
 								system("rm -rvf /mnt/* ");
 								close(wtdFd);
 								close(wtdFd);

二进制
EVSE/Projects/AW-ChargeLab/Images/FactoryDefaultConfig.bin


二进制
EVSE/Projects/AW-ChargeLab/Images/ramdisk.gz


+ 79 - 19
EVSE/Projects/AW-Regular/Apps/main.c

@@ -551,21 +551,59 @@ uint8_t ocpp_get_auth_conf()
 	return result;
 	return result;
 }
 }
 
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 {
 	uint8_t result = OFF;
 	uint8_t result = OFF;
 
 
-	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
-	{
-		if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
-			result = PASS;
-	}
-	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+	switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)
 	{
 	{
-		if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
-			result = PASS;
+		case SYS_MODE_AUTHORIZING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0))
+					result = PASS;
+			}
+
+			break;
+		case SYS_MODE_CHARGING:
+		case SYS_MODE_TERMINATING:
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 1.6 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.ResponseIdTagInfo.ParentIdTag : %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag);
+				DEBUG_INFO("StartTransaction[%d].ResponseIdTagInfo.ParentIdTag : %s \n", gun_index ,ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag);
+
+				if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0))
+					result = PASS;
+			}
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+			{
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("=== OCPP GETTING AUTHORIZE RESULT 2.0 ====\n");
+				DEBUG_INFO("==========================================\n");
+				DEBUG_INFO("Authorize.Response_idTokenInfo.groupIdToken.idToken : %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken);
+				DEBUG_INFO("TransactionEvent[%d].Response_idTokenInfo.groupIdToken.idToken : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken);
+
+				if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) &&
+				   (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken)==0))
+					result = PASS;
+			}
+
+			break;
+		default:
+			break;
 	}
 	}
 
 
+	DEBUG_INFO("Authorize result : %s \n", ((result == PASS)?"Pass":"Fail"));
+
 	return result;
 	return result;
 }
 }
 
 
@@ -688,7 +726,7 @@ uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 	{
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
-		{			
+		{
 			if((strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked")==0) ||
 			if((strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) ||
 			   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) ||
@@ -2880,7 +2918,7 @@ void checkTask()
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
 				system("pkill OcppBackend");
 			}
 			}
-			
+
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			{
 			{
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
@@ -2895,7 +2933,7 @@ void checkTask()
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
 				system("pkill OcppBackend20");
 			}
 			}
-			
+
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			{
 			{
 				DEBUG_INFO("OcppBackend20 not running, restart it.\n");
 				DEBUG_INFO("OcppBackend20 not running, restart it.\n");
@@ -3243,6 +3281,7 @@ void checkStopReason(uint8_t gun_index)
 {
 {
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized");
@@ -3265,6 +3304,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
+
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+			}
+
+			DEBUG_INFO("Gun-%d [ IdTag ] : %s \n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag);
 		}
 		}
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq)
 		{
 		{
@@ -3280,12 +3330,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
 
-		memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 	{
+		memset(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized");
@@ -3312,6 +3362,17 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 		{
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local");
+
+			if(!isMatchStartUser(gun_index))
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
+			}
+			else
+			{
+				memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
+			}
+
+			DEBUG_INFO("Gun-%d [ idToken ] : %s \n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken);
 		}
 		}
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT))
 		else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT))
 		{
 		{
@@ -3331,7 +3392,6 @@ void checkStopReason(uint8_t gun_index)
 		}
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 
 
-		memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId));
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
 	}
@@ -3633,7 +3693,7 @@ int main(void)
 						// Set max current to rating current
 						// Set max current to rating current
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 						
 						
-						// Default Ethernet / Wifi / 4G to 1:disconnected 
+						// Default Ethernet / Wifi / 4G to 1:disconnected
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON;
 						ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON;
@@ -3826,7 +3886,7 @@ int main(void)
 								   (!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_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
 								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
 								{
 								{
-									if(ocpp_get_auth_result() ||
+									if(ocpp_get_auth_result(gun_index) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									{
 									{
@@ -4049,7 +4109,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4386,7 +4446,7 @@ int main(void)
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4551,7 +4611,7 @@ int main(void)
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								DEBUG_WARN("Firmware upgrade fail.\n");
 								DEBUG_WARN("Firmware upgrade fail.\n");
-								
+
 								sleep(5);
 								sleep(5);
 								system("rm -rvf /mnt/* ");
 								system("rm -rvf /mnt/* ");
 								close(wtdFd);
 								close(wtdFd);

+ 21 - 5
EVSE/Projects/Noodoe/Apps/main.c

@@ -1308,7 +1308,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 
 	// Get CSU root file system version
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.51.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.52.00.0000.00");
 
 
 	// Get AC connector type from model name
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
 	for(uint8_t idx=0;idx<3;idx++)
@@ -3044,7 +3044,8 @@ int main(void)
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) ||
+										if(((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) && 
+										    (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0))||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -3484,7 +3485,8 @@ int main(void)
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									  (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 									{
-										if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) ||
+										if(((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) && 
+										    (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0)) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 										   (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -3530,6 +3532,7 @@ int main(void)
 						sleep(3);
 						sleep(3);
 					}
 					}
 
 
+					memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 					if(ShmOCPP16Data->MsMsg.bits.ResetReq)
 					if(ShmOCPP16Data->MsMsg.bits.ResetReq)
 					{
 					{
 						if(strcmp((char*)ShmOCPP16Data->Reset.Type, "Hard")==0)
 						if(strcmp((char*)ShmOCPP16Data->Reset.Type, "Hard")==0)
@@ -3544,6 +3547,17 @@ int main(void)
 					else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 					else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop)
 					{
 					{
 						sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
 						sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local");
+						
+						if(!isMatchStartUser(gun_index))
+						{
+							memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+						}
+						else
+						{
+							memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
+						}
+
+						DEBUG_INFO("Gun-%d [ IdTag ] : %s \n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag);
 					}
 					}
 					else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)
 					else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)
 					{
 					{
@@ -3553,6 +3567,10 @@ int main(void)
 					{
 					{
 						sprintf((char*)ShmOCPP16Data->StopTransaction[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].StopReason, "UnlockCommand");
 						sprintf((char*)ShmOCPP16Data->StopTransaction[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].StopReason, "UnlockCommand");
 					}
 					}
+					else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
+					{
+						sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EmergencyStop");
+					}
 					else
 					else
 					{
 					{
 						sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other");
 						sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other");
@@ -3560,9 +3578,7 @@ int main(void)
 
 
 					DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 					DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
 
-					memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
 					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0);
-					
 					ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 					ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 					ShmCharger->gun_info[gun_index].rfidReq = OFF;
 					ShmCharger->gun_info[gun_index].rfidReq = OFF;
 					ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF;
 					ShmCharger->gun_info[gun_index].isAuthPassEnd = OFF;

+ 34 - 25
EVSE/Projects/define.h

@@ -474,6 +474,7 @@ struct SysConfigData
 	unsigned char			ShowInformation;
 	unsigned char			ShowInformation;
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
+	unsigned char			StopChargingByButton;		//0: Disable  1: Enable
 };
 };
 
 
 struct ChargingInfoData
 struct ChargingInfoData
@@ -3833,7 +3834,7 @@ struct LedModuleData
 /**************************************************************************************/
 /**************************************************************************************/
 struct StructIdTagInfo
 struct StructIdTagInfo
 {
 {
-	unsigned char 	ExpiryDate[28];
+	unsigned char 	ExpiryDate[36];
 	unsigned char 	ParentIdTag[21];
 	unsigned char 	ParentIdTag[21];
 	unsigned char 	Status[16];		//Accepted, Blocked, Expired, Invalid, ConcurrentTx
 	unsigned char 	Status[16];		//Accepted, Blocked, Expired, Invalid, ConcurrentTx
 };
 };
@@ -3904,7 +3905,7 @@ struct StructSampledValue
 };
 };
 struct StructMeterValue
 struct StructMeterValue
 {
 {
-	unsigned char 				TimeStamp[28];
+	unsigned char 				TimeStamp[36];
 	struct StructSampledValue	SampledValue[20];
 	struct StructSampledValue	SampledValue[20];
 };
 };
 struct StructConfigurationKeyItems
 struct StructConfigurationKeyItems
@@ -3926,7 +3927,7 @@ struct StructChargingSchedulePeriod
 struct StructChargingSchedule
 struct StructChargingSchedule
 {
 {
 	int											Duration;
 	int											Duration;
-	unsigned char 								StartSchedule[28];
+	unsigned char 								StartSchedule[36];
 	unsigned char 								ChargingRateUnit[4];		//A, W
 	unsigned char 								ChargingRateUnit[4];		//A, W
 	struct StructChargingSchedulePeriod			ChargingSchedulePeriod[10];
 	struct StructChargingSchedulePeriod			ChargingSchedulePeriod[10];
 	float 										MinChargingRate;			//0.1;
 	float 										MinChargingRate;			//0.1;
@@ -3939,8 +3940,8 @@ struct StructChargingProfile
 	unsigned char 					ChargingProfilePurpose[24];	//ChargePointMaxProfile, TxDefaultProfile, TxProfile
 	unsigned char 					ChargingProfilePurpose[24];	//ChargePointMaxProfile, TxDefaultProfile, TxProfile
 	unsigned char 					ChargingProfileKind[12];		//Absolute, Recurring, Relative
 	unsigned char 					ChargingProfileKind[12];		//Absolute, Recurring, Relative
 	unsigned char 					RecurrencyKind[8];			//Daily, Weekly
 	unsigned char 					RecurrencyKind[8];			//Daily, Weekly
-	unsigned char 					ValidFrom[28];
-	unsigned char 					ValidTo[28];
+	unsigned char 					ValidFrom[36];
+	unsigned char 					ValidTo[36];
 	struct StructChargingSchedule	ChargingSchedule;
 	struct StructChargingSchedule	ChargingSchedule;
 };
 };
 
 
@@ -3956,13 +3957,13 @@ struct StructBootNotification
 	unsigned char CpMeterType[25];			//meterType
 	unsigned char CpMeterType[25];			//meterType
 	unsigned char CpMeterSerialNumber[25];	//meterSerialNumber
 	unsigned char CpMeterSerialNumber[25];	//meterSerialNumber
 	unsigned char ResponseStatus[16];			//Accepted, Pending, Rejected
 	unsigned char ResponseStatus[16];			//Accepted, Pending, Rejected
-	unsigned char ResponseCurrentTime[28];	//currentTime					//mandatory
+	unsigned char ResponseCurrentTime[36];	//currentTime					//mandatory
 	int 			ResponseHeartbeatInterval;	//interval						//mandatory
 	int 			ResponseHeartbeatInterval;	//interval						//mandatory
 
 
 };
 };
 struct StructHeartbeat
 struct StructHeartbeat
 {
 {
-	unsigned char 				ResponseCurrentTime[28];
+	unsigned char 				ResponseCurrentTime[36];
 };
 };
 struct StructAuthorize
 struct StructAuthorize
 {
 {
@@ -3975,7 +3976,7 @@ struct StructStartTransaction
 	unsigned char 				IdTag[21];
 	unsigned char 				IdTag[21];
 	int 						MeterStart;
 	int 						MeterStart;
 	int 						ReservationId;
 	int 						ReservationId;
-	unsigned char 				Timestamp[28];
+	unsigned char 				Timestamp[36];
 	struct StructIdTagInfo		ResponseIdTagInfo;
 	struct StructIdTagInfo		ResponseIdTagInfo;
 	int 						ResponseTransactionId;
 	int 						ResponseTransactionId;
 };
 };
@@ -3983,7 +3984,7 @@ struct StructStopTransaction
 {
 {
 	unsigned char 				IdTag[21];
 	unsigned char 				IdTag[21];
 	int 						MeterStop;
 	int 						MeterStop;
-	unsigned char 				Timestamp[28];
+	unsigned char 				Timestamp[36];
 	int 						TransactionId;
 	int 						TransactionId;
 	unsigned char 				StopReason[20];				/*	"EmergencyStop",
 	unsigned char 				StopReason[20];				/*	"EmergencyStop",
 															"EVDisconnected",
 															"EVDisconnected",
@@ -4034,7 +4035,7 @@ struct StructStatusNotification
 								                "Faulted"
 								                "Faulted"
 								            */
 								            */
 
 
-	unsigned char 	Timestamp[28];
+	unsigned char 	Timestamp[36];
 	unsigned char 	VendorId[256];
 	unsigned char 	VendorId[256];
 	unsigned char 	VendorErrorCode[50];
 	unsigned char 	VendorErrorCode[50];
 };
 };
@@ -4094,7 +4095,7 @@ struct StructGetCompositeSchedule
 	unsigned char					ChargingRateUnit[4];		//A,W
 	unsigned char					ChargingRateUnit[4];		//A,W
 	unsigned char 					ResponseStatus[12];			//Accepted,Rejected
 	unsigned char 					ResponseStatus[12];			//Accepted,Rejected
 	int 							ResponseConnectorId;
 	int 							ResponseConnectorId;
-	unsigned char					ResponseScheduleStart[28];
+	unsigned char					ResponseScheduleStart[36];
 	struct StructChargingSchedule	ResponseChargingSchedule;
 	struct StructChargingSchedule	ResponseChargingSchedule;
 };
 };
 struct StructGetConfiguration
 struct StructGetConfiguration
@@ -4109,8 +4110,8 @@ struct StructGetDiagnostics
 	unsigned char 			Location[256];
 	unsigned char 			Location[256];
 	int 					Retries;
 	int 					Retries;
 	int						RetryInterval;
 	int						RetryInterval;
-	unsigned char 			StartTime[28];
-	unsigned char 			StopTime[28];
+	unsigned char 			StartTime[36];
+	unsigned char 			StopTime[36];
 	unsigned char 			ResponseFileName[256];
 	unsigned char 			ResponseFileName[256];
 };
 };
 struct StructGetLocalListVersion
 struct StructGetLocalListVersion
@@ -4139,7 +4140,7 @@ struct StructRemoteStopTransaction
 struct StructReserveNow
 struct StructReserveNow
 {
 {
 	int			 		ConnectorId;
 	int			 		ConnectorId;
-	unsigned char 		ExpiryDate[28];
+	unsigned char 		ExpiryDate[36];
 	unsigned char 		IdTag[21];
 	unsigned char 		IdTag[21];
 	unsigned char 		ParentIdTag[21];
 	unsigned char 		ParentIdTag[21];
 	int					ReservationId;
 	int					ReservationId;
@@ -4188,7 +4189,7 @@ struct StructUpdateFirmware
 {
 {
 	unsigned char 		Location[256];
 	unsigned char 		Location[256];
 	int					Retries;
 	int					Retries;
-	unsigned char 		RetrieveDate[28];
+	unsigned char 		RetrieveDate[36];
 	int 				RetryInterval;
 	int 				RetryInterval;
 };
 };
 
 
@@ -4211,7 +4212,7 @@ struct OCPP16ConfigurationTable
 
 
 struct StrcutSetUserPrice
 struct StrcutSetUserPrice
 {
 {
-    unsigned char   idToken[20];
+    unsigned char   idToken[21];
     unsigned char   price[256];
     unsigned char   price[256];
 };
 };
 
 
@@ -4239,15 +4240,15 @@ struct CertificateHashDataType
 struct LogParametersType
 struct LogParametersType
 {
 {
 	unsigned char remoteLocation[513];								// Required. The URL of the location at the remote system where the log should be stored.
 	unsigned char remoteLocation[513];								// Required. The URL of the location at the remote system where the log should be stored.
-	unsigned char oldestTimestamp[28];								// Optional. This contains the date and time of the oldest logging information to include in the diagnostics.
-	unsigned char latestTimestamp[28];								// Optional. This contains the date and time of the latest logging information to include in the diagnostics.
+	unsigned char oldestTimestamp[36];								// Optional. This contains the date and time of the oldest logging information to include in the diagnostics.
+	unsigned char latestTimestamp[36];								// Optional. This contains the date and time of the latest logging information to include in the diagnostics.
 };
 };
 
 
 struct FirmwareType
 struct FirmwareType
 {
 {
 	unsigned char location[513];									// Required. URI defining the origin of the firmware.
 	unsigned char location[513];									// Required. URI defining the origin of the firmware.
-	unsigned char retrieveDateTime[28];								// Required. Date and time at which the firmware shall be retrieved.
-	unsigned char installDateTime[28];								// Optional. Date and time at which the firmware shall be installed.
+	unsigned char retrieveDateTime[36];								// Required. Date and time at which the firmware shall be retrieved.
+	unsigned char installDateTime[36];								// Optional. Date and time at which the firmware shall be installed.
 	unsigned char signingCertificate[5501];							// Optional. Certificate with which the firmware was signed. X.509 certificate, first DER encoded into binary, and then Base64 encoded.
 	unsigned char signingCertificate[5501];							// Optional. Certificate with which the firmware was signed. X.509 certificate, first DER encoded into binary, and then Base64 encoded.
 	unsigned char signature[801];									// Optional. Base64 encoded firmware signature.
 	unsigned char signature[801];									// Optional. Base64 encoded firmware signature.
 };
 };
@@ -4525,7 +4526,7 @@ struct OCPP16Data
 /*
 /*
  * =============== Enum variable content ===============
  * =============== Enum variable content ===============
  */
  */
-enum AlignedDataCtrlrVariable
+enum OCPP20CtrlrVariable
 {
 {
 	AlignedDataCtrlr_Enabled=0,
 	AlignedDataCtrlr_Enabled=0,
 	AlignedDataCtrlr_Available,
 	AlignedDataCtrlr_Available,
@@ -4623,6 +4624,7 @@ enum AlignedDataCtrlrVariable
 	SecurityCtrlr_CertificateEntries,
 	SecurityCtrlr_CertificateEntries,
 	SecurityCtrlr_SecurityProfile,
 	SecurityCtrlr_SecurityProfile,
 	SecurityCtrlr_AdditionalRootCertificateCheck,
 	SecurityCtrlr_AdditionalRootCertificateCheck,
+	SecurityCtrlr_MaxCertificateChainSize,
 	SmartChargingCtrlr_Enabled,
 	SmartChargingCtrlr_Enabled,
 	SmartChargingCtrlr_Available,
 	SmartChargingCtrlr_Available,
 	SmartChargingCtrlr_ACPhaseSwitchingSupported,
 	SmartChargingCtrlr_ACPhaseSwitchingSupported,
@@ -5079,6 +5081,11 @@ struct TransactionType
 	unsigned int remoteStartId;										// Optional. The ID given to remote start request (RequestStartTransactionRequest.
 	unsigned int remoteStartId;										// Optional. The ID given to remote start request (RequestStartTransactionRequest.
 };
 };
 
 
+struct StatusInfoType
+{
+	unsigned char reasonCode[21];									// Required. A predefined code for the reason why thestatus is returned in this response. The string is case-insensitive.
+	unsigned char additionalInfo[513];								// Optional. Additional text to provide detailed information.
+};
 /*
 /*
  * =============== Message ===============
  * =============== Message ===============
  */
  */
@@ -5108,9 +5115,10 @@ struct CancelReservation_20
 
 
 struct CertificateSigned_20
 struct CertificateSigned_20
 {
 {
-	unsigned char certificate[10][5500];							// Required. The signed X.509 certificate, first DER encoded into binary, and then Base64 encoded. This can also contain the necessary sub CA certificates. In that case, the order should follow the certificate chain, starting from the leaf certificate.
+	unsigned char certificateChain[10001];							// Required. Required. The signed PEM encoded X.509 certificate.This can also contain the necessary sub CA certificates.In that case, the order of the bundle should follow thecertificate chain, starting from the leaf certificate.The Configuration Variable MaxCertificateChainSize canbe used to limit the maximum size of this field.
 	unsigned char certificateType[32];								// Optional. Indicates the type of the signed certificate that is returned.
 	unsigned char certificateType[32];								// Optional. Indicates the type of the signed certificate that is returned.
 	unsigned char Response_status[16];								// Required. Returns whether certificate signing has been accepted, otherwise rejected.
 	unsigned char Response_status[16];								// Required. Returns whether certificate signing has been accepted, otherwise rejected.
+	struct StatusInfoType Response_statusInfo;						// Optional. Detailed status information.
 	unsigned char guid[37];											// Save guid from server request
 	unsigned char guid[37];											// Save guid from server request
 };
 };
 
 
@@ -5219,7 +5227,7 @@ struct GetCertificateStatus_20
 {
 {
 	struct OCSPRequestDataType ocspRequestData;						// Required. Indicates the certificate of which the status is requested.
 	struct OCSPRequestDataType ocspRequestData;						// Required. Indicates the certificate of which the status is requested.
 	unsigned char Response_status[16];								// Required. This indicates whether the charging station was able to retrieve the OCSP certificate status.
 	unsigned char Response_status[16];								// Required. This indicates whether the charging station was able to retrieve the OCSP certificate status.
-	unsigned char Response_ocspResult[5500];						// Optional. OCSPResponse class as defined in IETF RFC 6960. DER encoded (as defined in IETF RFC 6960), and then base64 encoded. MAY only be omitted when status is not Accepted.
+	unsigned char Response_ocspResult[5501];						// Optional. OCSPResponse class as defined in IETF RFC 6960. DER encoded (as defined in IETF RFC 6960), and then base64 encoded. MAY only be omitted when status is not Accepted.
 };
 };
 
 
 struct GetChargingProfiles_20
 struct GetChargingProfiles_20
@@ -5318,7 +5326,7 @@ struct Heartbeat_20
 struct InstallCertificate_20
 struct InstallCertificate_20
 {
 {
 	unsigned char certificateType[32];								// Required. Indicates the certificate type that is sent.
 	unsigned char certificateType[32];								// Required. Indicates the certificate type that is sent.
-	unsigned char certificate[5500];								// Required. A X.509 certificate, first DER encoded into binary, and then Base64 encoded.
+	unsigned char certificate[5501];								// Required. A X.509 certificate, first DER encoded into binary, and then Base64 encoded.
 	unsigned char Response_status[16];								// Required. Charging Station indicates if installation was successful.
 	unsigned char Response_status[16];								// Required. Charging Station indicates if installation was successful.
 	unsigned char guid[37];											// Save guid from server request
 	unsigned char guid[37];											// Save guid from server request
 };
 };
@@ -5541,9 +5549,10 @@ struct SetVariables_20
 
 
 struct SignCertificate_20
 struct SignCertificate_20
 {
 {
-	unsigned char csr[5500];										// Required. The Charging Station SHALL send the public key in form of a Certificate Signing Request (CSR) as described in RFC 2986 [22] using the SignCertificateRequest message.
+	unsigned char csr[5501];										// Required. The Charging Station SHALL send the public key in form of a Certificate Signing Request (CSR) as described in RFC 2986 [22] using the SignCertificateRequest message.
 	unsigned char certificateType[32];								// Optional. Indicates the type of certificate that is to be signed. When omitted the certificate is to be used for both the 15118 connection (if implemented) and the Charging Station to CSMS connection.
 	unsigned char certificateType[32];								// Optional. Indicates the type of certificate that is to be signed. When omitted the certificate is to be used for both the 15118 connection (if implemented) and the Charging Station to CSMS connection.
 	unsigned char Response_status[16];								// Required. Specifies whether the CSMS can process the request.
 	unsigned char Response_status[16];								// Required. Specifies whether the CSMS can process the request.
+	struct StatusInfoType Response_statusInfo;						// Optional. Detailed status information.
 };
 };
 
 
 struct StatusNotification_20
 struct StatusNotification_20

+ 9 - 0
EVSE/rootfs/etc/init.d/rcS

@@ -108,3 +108,12 @@ ln -sf libbz2.so.1.0.6 libbz2.so.1
 /usr/sbin/ntpd -nqp cn.ntp.org.cn &
 /usr/sbin/ntpd -nqp cn.ntp.org.cn &
 /usr/sbin/ntpd -nqp tock.stdtime.gov.tw &
 /usr/sbin/ntpd -nqp tock.stdtime.gov.tw &
 /usr/sbin/ntpd -nqp 0.europe.pool.ntp.org &
 /usr/sbin/ntpd -nqp 0.europe.pool.ntp.org &
+
+#   ---------------------------------------------
+#   Enable auto reboot when kernel panic occur
+#   ---------------------------------------------
+echo 3 > /proc/sys/kernel/panic
+echo 1 > /proc/sys/kernel/panic_on_oops
+echo 1 > /proc/sys/kernel/panic_on_warn
+echo 1 > /proc/sys/kernel/panic_on_rcu_stall
+

+ 1 - 0
EVSE/rootfs/root/.gitignore

@@ -8,3 +8,4 @@ Module_ProduceUtils
 Module_EventLogging
 Module_EventLogging
 Module_PhBackend
 Module_PhBackend
 Module_InitUpgrade
 Module_InitUpgrade
+Module_Payment

二进制
EVSE/rootfs/root/Module_Payment


二进制
EVSE/rootfs/root/OcppBackend20


+ 1 - 1
EVSE/rootfs/var/www/head.php

@@ -119,7 +119,7 @@
 		break;
 		break;
 	}
 	}
 	if(substr($model,4,3)=="122"){
 	if(substr($model,4,3)=="122"){
-		$am120='block';
+		$am120='none';
 	}
 	}
 	else{
 	else{
 		$am120='none';
 		$am120='none';

+ 8 - 0
EVSE/rootfs/var/www/set_charging.php

@@ -574,6 +574,13 @@ img {
 											<input type="text" name="MaxChargingDuration" id="MaxChargingDuration" class="form-control" value="<?php echo $obj['MaxChargingDuration'];?>" placeholder="<?php echo ($obj['MaxChargingDuration']==0||$obj['MaxChargingDuration']=="")?"'0' means unlimit":"";?>" title="'0' means unlimit">
 											<input type="text" name="MaxChargingDuration" id="MaxChargingDuration" class="form-control" value="<?php echo $obj['MaxChargingDuration'];?>" placeholder="<?php echo ($obj['MaxChargingDuration']==0||$obj['MaxChargingDuration']=="")?"'0' means unlimit":"";?>" title="'0' means unlimit">
 											<small class="form-text text-muted-red"><label id="MaxChargingDurationText" style="display:none;">'0' means unlimit</label></small>
 											<small class="form-text text-muted-red"><label id="MaxChargingDurationText" style="display:none;">'0' means unlimit</label></small>
 										</div>
 										</div>
+										<div class="form-group" style="display:<?php echo $am001;?>">
+											<label>Stop Charging By Button</label>
+											<select class="form-control" id="StopChargingByButton" name="StopChargingByButton">
+												<option value="0" <?php echo $obj['StopChargingByButton']=="0"?"selected":""?>>Disable</option>
+												<option value="1" <?php echo $obj['StopChargingByButton']=="1"?"selected":""?>>Enable</option>
+											</select>
+										</div>
 										<div class="form-group" id="AcMaxChargingCurrentDiv">
 										<div class="form-group" id="AcMaxChargingCurrentDiv">
 											<label>AC Max Charging Current</label>
 											<label>AC Max Charging Current</label>
 											<small class="form-text text-muted-red">amp</small>
 											<small class="form-text text-muted-red">amp</small>
@@ -1451,6 +1458,7 @@ img {
 						"&MaxChargingCurrent=" + document.getElementById("MaxChargingCurrent").value+
 						"&MaxChargingCurrent=" + document.getElementById("MaxChargingCurrent").value+
 						"&AcMaxChargingCurrent=" + document.getElementById("AcMaxChargingCurrent").value+
 						"&AcMaxChargingCurrent=" + document.getElementById("AcMaxChargingCurrent").value+
 						"&MaxChargingDuration=" + document.getElementById("MaxChargingDuration").value+
 						"&MaxChargingDuration=" + document.getElementById("MaxChargingDuration").value+
+						"&StopChargingByButton=" + document.getElementById("StopChargingByButton").value+
 						"&LocalWhiteCard0=" + document.getElementById("LocalWhiteCard0").value+
 						"&LocalWhiteCard0=" + document.getElementById("LocalWhiteCard0").value+
 						"&LocalWhiteCard1=" + document.getElementById("LocalWhiteCard1").value+
 						"&LocalWhiteCard1=" + document.getElementById("LocalWhiteCard1").value+
 						"&LocalWhiteCard2=" + document.getElementById("LocalWhiteCard2").value+
 						"&LocalWhiteCard2=" + document.getElementById("LocalWhiteCard2").value+

+ 4 - 0
EVSE/rootfs/var/www/set_charging_action.php

@@ -27,6 +27,7 @@
 		checkMaxValue("MaxChargingCurrent");
 		checkMaxValue("MaxChargingCurrent");
 		checkMaxValue("AcMaxChargingCurrent");
 		checkMaxValue("AcMaxChargingCurrent");
 		checkMaxValue("MaxChargingDuration");
 		checkMaxValue("MaxChargingDuration");
+		checkValue("StopChargingByButton");
 		if(isset($_POST['MaxChargingEnergy'])){
 		if(isset($_POST['MaxChargingEnergy'])){
 			$json['MaxChargingEnergy']			= (int)$_POST['MaxChargingEnergy'];
 			$json['MaxChargingEnergy']			= (int)$_POST['MaxChargingEnergy'];
 		}
 		}
@@ -42,6 +43,9 @@
 		if(isset($_POST['MaxChargingDuration'])){
 		if(isset($_POST['MaxChargingDuration'])){
 			$json['MaxChargingDuration'] 		= (int)$_POST['MaxChargingDuration'];
 			$json['MaxChargingDuration'] 		= (int)$_POST['MaxChargingDuration'];
 		}
 		}
+		if(isset($_POST['StopChargingByButton'])){
+			$json['StopChargingByButton'] 		= (int)$_POST['StopChargingByButton'];
+		}
 		if(isset($_POST['LocalWhiteCard0'])){
 		if(isset($_POST['LocalWhiteCard0'])){
 			$json['LocalWhiteCard0']			= isset($_POST['LocalWhiteCard0'])?$_POST['LocalWhiteCard0']:"";
 			$json['LocalWhiteCard0']			= isset($_POST['LocalWhiteCard0'])?$_POST['LocalWhiteCard0']:"";
 		}
 		}

部分文件因为文件数量过多而无法显示