Преглед изворни кода

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. BIN
      EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin
  17. BIN
      EVSE/Projects/AW-CCS/Images/ramdisk.gz
  18. 79 19
      EVSE/Projects/AW-ChargeLab/Apps/main.c
  19. BIN
      EVSE/Projects/AW-ChargeLab/Images/FactoryDefaultConfig.bin
  20. BIN
      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. BIN
      EVSE/rootfs/root/Module_Payment
  27. BIN
      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
 
 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:
@@ -118,3 +119,10 @@ Module_InitUpgrade:
 	$(CC) -o Module_InitUpgrade Module_InitUpgrade.o
 	rm -f Module_InitUpgrade.o
 	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 AcMaxChargingCurrent = 0;
 			int MaxChargingDuration = 0;
+			int StopChargingByButton = 0;
 			char *LocalWhiteCard0 = NULL;
 			char *LocalWhiteCard1 = NULL;
 			char *LocalWhiteCard2 = NULL;
@@ -725,6 +726,10 @@ int main(int argc, char *argv[]) {
 				MaxChargingDuration = json_object_get_int(val_obj);
 				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) ) {
 				LocalWhiteCard0 = (char*)json_object_get_string(val_obj);
 				strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0],LocalWhiteCard0);
@@ -1459,6 +1464,7 @@ int main(int argc, char *argv[]) {
 		struct json_object *MaxChargingCurrent;
 		struct json_object *AcMaxChargingCurrent;
 		struct json_object *MaxChargingDuration;
+		struct json_object *StopChargingByButton;
 		struct json_object *LocalWhiteCard[10];
 		struct json_object *LocalWhiteCardArr= json_object_new_array();
 		struct json_object *isBilling;
@@ -1699,6 +1705,7 @@ int main(int argc, char *argv[]) {
 		MaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
 		AcMaxChargingCurrent = json_object_new_int(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent);
 		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[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[1]);
 		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,"AcMaxChargingCurrent",AcMaxChargingCurrent);
 		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[1]);
 		json_object_array_add(LocalWhiteCardArr,LocalWhiteCard[2]);

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

@@ -41,7 +41,7 @@ static char *requestNames[] = { "CancelReservation",
 								"Reset",
 								"SendLocalList",
 								"SetChargingProfile",
-								"SetDisplayMessage",
+								"SetDisplayMessages",
 								"SetMonitoringBase",
 								"SetMonitoringLevel",
 								"SetNetworkProfile",
@@ -135,7 +135,7 @@ static FunCallPtr funcalls[] = {handleCancelReservationRequest,
 								handleResetRequest,
 								handleSendLocalListRequest,
 								handleSetChargingProfileRequest,
-								handleSetDisplayMessageRequest,
+								handleSetDisplayMessagesRequest,
 								handleSetMonitoringBaseRequest,
 								handleSetMonitoringLevelRequest,
 								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].variable.name, "Measurands");
 		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].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		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].variable.name, "TxEndedMeasurands");
 		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].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		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].variable.name, "Storage");
 		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].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		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].variable.name, "DisplayMessages");
 		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].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]);
 
 		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].variable.name, "Entries");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
+		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.maxLimit = 5000;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		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].variable.name, "Storage");
 		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].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
 		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].variable.name, "TxEndedMeasurands");
 		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].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]);
 
 		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].variable.name, "TxStartedMeasurands");
 		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].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		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].variable.name, "TxUpdatedMeasurands");
 		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].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]);
 
 		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]);
 		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].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, " ");
 		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].variable.name, "CertificateEntries");
 		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].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");
 		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");
 		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 */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		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].variable.name, "Entries");
 		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].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]);
 
 		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].variable.name, "AdditionalRootCertificateCheck");
 
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].component.name, "SecurityCtrlr");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variable.name, "MaxCertificateChainSize");
+
 		/* SmartChargingCtrlr Required item */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
@@ -5190,6 +5218,46 @@ void CheckSystemValue(void)
 		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 &&
 	   (server_sign == TRUE) &&
 	   (ShmOCPP20Data->GetReport.requestId > 0))
@@ -5339,15 +5407,24 @@ void CheckSystemValue(void)
 	{
 		if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Install]) == 0)
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 		else if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Update]) == 0)
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 		else
 		{
-
+			/*
+			 *	TODO:
+			 *		1.
+			 */
 		}
 
 		sendGet15118EVCertificateRequest();
