瀏覽代碼

[Add][Modularization][Module_Firewall]

2022.12.09 / Folus Wen

Actions:
1. Add Module_Firewall.
2. define.h add firewall configuration to SysConfig.

Files:
1. As follow commit history

Image version: V0.01.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
Folus Wen 2 年之前
父節點
當前提交
47974da100

+ 343 - 0
EVSE/Modularization/Firewall/Module_Firewall.c

@@ -0,0 +1,343 @@
+/*
+ * Module_Firewall.c
+ *
+ *  Created on: 2022/12/9
+ *      Author: folus
+ */
+#include	"yuarel.h"
+#include	"define.h"
+
+enum
+{
+	TMR_IDX_CONFIG,
+	TMR_IDX_CNT
+};
+
+#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 YES								1
+#define NO								0
+#define ON								1
+
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+
+struct timespec					tmr[TMR_IDX_CNT];
+uint8_t 						natInterface = 0;
+
+struct FirewallPresentSetting
+{
+	unsigned char			isEnalbleFirewall;					// 0: Disable	1: Enable
+	unsigned char			FirewallAcceptAddr[10][128];		// Max accepted server address is 10
+}firewallPresentInfo;
+
+/**
+ *
+ * @param fmt
+ * @return
+ */
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	va_list args;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	CurrentTime = time(NULL);
+	tm=localtime(&CurrentTime);
+	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]Firewall_SystemLog",
+			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
+			buffer,
+			tm->tm_year+1900,tm->tm_mon+1);
+#ifdef SystemLogMessage
+	system(Buf);
+#endif
+
+#ifdef ConsloePrintLog
+	printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer);
+#endif
+
+	return rc;
+}
+
+/**
+ *
+ * @return
+ */
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//creat 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
+    {}
+
+   	 //creat 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
+    {}
+
+    return result;
+}
+
+/**
+ *
+ * @param cmd
+ * @return
+ */
+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;
+}
+
+/**
+ *
+ * @param timer
+ */
+void refreshStartTimer(struct timespec *timer)
+{
+	clock_gettime(CLOCK_MONOTONIC, timer);
+}
+
+/**
+ *
+ * @param timer
+ * @return
+ */
+int getDiffSecNow(struct timespec timer)
+{
+	struct timespec timerNow;
+
+	clock_gettime(CLOCK_MONOTONIC, &timerNow);
+
+	return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
+}
+
+/**
+ *
+ * @return
+ */
+unsigned int isKernelSupportNAT()
+{
+	unsigned int result = NO;
+	unsigned int version = 0;
+	FILE *fp;
+	char cmd[256];
+	char buf[512];
+
+	// Get IP address & net mask
+	strcpy(cmd, "uname -v");
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		if(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			sscanf(buf, "#%d", &version);
+			//DEBUG_INFO("Kernel version: %d\n", version);
+
+			if(version >= 30)
+				result = YES;
+		}
+	}
+	pclose(fp);
+
+	return result;
+}
+
+/**
+ *
+ * @return
+ */
+int firewallConfig()
+{
+	struct yuarel url;
+	char urlBuf[512] = {0};
+	char cmdBuf[512] = {0};
+
+	runShellCmd("/sbin/iptables -F");
+
+	if(ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall)
+	{
+		// Other address mandatory configure
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 192.168.0.0/255.255.0.0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 8.8.8.8/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 180.76.76.76/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d evsocket.phihong.com.tw/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ocpp.phihong.com.tw/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ftp.phihong.com.tw/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d time.windows.com/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d cn.ntp.org.cn/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d tock.stdtime.gov.tw/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 0.europe.pool.ntp.org/255.255.255.255 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d curl.haxx.se/255.255.255.255 -j ACCEPT");
+
+		runShellCmd("/sbin/iptables -A INPUT -p all -s 192.168.0.0/255.255.0.0 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s 8.8.8.8/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s 180.76.76.76/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s evsocket.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s ocpp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s ftp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s time.windows.com/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s cn.ntp.org.cn/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s tock.stdtime.gov.tw/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s 0.europe.pool.ntp.org/255.255.255.255 -d any/0 -j ACCEPT");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s curl.haxx.se/255.255.255.255 -d any/0 -j ACCEPT");
+
+		// Back end server URL parse
+		if((ShmSysConfigAndInfo->SysConfig.OcppServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) )
+		{
+			memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL));
+			if(yuarel_parse(&url, urlBuf) != -1)
+			{
+				DEBUG_INFO("Add %s to allow rule.\n", url.host);
+				sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
+				runShellCmd(cmdBuf);
+				sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
+				runShellCmd(cmdBuf);
+			}
+		}
+
+		if((ShmSysConfigAndInfo->SysConfig.MaintainServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) )
+		{
+			memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.MaintainServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.MaintainServerURL));
+			if(yuarel_parse(&url, urlBuf) != -1)
+			{
+				DEBUG_INFO("Add %s to allow rule.\n", url.host);
+				sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
+				runShellCmd(cmdBuf);
+				sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
+				runShellCmd(cmdBuf);
+			}
+		}
+
+		// User custom configure address
+		for(uint8_t idx=0;idx<ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr);idx++)
+		{
+			if(strlen((char*)ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]) > 0)
+			{
+				DEBUG_INFO("Add %s to allow rule.\n", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
+				sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
+				runShellCmd(cmdBuf);
+				sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
+				runShellCmd(cmdBuf);
+			}
+		}
+
+		// Deny any address
+		runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d any/0 -j DROP");
+		runShellCmd("/sbin/iptables -A INPUT -p all -s any/0 -d any/0 -j DROP");
+
+		// List present rule
+		runShellCmd("/sbin/iptables -L -n");
+	}
+
+	return PASS;
+}
+
+/**
+ *
+ * @return
+ */
+int isChangeConfiguration()
+{
+	int result = NO;
+
+	if((firewallPresentInfo.isEnalbleFirewall != ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall) ||
+		(memcmp(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0])) != 0))
+	{
+
+		firewallPresentInfo.isEnalbleFirewall = ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall;
+		memcpy(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0]));
+
+		result = YES;
+	}
+	return result;
+}
+
+
+/**
+ *
+ * @return
+ */
+int main(void)
+{
+	//==========================================
+	//Initialization share memory
+	//==========================================
+	if(InitShareMemory() == FAIL)
+	{
+		DEBUG_ERROR("InitShareMemory NG\n");
+
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
+		}
+		sleep(5);
+
+		return 0;
+	}
+	DEBUG_INFO("Module_Firewall version: V0.01\n");
+	DEBUG_INFO("Module_Firewall initialized...\n");
+
+	for(;;)
+	{
+		if(isChangeConfiguration())
+		{
+			DEBUG_INFO("Firewall rule changed.\n");
+			sleep(3);
+			firewallConfig();
+		}
+
+		usleep(100000);
+	}
+
+	return -1;
+}

+ 270 - 0
EVSE/Modularization/Firewall/yuarel.c

@@ -0,0 +1,270 @@
+/*
+ * yuarel.c
+ *
+ *  Created on: 2022/12/9
+ *      Author: folus
+ */
+#include "yuarel.h"
+
+/**
+ * Parse a non null terminated string into an integer.
+ *
+ * str: the string containing the number.
+ * len: Number of characters to parse.
+ */
+static inline int natoi(const char *str, size_t len)
+{
+	int i, r = 0;
+	for (i = 0; i < len; i++) {
+		r *= 10;
+		r += str[i] - '0';
+	}
+
+	return r;
+}
+
+/**
+ * Check if a URL is relative (no scheme and hostname).
+ *
+ * url: the string containing the URL to check.
+ *
+ * Returns 1 if relative, otherwise 0.
+ */
+static inline int is_relative(const char *url)
+{
+	return (*url == '/') ? 1 : 0;
+}
+
+/**
+ * Parse the scheme of a URL by inserting a null terminator after the scheme.
+ *
+ * str: the string containing the URL to parse. Will be modified.
+ *
+ * Returns a pointer to the hostname on success, otherwise NULL.
+ */
+static inline char *parse_scheme(char *str)
+{
+	char *s;
+
+	/* If not found or first in string, return error */
+	s = strchr(str, ':');
+	if (s == NULL || s == str) {
+		return NULL;
+	}
+
+	/* If not followed by two slashes, return error */
+	if (s[1] == '\0' || s[1] != '/' || s[2] == '\0' || s[2] != '/') {
+		return NULL;
+	}
+
+	*s = '\0'; // Replace ':' with NULL
+
+	return s + 3;
+}
+
+/**
+ * Find a character in a string, replace it with '\0' and return the next
+ * character in the string.
+ *
+ * str: the string to search in.
+ * find: the character to search for.
+ *
+ * Returns a pointer to the character after the one to search for. If not
+ * found, NULL is returned.
+ */
+static inline char *find_and_terminate(char *str, char find)
+{
+	str = strchr(str, find);
+	if (NULL == str) {
+		return NULL;
+	}
+
+	*str = '\0';
+	return str + 1;
+}
+
+/* Yes, the following functions could be implemented as preprocessor macros
+     instead of inline functions, but I think that this approach will be more
+     clean in this case. */
+static inline char *find_fragment(char *str)
+{
+	return find_and_terminate(str, '#');
+}
+
+static inline char *find_query(char *str)
+{
+	return find_and_terminate(str, '?');
+}
+
+static inline char *find_path(char *str)
+{
+	return find_and_terminate(str, '/');
+}
+
+/**
+ * Parse a URL string to a struct.
+ *
+ * url: pointer to the struct where to store the parsed URL parts.
+ * u:   the string containing the URL to be parsed.
+ *
+ * Returns 0 on success, otherwise -1.
+ */
+int yuarel_parse(struct yuarel *url, char *u)
+{
+	if (NULL == url || NULL == u) {
+		return -1;
+	}
+
+	memset(url, 0, sizeof (struct yuarel));
+
+	/* (Fragment) */
+	url->fragment = find_fragment(u);
+
+	/* (Query) */
+	url->query = find_query(u);
+
+	/* Relative URL? Parse scheme and hostname */
+	if (!is_relative(u)) {
+		/* Scheme */
+		url->scheme = u;
+		u = parse_scheme(u);
+		if (u == NULL) {
+			return -1;
+		}
+
+		/* Host */
+		if ('\0' == *u) {
+			return -1;
+		}
+		url->host = u;
+
+		/* (Path) */
+		url->path = find_path(u);
+
+		/* (Credentials) */
+		u = strchr(url->host, '@');
+		if (NULL != u) {
+			/* Missing credentials? */
+			if (u == url->host) {
+				return -1;
+			}
+
+			url->username = url->host;
+			url->host = u + 1;
+			*u = '\0';
+
+			u = strchr(url->username, ':');
+			if (NULL == u) {
+				return -1;
+			}
+
+			url->password = u + 1;
+			*u = '\0';
+		}
+
+		/* Missing hostname? */
+		if ('\0' == *url->host) {
+			return -1;
+		}
+
+		/* (Port) */
+		u = strchr(url->host, ':');
+		if (NULL != u && (NULL == url->path || u < url->path)) {
+			*(u++) = '\0';
+			if ('\0' == *u) {
+				return -1;
+			}
+
+			if (url->path) {
+				url->port = natoi(u, url->path - u - 1);
+			} else {
+				url->port = atoi(u);
+			}
+		}
+
+		/* Missing hostname? */
+		if ('\0' == *url->host) {
+			return -1;
+		}
+	} else {
+		/* (Path) */
+		url->path = find_path(u);
+	}
+
+	return 0;
+}
+
+/**
+ * Split a path into several strings.
+ *
+ * No data is copied, the slashed are used as null terminators and then
+ * pointers to each path part will be stored in **parts. Double slashes will be
+ * treated as one.
+ *
+ * path: the path to split.
+ * parts: a pointer to an array of (char *) where to store the result.
+ * max_parts: max number of parts to parse.
+ */
+int
+yuarel_split_path(char *path, char **parts, int max_parts)
+{
+	int i = 0;
+
+	if (NULL == path || '\0' == *path) {
+		return -1;
+	}
+
+	do {
+		/* Forward to after slashes */
+		while (*path == '/') path++;
+
+		if ('\0' == *path) {
+			break;
+		}
+
+		parts[i++] = path;
+
+		path = strchr(path, '/');
+		if (NULL == path) {
+			break;
+		}
+
+		*(path++) = '\0';
+	} while (i < max_parts);
+
+	return i;
+}
+
+int
+yuarel_parse_query(char *query, char delimiter, struct yuarel_param *params, int max_params)
+{
+	int i = 0;
+
+	if (NULL == query || '\0' == *query) {
+		return -1;
+	}
+
+	params[i++].key = query;
+	while (i < max_params && NULL != (query = strchr(query, delimiter))) {
+		*query = '\0';
+		params[i].key = ++query;
+		params[i].val = NULL;
+
+		/* Go back and split previous param */
+		if (i > 0) {
+			if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL) {
+				*(params[i - 1].val)++ = '\0';
+			}
+		}
+		i++;
+	}
+
+	/* Go back and split last param */
+	if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL) {
+		*(params[i - 1].val)++ = '\0';
+	}
+
+	return i;
+}
+
+