@@ -5355,8 +5432,6 @@ void CheckSystemValue(void)
 	}
 
 
-
-
 	//===============================
 	// Each connector operation check
 	//===============================
@@ -6006,7 +6081,14 @@ void CheckSystemValue(void)
 		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf == ON))
 		{
 			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);
 		}
+
+		//==========================================
+		// 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)
 	{
 		result = PASS;
+
+		ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = OFF;
 	}
 	return result;
 }
@@ -7935,7 +8036,7 @@ int sendSecurityEventNotificationRequest()
 	return result;
 }
 
-int sendSignCertificateRequest()
+int sendSignCertificateRequest(CertificateSigningUseEnumType certType)
 {
 	mtrace();
 	int result = FAIL;
@@ -7945,7 +8046,23 @@ int sendSignCertificateRequest()
 	json_object *SignCertificate = json_object_new_object();
 	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));
+
+	sprintf((char*)ShmOCPP20Data->SignCertificate.certificateType, CertificateSigningUseEnumTypeStr[certType]);
 	json_object_object_add(SignCertificate, "certificateType", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.certificateType));
 
 	random_uuid(guid);
@@ -9096,11 +9213,21 @@ int sendCertificateSignedConfirmation(char *uuid)
 	int result = FAIL;
 	char message[4096]={0};
 	json_object *CertificateSigned = json_object_new_object();
+	json_object *statusInfo = json_object_new_object();
 
 	DEBUG_INFO("sendCertificateSignedConfirmation...\n");
 
 	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]"
 								,MESSAGE_TYPE_CALLRESULT
 								,uuid
@@ -9850,7 +9977,7 @@ int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index)
 	return result;
 }
 
-int sendSetDisplayMessageConfirmation(char *uuid)
+int sendSetDisplayMessagesConfirmation(char *uuid)
 {
 	mtrace();
 	int result = FAIL;
@@ -10293,18 +10420,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 		memset(&ShmOCPP20Data->CertificateSigned, 0, sizeof(struct CertificateSigned_20));
 		memcpy(&ShmOCPP20Data->CertificateSigned.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.guid));
 		// 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
 		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)
 			{
-
+				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)
 			{
-
+				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]);
 	}
@@ -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));
 			}
-			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
+			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
+			ShmOCPP20Data->MsMsg.bits.GetDisplayMessagesReq = ON;
 		}
 		else
-			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Unknown]);
+			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Unknown]);
 	}
 	json_object_put(GetDisplayMessages);
 
@@ -14406,7 +14534,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	return result;
 }
 
-int handleSetDisplayMessageRequest(char *uuid, char *payload)
+int handleSetDisplayMessagesRequest(char *uuid, char *payload)
 {
 	mtrace();
 	int result = FAIL;
@@ -14473,9 +14601,9 @@ int handleSetDisplayMessageRequest(char *uuid, char *payload)
 	json_object_put(SetDisplayMessage);
 
 	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;
 
 	return result;
@@ -14768,6 +14896,7 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 	mtrace();
 	int result = FAIL;
 	json_object *SetVariableMonitoring;
+	uint8_t variableQuantity = 0;
 
 	DEBUG_INFO("handleSetVariableMonitoringRequest...\n");
 	SetVariableMonitoring = json_tokener_parse(payload);
@@ -14778,6 +14907,7 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 		// Required data
 		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)
 			{
 				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)
 			{
 				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)
@@ -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));
 			}
+
+			strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, SetMonitoringStatusEnumTypeStr[SetMonitoringStatusEnumType_Accepted]);
 		}
 	}
 	json_object_put(SetVariableMonitoring);
 
+
+	sendSetVariableMonitoringConfirmation(uuid, variableQuantity);
+
 	return result;
 }
 
@@ -14967,7 +15097,6 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 	int result = FAIL;
 	int connectorIdIsNULL = FALSE;
 	int connectorIdInt =0;
-	char requestedMessagestr[40]={0};
 	json_object *TriggerMessage;
 
 	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((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] );
 			sendTriggerMessageConfirmation(uuid);