+ 63 - 0
EVSE/Modularization/Firewall/yuarel.h

@@ -0,0 +1,63 @@
+/*
+ * yuarel.h
+ *
+ *  Created on: 2022/12/9
+ *      Author: folus
+ */
+
+#ifndef YUAREL_H_
+#define YUAREL_H_
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+#include	<dirent.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	<stdbool.h>
+#include	<stddef.h>
+#include	<stdint.h>
+
+struct yuarel {
+	char *scheme; /* scheme, without ":" and "//" */
+	char *username; /* username, default: NULL */
+	char *password; /* password, default: NULL */
+	char *host; /* hostname or IP address */
+	int port; /* port, default: 0 */
+	char *path; /* path, without leading "/", default: NULL */
+	char *query; /* query, default: NULL */
+	char *fragment; /* fragment, default: NULL */
+};
+
+/* A struct to hold the query string parameter values. */
+struct yuarel_param {
+	char *key;
+	char *val;
+};
+extern int yuarel_parse(struct yuarel *url, char *url_str);
+extern int yuarel_split_path(char *path, char **parts, int max_parts);
+extern int yuarel_parse_query(char *query, char delimiter, struct yuarel_param *params, int max_params);
+
+
+#endif /* YUAREL_H_ */

+ 8 - 2
EVSE/Modularization/Makefile