@@ -15034,7 +15163,7 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 	//==========================
 	// 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) ||
 		   ((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;
 	}
-	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)
 			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Idle]);
 		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))
 			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);
 	}
-	else if (strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
+	else if (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
 	{
 		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)
 		{
@@ -15093,6 +15222,57 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 				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;
 }
@@ -15283,9 +15463,9 @@ void *UpdateFirmwareProcess(void *data)
 	int retriesInt =0, retryIntervalInt=0;
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	int port=0;
-	char locationstr[160]={0}, retrieveDatestr[30]={0};
+	char locationstr[512]={0}, retrieveDatestr[36]={0};
 	int isSuccess = 0;
-	char ftpbuf[200];
+	char ftpbuf[512];
 	char temp[100];
 	char * pch;
 
@@ -15315,17 +15495,25 @@ void *UpdateFirmwareProcess(void *data)
 	}
 	json_object_put(UpdateFirmware);
 
-
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	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/*");
 	if(strncmp(locationstr,"http", 4) == 0)
 	{
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 
-	    //sscanf(locationstr,"%[^:]:%*2[/]%[^:]:%[^@]@%[^/]%199[^\n]",
-		    	    	//	         protocol, user, password, host, path);
 		sprintf(ftppath,"/%s", path);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("protocol: %s\n",protocol);
@@ -15362,21 +15550,24 @@ void *UpdateFirmwareProcess(void *data)
 			{
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				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
 			{
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
 				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
 	{
     	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
     	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 i=1;
     	char filenametemp[50];
@@ -15414,16 +15605,6 @@ void *UpdateFirmwareProcess(void *data)
     	sscanf(host,"%[^/]%s",host1, 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)
     	{
     		port = 21;
@@ -15442,7 +15623,9 @@ void *UpdateFirmwareProcess(void *data)
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 				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
 			{
@@ -15450,15 +15633,19 @@ void *UpdateFirmwareProcess(void *data)
 				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 
 			}
-		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
 	}
     else
     {
 		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
 		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);
 
 }
@@ -15915,6 +16102,15 @@ void hanldeSignCertificateResponse(char *payload, int gun_index)
 		// Required data
 		if(json_object_object_get(SignCertificate,"status") != NULL)
 			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);
 

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

@@ -871,7 +871,7 @@ int sendDeleteCertificateConfirmation(char *uuid);
 int sendGetBaseReportConfirmation(char *uuid);
 int sendGetChargingProfilesConfirmation(char *uuid, unsigned char gun_index);
 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 sendGetLocalListVersionConfirmation(char *uuid);
 int sendGetLogConfirmation(char *uuid);
@@ -887,7 +887,7 @@ int sendReserveNowConfirmation(char *uuid, unsigned char gun_index);
 int sendResetConfirmation(char *uuid);
 int sendSendLocalListConfirmation(char *uuid);
 int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index);
-int sendSetDisplayMessageConfirmation(char *uuid);
+int sendSetDisplayMessagesConfirmation(char *uuid);
 int sendSetMonitoringBaseConfirmation(char *uuid);
 int sendSetMonitoringLevelConfirmation(char *uuid);
 int sendSetNetworkProfileConfirmation(char *uuid);
@@ -937,7 +937,7 @@ int handleReserveNowRequest(char *uuid, char *payload);
 int handleResetRequest(char *uuid, char *payload);
 int handleSendLocalListRequest(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 handleSetMonitoringLevelRequest(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;
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
+			DEBUG_OCPPMESSAGE_INFO("<==== Get PONG packet.\n");
 			break;
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 			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
 {
 	int listVersionInt;
-	char idTagstr[20];
-	char parentIdTag[20];
-	char expiryDate[30];
+	char idTagstr[21];
+	char parentIdTag[21];
+	char expiryDate[36];
 	char idTagstatus[16];
 }idTagQuery;
 
@@ -3472,7 +3472,7 @@ void CheckSystemValue(void)
 			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();
 		}
@@ -3534,8 +3534,8 @@ int sendAuthorizeRequest(int gun_index)
 			}
 
 			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");
 			DEBUG_INFO("ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status);
 			ShmOCPP16Data->SpMsg.bits.AuthorizeReq = 0;
@@ -3547,7 +3547,7 @@ int sendAuthorizeRequest(int gun_index)
 		{
 			DEBUG_INFO("off-line Local Authorization get result !!!!\n");
 			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]))
 				sprintf((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Expired");
@@ -4333,10 +4333,12 @@ S_FAULT                 =12
 	}
 
 	//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;
 	}
+	ShmOCPP16Data->CsMsg.bits[gun_index].TriggerMessageReq = 0;
 
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].Timestamp, buf);
 	strcpy((char *)ShmOCPP16Data->StatusNotification[gun_index].VendorId, (char*)ShmSysConfigAndInfo->SysConfig.chargePointVendor);
@@ -6311,7 +6313,7 @@ int sendSignCertificateRequest()
 
 	// Read csr file content
 	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;
 	size_t len = 0;
 	while(getline(&line, &len, fp) != -1)
@@ -9061,8 +9063,10 @@ void* GetDiagnosticsProcess(void* data)
 	}
 
 end:
-	DiagnosticsStatusNotificationStatus = DIAGNOSTIC_STATUS_IDLE;
 	system("rm -f /mnt/*");
+	sleep(5);
+	sprintf((char*)ShmOCPP16Data->DiagnosticsStatusNotification.Status, "%s", DiagnosticsStatusStr[DiagnosticsStatus_Idle]);
+	ShmOCPP16Data->SpMsg.bits.DiagnosticsStatusNotificationReq = 1;
 	pthread_exit(NULL);
 }
 
@@ -11555,13 +11559,17 @@ int handleTriggerMessageRequest(char *uuid, char *payload)
 		{
 			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
 			{
+				ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].TriggerMessageReq = 1;
 				cpinitateMsg.bits[connectorIdInt -1].StatusNotificationReq = 1;
 			}
 		}
 		else
 		{
 			for(int idx=0;idx< gunTotalNumber;idx++)
+			{
+				ShmOCPP16Data->CsMsg.bits[idx].TriggerMessageReq = 1;
 				cpinitateMsg.bits[idx].StatusNotificationReq = 1;
+			}
 		}
 	}
 
@@ -11742,13 +11750,12 @@ void *UpdateFirmwareProcess(void *data)
 	int retriesInt =0, retryIntervalInt=0;
 	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
 	int port=0;
-	char locationstr[160]={0}, retrieveDatestr[30]={0};
+	char locationstr[512]={0}, retrieveDatestr[36]={0};
 	int isSuccess = 0;
-	char ftpbuf[200];
+	char ftpbuf[512];
 	char temp[100];
 	char * pch;
 
-
 	DEBUG_INFO("handleUpdateFirmwareRequest ...\n");
 	json_object *UpdateFirmware;
 	UpdateFirmware = json_tokener_parse(UpdateFirmwarepayloadData);
@@ -11774,17 +11781,24 @@ void *UpdateFirmwareProcess(void *data)
 	}
 	json_object_put(UpdateFirmware);
 
-
 	memset(ftppath, 0, ARRAY_SIZE(ftppath));
 	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/*");
 	if(strncmp(locationstr,"http", 4) == 0)
 	{
 		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
 
-	    //sscanf(locationstr,"%[^:]:%*2[/]%[^:]:%[^@]@%[^/]%199[^\n]",
-		    	    	//	         protocol, user, password, host, path);
 		sprintf(ftppath,"/%s", path);
 		DEBUG_INFO("locationstr: %s\n", locationstr);
 		DEBUG_INFO("protocol: %s\n",protocol);
@@ -11814,21 +11828,24 @@ void *UpdateFirmwareProcess(void *data)
 		{
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-			sleep(3);
+			sleep(1);
 
 			isSuccess = httpDownLoadFile(host, ftppath, filenametemp, locationstr);
 			if(!isSuccess)
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				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
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				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
 	{
@@ -11892,7 +11909,7 @@ void *UpdateFirmwareProcess(void *data)
 		{
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
-			sleep(3);
+			sleep(1);
 
 			isSuccess = ftpDownLoadFile(host1, user, password, port, ftppath, filenametemp, locationstr);
 			if(!isSuccess)
@@ -11901,24 +11918,29 @@ void *UpdateFirmwareProcess(void *data)
 				DEBUG_INFO("Update firmware request and download file fail.\n");
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 				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
 			{
 				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
 				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
 			}
-		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
 	}
     else
     {
 		sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
 		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);
-
 }
 
 int handleCertificateSignedRequest(char *uuid, char *payload)
@@ -11935,7 +11957,7 @@ int handleCertificateSignedRequest(char *uuid, char *payload)
 	}
 	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);
 	fclose(fp);
 	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
@@ -12077,9 +12099,9 @@ int handleExtendedTriggerMessageRequest(char *uuid, char *payload)
 	{
 		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 )

+ 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;
 		case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
 			DEBUG_INFO("LWS_CALLBACK_CLIENT_RECEIVE_PONG\n");
+			DEBUG_OCPPMESSAGE_INFO("<===== Get PONG packet.\n");
 			break;
 		case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
 			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_100						0x06
 #define CONNECTION_COMPLETE_MARK			0x01
-#define QRCODE_DISABLE						0x01
+#define QRCODE_BANDED						0x01
 #define QRCODE_ENABLE 						0x02
-#define QRCODE_BANDED						0x03
+#define QRCODE_DISABLE						0x03
 
 //=======================================
 // 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].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
 			{
 				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)
 						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<27;
 					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;
 					
@@ -2265,7 +2270,23 @@ int main(void)
 					else
 						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
 				//==========================================================
@@ -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 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);
 					}
 
@@ -2380,6 +2402,17 @@ int main(void)
 						DEBUG_INFO("*******************************************\n");
 						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
@@ -2554,6 +2587,7 @@ int main(void)
 						//===============================
 						// 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;
@@ -2566,6 +2600,7 @@ int main(void)
 							else
 								failCount[gun_index] = FAIL_SPEC_COMM;
 						}
+						*/
 						break;
 					case 13:
 						//===============================
@@ -2810,6 +2845,7 @@ int main(void)
 							}
 							break;
 						case 6:
+							/*
 							DEBUG_INFO("===========================================\n");
 							DEBUG_INFO("==== Normal priority polling : Case 13 ====\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 L3N_L31 power consumption : %f kWh\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/100));
 							}
+							*/
 							break;
 						case 7:
 							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 	"main.h"
 
+
 //==========================
 // System basic sample constant
 //==========================
@@ -567,21 +568,59 @@ uint8_t ocpp_get_auth_conf()
 	return result;
 }
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 	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;
 }
 
@@ -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);
 
 	// 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
 	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)
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 			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)
 		{
 			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)
 		{
@@ -3488,12 +3539,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		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);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	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))
 		{
 			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)
 		{
 			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) ||
 				(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);
 
-		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);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
@@ -3782,7 +3843,7 @@ int main(void)
 				if(ShmCharger->isLcdOn == ON)
 				{
 					//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;
 				}
 			}
@@ -3791,7 +3852,7 @@ int main(void)
 				if(ShmCharger->isLcdOn == OFF)
 				{
 					//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;
 				}
 			}
@@ -3843,10 +3904,26 @@ int main(void)
 			//==========================================
 			// 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
-				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"
@@ -4184,7 +4261,7 @@ int main(void)
 								   (!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() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)))
 									{
@@ -4200,7 +4277,6 @@ int main(void)
 									else
 									{
 										ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
-																				 
 										DEBUG_INFO("Authorize fail.\n");
 										setSpeaker(ON,SPEAKER_INTERVAL_3COUNT);
 										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));
 									ocpp_copy_userid_to_starttransaction(gun_index);
 									ocpp_set_starttransaction_req(gun_index, ON);
+									ftime(&startChargingTime[gun_index]);
 
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
 								}
@@ -4478,6 +4555,7 @@ int main(void)
 									ocpp_set_starttransaction_req(gun_index, ON);
 									ShmCharger->gun_info[gun_index].isCCSStartTransation = OFF;
 									setChargerMode(gun_index, SYS_MODE_CHARGING);
+									ftime(&startChargingTime[gun_index]);
 									ftime(&startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]);
 								}
 
@@ -4518,7 +4596,7 @@ int main(void)
 							setRelay(gun_index,ON);
 						ocpp_copy_userid_to_starttransaction(gun_index);
 						ocpp_set_starttransaction_req(gun_index, ON);
-
+						ftime(&startChargingTime[gun_index]);
 						setChargerMode(gun_index, SYS_MODE_CHARGING);
 					}
 
@@ -4580,7 +4658,7 @@ int main(void)
 					if(isModeChange(gun_index))
 					{
 						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_PROFILE_PREPARE]);
 						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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4736,6 +4814,7 @@ int main(void)
 										}
 										else
 										{
+											ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID;
 											ShmCharger->gun_info[gun_index].rfidReq = OFF;
 											ocpp_set_auth_req(OFF);
 											DEBUG_INFO("Authorize fail.\n");
@@ -4989,11 +5068,6 @@ int main(void)
 				case SYS_MODE_TERMINATING:
 					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)
 						{
 							setLedMotion(gun_index, LED_ACTION_STOP);
@@ -5005,6 +5079,12 @@ int main(void)
 						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
 					if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) ||
 					   (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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (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() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -5238,19 +5318,23 @@ int main(void)
 						setLedMotion(gun_index, LED_ACTION_STOP);
 						setRelay(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;
-
 				case SYS_MODE_ALARM:
 					setLedMotion(gun_index,LED_ACTION_ALARM);
 

BIN
EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin


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;
 }
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 	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;
 }
 
@@ -688,7 +726,7 @@ uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
-		{			
+		{
 			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, "Invalid")==0) ||
@@ -2880,7 +2918,7 @@ void checkTask()
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
 			}