@@ -7,8 +7,8 @@ Lib_RatedCurrentLib = "-L./" -lm -lModule_RatedCurrent
 Lib_Xml = "-L../GPL/libxml2-2.7.6/release/lib" -lxml2
 Lib_Openssl = "-L../GPL/openssl-1.1.1n/release/lib" -lssl
 
-all: clean Module_RFIDLib Module_SystexLib Infypwr_PsuCommObj Phihong_PsuCommObj Module_RatedCurrentLib Module_UpgradeLib UUpwr_PsuCommObj\
-     Module_Wifi Module_4g WebServiceLib Module_EventLogging Module_ProduceUtils Module_DcMeter Module_PowerSharing_Task \
+all: clean Module_RFIDLib Module_SystexLib Infypwr_PsuCommObj Phihong_PsuCommObj Module_RatedCurrentLib Module_UpgradeLib UUpwr_PsuCommObj \
+     Module_Wifi Module_4g WebServiceLib Module_EventLogging Module_ProduceUtils Module_DcMeter Module_PowerSharing_Task Module_Firewall \
      Ocpp16 Ocpp20 Ocppph \
      Module_Payment Module_Payment_Bazel8 Module_Payment_Enegate
 
@@ -199,4 +199,10 @@ Module_PowerSharing_Task:
 	rm -f *.o
 	mv -f Module_PowerSharing ../rootfs/root
 