-			
+
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			{
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
@@ -2895,7 +2933,7 @@ void checkTask()
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
 			}
-			
+
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			{
 				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)
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 			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)
 		{
 			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)
 		{
@@ -3280,12 +3330,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		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);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	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))
 		{
 			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)
 		{
 			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))
 		{
@@ -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);
 
-		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);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
@@ -3633,7 +3693,7 @@ int main(void)
 						// Set max current to 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.InternetDisconnectViaWiFi = 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_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() && (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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4551,7 +4611,7 @@ int main(void)
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								DEBUG_WARN("Firmware upgrade fail.\n");
-								
+
 								sleep(5);
 								system("rm -rvf /mnt/* ");
 								close(wtdFd);

BIN
EVSE/Projects/AW-ChargeLab/Images/FactoryDefaultConfig.bin


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;
 }
 
-uint8_t ocpp_get_auth_result()
+uint8_t ocpp_get_auth_result(uint8_t gun_index)
 {
 	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;
 }
 
@@ -688,7 +726,7 @@ uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 		if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE"))
-		{			
+		{
 			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, "Invalid")==0) ||
@@ -2880,7 +2918,7 @@ void checkTask()
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
 			}
-			
+
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
 			{
 				DEBUG_INFO("OcppBackend not running, restart it.\n");
@@ -2895,7 +2933,7 @@ void checkTask()
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
 			}
-			
+
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
 			{
 				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)
 	{
+		memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		if(!ocpp_get_starttransaction_result(gun_index))
 		{
 			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)
 		{
 			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)
 		{
@@ -3280,12 +3330,12 @@ void checkStopReason(uint8_t gun_index)
 		}
 		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);
 		ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 	}
 	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))
 		{
 			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)
 		{
 			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))
 		{
@@ -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);
 
-		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);
 		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
 	}
@@ -3633,7 +3693,7 @@ int main(void)
 						// Set max current to 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.InternetDisconnectViaWiFi = 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_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() && (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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!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_FREE)))
 									{
-										if(ocpp_get_auth_result() ||
+										if(ocpp_get_auth_result(gun_index) ||
 										   (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
 										   (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -4551,7 +4611,7 @@ int main(void)
 								sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed");
 								ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 								DEBUG_WARN("Firmware upgrade fail.\n");
-								
+
 								sleep(5);
 								system("rm -rvf /mnt/* ");
 								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);
 
 	// 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
 	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_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) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!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_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) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST)) ||
 										   (!ShmOCPP16Data->OcppConnStatus && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
@@ -3530,6 +3532,7 @@ int main(void)
 						sleep(3);
 					}
 
+					memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 					if(ShmOCPP16Data->MsMsg.bits.ResetReq)
 					{
 						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)
 					{
 						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)
 					{
@@ -3553,6 +3567,10 @@ int main(void)
 					{
 						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
 					{
 						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);
 
-					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);
-					
 					ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON;
 					ShmCharger->gun_info[gun_index].rfidReq = 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           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
+	unsigned char			StopChargingByButton;		//0: Disable  1: Enable
 };
 
 struct ChargingInfoData
@@ -3833,7 +3834,7 @@ struct LedModuleData
 /**************************************************************************************/
 struct StructIdTagInfo
 {
-	unsigned char 	ExpiryDate[28];
+	unsigned char 	ExpiryDate[36];
 	unsigned char 	ParentIdTag[21];
 	unsigned char 	Status[16];		//Accepted, Blocked, Expired, Invalid, ConcurrentTx
 };
@@ -3904,7 +3905,7 @@ struct StructSampledValue
 };
 struct StructMeterValue
 {
-	unsigned char 				TimeStamp[28];
+	unsigned char 				TimeStamp[36];
 	struct StructSampledValue	SampledValue[20];
 };
 struct StructConfigurationKeyItems
@@ -3926,7 +3927,7 @@ struct StructChargingSchedulePeriod
 struct StructChargingSchedule
 {
 	int											Duration;
-	unsigned char 								StartSchedule[28];
+	unsigned char 								StartSchedule[36];
 	unsigned char 								ChargingRateUnit[4];		//A, W
 	struct StructChargingSchedulePeriod			ChargingSchedulePeriod[10];
 	float 										MinChargingRate;			//0.1;
@@ -3939,8 +3940,8 @@ struct StructChargingProfile
 	unsigned char 					ChargingProfilePurpose[24];	//ChargePointMaxProfile, TxDefaultProfile, TxProfile
 	unsigned char 					ChargingProfileKind[12];		//Absolute, Recurring, Relative
 	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;
 };
 
@@ -3956,13 +3957,13 @@ struct StructBootNotification
 	unsigned char CpMeterType[25];			//meterType
 	unsigned char CpMeterSerialNumber[25];	//meterSerialNumber
 	unsigned char ResponseStatus[16];			//Accepted, Pending, Rejected
-	unsigned char ResponseCurrentTime[28];	//currentTime					//mandatory
+	unsigned char ResponseCurrentTime[36];	//currentTime					//mandatory
 	int 			ResponseHeartbeatInterval;	//interval						//mandatory
 
 };
 struct StructHeartbeat
 {
-	unsigned char 				ResponseCurrentTime[28];
+	unsigned char 				ResponseCurrentTime[36];
 };
 struct StructAuthorize
 {
@@ -3975,7 +3976,7 @@ struct StructStartTransaction
 	unsigned char 				IdTag[21];
 	int 						MeterStart;
 	int 						ReservationId;
-	unsigned char 				Timestamp[28];
+	unsigned char 				Timestamp[36];
 	struct StructIdTagInfo		ResponseIdTagInfo;
 	int 						ResponseTransactionId;
 };
@@ -3983,7 +3984,7 @@ struct StructStopTransaction
 {
 	unsigned char 				IdTag[21];
 	int 						MeterStop;
-	unsigned char 				Timestamp[28];
+	unsigned char 				Timestamp[36];
 	int 						TransactionId;
 	unsigned char 				StopReason[20];				/*	"EmergencyStop",
 															"EVDisconnected",
@@ -4034,7 +4035,7 @@ struct StructStatusNotification
 								                "Faulted"
 								            */
 
-	unsigned char 	Timestamp[28];
+	unsigned char 	Timestamp[36];
 	unsigned char 	VendorId[256];
 	unsigned char 	VendorErrorCode[50];
 };
@@ -4094,7 +4095,7 @@ struct StructGetCompositeSchedule
 	unsigned char					ChargingRateUnit[4];		//A,W
 	unsigned char 					ResponseStatus[12];			//Accepted,Rejected
 	int 							ResponseConnectorId;
-	unsigned char					ResponseScheduleStart[28];
+	unsigned char					ResponseScheduleStart[36];
 	struct StructChargingSchedule	ResponseChargingSchedule;
 };
 struct StructGetConfiguration
@@ -4109,8 +4110,8 @@ struct StructGetDiagnostics
 	unsigned char 			Location[256];
 	int 					Retries;
 	int						RetryInterval;