+Module_Firewall:
+	@echo "===== Module_Firewall_Task ======================================="
+	rm -f Module_Firewall
+	$(CC) -D $(Project) "-I../Projects" -O0  -Wall -fmessage-length=0 ./Firewall/Module_Firewall.c ./Firewall/yuarel.c -lrt -o Module_Firewall
+	rm -f *.o
+	mv -f Module_Firewall ../rootfs/root
 

+ 39 - 0
EVSE/Projects/AX80/Apps/Module_ConfigTools.c

@@ -600,6 +600,8 @@ int main(void)
 			printf("\n  teleapn: Telecomm APN.");
 			printf("\n  teleid: Telecomm login id.");
 			printf("\n  telepwd: Telecomm login password.");
+			printf("\n  firewallEnable: Firewall enable/disable.");
+			printf("\n  firewallRule: Firewall accepted list.");
 			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
 			scanf("%s", &cmd[0]);
@@ -788,6 +790,43 @@ int main(void)
 					DEBUG_INFO("Telecomm CHAP password: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd);
 				}
 			}
+			else if(strcmp(cmd, "firewallEnable") == 0)
+			{
+				memset(cmd, 0x00, ARRAY_SIZE(cmd));
+				printf("\n ***** firewallEnable *****************************");
+				printf("\n  Current firewall mode: %d", ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall);
+				printf("\n  0: Disable.");
+				printf("\n  1: Enable.");
+				printf("\n **************************************************");
+				printf("\n  Please input firewall mode: ");
+				scanf("%s", &cmd[0]);
+
+				ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd):0);
+				if(ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall)
+					DEBUG_INFO("Firewall mode: Enable\n");
+				else
+					DEBUG_INFO("Firewall mode: Disable\n");
+			}
+			else if(strcmp(cmd, "firewallRule") == 0)
+			{
+				memset(cmd, 0x00, ARRAY_SIZE(cmd));
+				printf("\n ***** firewallRule ************************************");
+				for(uint8_t idx=0;idx<ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr);idx++)
+					printf("\n %d Accepted address-%d: %s", idx, idx, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
+
+				printf("\n **************************************************");
+				printf("\n  Please select item change: ");
+				scanf("%s", &cmd[0]);
+
+				uint8_t idxList = atoi(cmd);
+				printf("\n Please input accepted address: ");
+				scanf("%s", &cmd[0]);
+
+				memset(&ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idxList], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idxList]));
+				strcpy((char*)&ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idxList], (char*)&cmd[0]);
+				DEBUG_INFO("Input accepted address-%d: %s\n", idxList, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idxList]);
+
+			}
 		}
 		else if(strcmp(cmd, "test") == 0)
 		{

+ 3 - 1
EVSE/Projects/define.h

@@ -612,7 +612,9 @@ struct SysConfigData
     unsigned int            PowerSharingCapacityPower;          // Local power sharing capacity power
     unsigned char           MaxChargingSoc;                     // 0: unlimit, 1 ~ 100 percent
     unsigned char			FanControlPolicy;					// 0: Auto mode		1: Quite mode
-	unsigned short			MaxChargingVoltage;					//0: rating value, 1 ~ RATING_VOLTAGE	volt
+	unsigned short			MaxChargingVoltage;					// 0: rating value, 1 ~ RATING_VOLTAGE	volt
+	unsigned char			isEnalbleFirewall;					// 0: Disable	1: Enable
+	unsigned char			FirewallAcceptAddr[10][128];		// Max accepted server address is 10
 };
 
 struct DERATING_BY_OTP

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

@@ -14,3 +14,4 @@ Module_Payment_Bazel8
 Module_DcMeter
 Module_PowerSharing
 Module_Payment_Enegate
+Module_Firewall