-	unsigned char 			StartTime[28];
-	unsigned char 			StopTime[28];
+	unsigned char 			StartTime[36];
+	unsigned char 			StopTime[36];
 	unsigned char 			ResponseFileName[256];
 };
 struct StructGetLocalListVersion
@@ -4139,7 +4140,7 @@ struct StructRemoteStopTransaction
 struct StructReserveNow
 {
 	int			 		ConnectorId;
-	unsigned char 		ExpiryDate[28];
+	unsigned char 		ExpiryDate[36];
 	unsigned char 		IdTag[21];
 	unsigned char 		ParentIdTag[21];
 	int					ReservationId;
@@ -4188,7 +4189,7 @@ struct StructUpdateFirmware
 {
 	unsigned char 		Location[256];
 	int					Retries;
-	unsigned char 		RetrieveDate[28];
+	unsigned char 		RetrieveDate[36];
 	int 				RetryInterval;
 };
 
@@ -4211,7 +4212,7 @@ struct OCPP16ConfigurationTable
 
 struct StrcutSetUserPrice
 {
-    unsigned char   idToken[20];
+    unsigned char   idToken[21];
     unsigned char   price[256];
 };
 
@@ -4239,15 +4240,15 @@ struct CertificateHashDataType
 struct LogParametersType
 {
 	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
 {
 	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 signature[801];									// Optional. Base64 encoded firmware signature.
 };
@@ -4525,7 +4526,7 @@ struct OCPP16Data
 /*
  * =============== Enum variable content ===============
  */
-enum AlignedDataCtrlrVariable
+enum OCPP20CtrlrVariable
 {
 	AlignedDataCtrlr_Enabled=0,
 	AlignedDataCtrlr_Available,
@@ -4623,6 +4624,7 @@ enum AlignedDataCtrlrVariable
 	SecurityCtrlr_CertificateEntries,
 	SecurityCtrlr_SecurityProfile,
 	SecurityCtrlr_AdditionalRootCertificateCheck,
+	SecurityCtrlr_MaxCertificateChainSize,
 	SmartChargingCtrlr_Enabled,
 	SmartChargingCtrlr_Available,
 	SmartChargingCtrlr_ACPhaseSwitchingSupported,
@@ -5079,6 +5081,11 @@ struct TransactionType
 	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 ===============
  */
@@ -5108,9 +5115,10 @@ struct CancelReservation_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 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
 };
 
@@ -5219,7 +5227,7 @@ struct GetCertificateStatus_20
 {
 	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_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
@@ -5318,7 +5326,7 @@ struct Heartbeat_20
 struct InstallCertificate_20
 {
 	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 guid[37];											// Save guid from server request
 };
@@ -5541,9 +5549,10 @@ struct SetVariables_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 Response_status[16];								// Required. Specifies whether the CSMS can process the request.
+	struct StatusInfoType Response_statusInfo;						// Optional. Detailed status information.
 };
 
 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 tock.stdtime.gov.tw &
 /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_PhBackend
 Module_InitUpgrade
+Module_Payment

BIN
EVSE/rootfs/root/Module_Payment


BIN
EVSE/rootfs/root/OcppBackend20


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

@@ -119,7 +119,7 @@
 		break;
 	}
 	if(substr($model,4,3)=="122"){
-		$am120='block';
+		$am120='none';
 	}
 	else{
 		$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">
 											<small class="form-text text-muted-red"><label id="MaxChargingDurationText" style="display:none;">'0' means unlimit</label></small>
 										</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">
 											<label>AC Max Charging Current</label>
 											<small class="form-text text-muted-red">amp</small>
@@ -1451,6 +1458,7 @@ img {
 						"&MaxChargingCurrent=" + document.getElementById("MaxChargingCurrent").value+
 						"&AcMaxChargingCurrent=" + document.getElementById("AcMaxChargingCurrent").value+
 						"&MaxChargingDuration=" + document.getElementById("MaxChargingDuration").value+
+						"&StopChargingByButton=" + document.getElementById("StopChargingByButton").value+
 						"&LocalWhiteCard0=" + document.getElementById("LocalWhiteCard0").value+
 						"&LocalWhiteCard1=" + document.getElementById("LocalWhiteCard1").value+
 						"&LocalWhiteCard2=" + document.getElementById("LocalWhiteCard2").value+

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

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

Неке датотеке нису приказане због велике количине промена