From be87219889d0fbfda9bc35c1cd98e8cf4d1485ed Mon Sep 17 00:00:00 2001
From: "nevadita.chatterjee" <nevadita.chatterjee@iopsys.eu>
Date: Tue, 9 Mar 2021 17:18:19 +0530
Subject: [PATCH] map-topology: Adding code for the host drop 2

---
 src/host.c          | 322 +++++++++++++++++++++++++++++++++++++++++---
 src/host.h          |  10 +-
 src/host_config.c   | 143 ++++++++++++--------
 src/host_config.h   |   7 +-
 src/topo_ieee1905.c |   4 +
 src/topologyd.c     |   5 +
 src/topologyd.h     |   1 +
 7 files changed, 410 insertions(+), 82 deletions(-)

diff --git a/src/host.c b/src/host.c
index 1283a3d..6baeba7 100644
--- a/src/host.c
+++ b/src/host.c
@@ -137,7 +137,7 @@ void host_dump_node_nbr(struct topologyd_private *priv, struct blob_buf *b)
 	blobmsg_close_array(b, nodes_array);
 }
 
-int host_topo_node_init(struct topologyd_private *priv, uint8_t *mac_addr)
+struct host_node* host_topo_node_init(struct topologyd_private *priv, uint8_t *mac_addr)
 {
 	struct host_node *p = NULL;
 	char mac_str[18] = { 0 };
@@ -175,7 +175,7 @@ int host_topo_node_init(struct topologyd_private *priv, uint8_t *mac_addr)
 		strftime(str_tm, sizeof(str_tm), "%Y-%m-%dT%H:%M:%S", info);
 		config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
 	}
-	return 0;
+	return p;
 }
 
 int host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_t *mac_addr)
@@ -185,7 +185,7 @@ int host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_
 	time_t tmp_t;
 	struct tm *info;
 	char str_tm[20];
-	int ret = 0;
+	int ret = 0, i = 0;
 
 	dbg("Inside %s %d \n", __func__, __LINE__);
 
@@ -216,6 +216,7 @@ int host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_
 			if (p == NULL)
 				return -1;
 		}
+		p->is_ieee1905_node = 1;
 		p->active = 1;
 		p->active_last_change = time(NULL);
 		//here we need to write  this info in the config file
@@ -243,6 +244,7 @@ int host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_
 			if (p == NULL)
 				return -1;
 		}
+		p->is_ieee1905_node = 0;
 		if (p->active != 1) {
 			p->active = 1;
 			p->active_last_change = time(NULL);
@@ -256,18 +258,39 @@ int host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_
 			config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
 			//Here Adding the ipv4 address and hostname and ipv6 address
 		}
-		ret = host_get_interface_type(priv, mac_str, p); 
+		ret = host_get_interface_type(priv, p); 
 		if (ret != 0)
                         err("Unable to fetch interface type \n");
 		if (p->intf_type == HOST_TYPE_WIFI)
 			config_set_host_option("hosts", "host", "macaddr", mac_str, "interface_type", "wifi");
 		else if (p->intf_type == HOST_TYPE_ETHER)
 			config_set_host_option("hosts", "host", "macaddr", mac_str, "interface_type", "eth");
+
+		//Here we need to rest the ipv4 and ipv6 list in the config 
+		//before adding to config again
+		for (i = 0; i < p->ipv4addr_count; i++) {
+                        config_del_host_list("hosts", "host", "macaddr", mac_str, "ipv4address", p->ipv4addr_list[i]);
+                }
+                for (i = 0; i < p->ipv6addr_count; i++) {
+                        config_del_host_list("hosts", "host", "macaddr", mac_str, "ipv6address", p->ipv6addr[i]);
+                }
+
 		ret = host_get_ipaddr_hostname(mac_str, p);
-                if (ret != 0)
+                if (ret != 0) {
                         err("Unable to fetch ip adddress and host name \n");
-                config_set_host_option("hosts", "host", "macaddr", mac_str, "ipaddress", p->ipv4addr);
-                config_set_host_option("hosts", "host", "macaddr", mac_str, "hostname", p->hostname);
+			p->is_ipaddr = 0;
+		} else {
+			p->is_ipaddr = 1;
+                	config_set_host_option("hosts", "host", "macaddr", mac_str, "ipaddress", p->ipv4addr);
+                	config_set_host_option("hosts", "host", "macaddr", mac_str, "hostname", p->hostname);
+
+			for (i = 0; i < p->ipv4addr_count; i++) {
+				config_set_host_list("hosts", "host", "macaddr", mac_str, "ipv4address", p->ipv4addr_list[i]);
+			}
+			for (i = 0; i < p->ipv6addr_count; i++) {
+                        	config_set_host_list("hosts", "host", "macaddr", mac_str, "ipv6address", p->ipv6addr[i]);
+                	}
+		}
 	}
 	return ret;
 }
@@ -417,7 +440,7 @@ int host_get_ipaddr_hostname(char *macaddr_str, struct host_node *p)
         int hw, flag;
         char mask[256];
         int i, j;
-	int ret = 1;
+	int ret = -1;
 	char macaddr[18]; 
         char ip_addr[24];
 	char device[16];
@@ -425,7 +448,7 @@ int host_get_ipaddr_hostname(char *macaddr_str, struct host_node *p)
 	//char ip6addr[128];
 
 
-	dbg("Inside %s %d \n", __func__, __LINE__);
+	dbg("Inside %s %d mac=[%s]\n", __func__, __LINE__, macaddr_str);
 
         // Walk through ARP table to get the ip address
         arpt = fopen("/proc/net/arp", "r");
@@ -503,7 +526,8 @@ out_str:
         free(json_str);
 }
 
-static int host_get_assoclist(struct topologyd_private *priv, char *intf_name, struct host_node *p)
+static int host_get_assoclist(struct topologyd_private *priv, 
+		char *intf_name, struct host_node *p)
 {
         struct blob_buf bb = {};
         int ret;
@@ -519,14 +543,26 @@ static int host_get_assoclist(struct topologyd_private *priv, char *intf_name, s
                 err("object '%s' not present!\n", intf_name);
                 return OBJECT_INVALID;
         }
-
-        ret = ubus_invoke(priv->ctx, id, "assoclist", bb.head,
-                                       host_list_stas, p, 2 * 1000);
-        if (ret) {
-                dbg("Failed to get assoclist (ret = %d)\n", ret);
-                blob_buf_free(&bb);
-                return -1;
-        }
+	
+	if ( p != NULL) {
+        	ret = ubus_invoke(priv->ctx, id, "assoclist", bb.head,
+                	                       host_list_stas, p, 2 * 1000);
+        	if (ret) {
+                	dbg("Failed to get assoclist (ret = %d)\n", ret);
+                	blob_buf_free(&bb);
+                	return -1;
+        	}
+	} 
+#if 0
+	else {
+		ret = ubus_invoke(priv->ctx, id, "assoclist", bb.head,
+                                               host_init_stas, mac_addr, 2 * 1000);
+                if (ret) {
+                        dbg("Failed to get assoclist (ret = %d)\n", ret);
+                        blob_buf_free(&bb);
+                        return -1;	
+	}
+#endif
         blob_buf_free(&bb);
         return 0;
 }
@@ -612,11 +648,15 @@ void host_wifi_sta_event_handler(void *c, struct blob_attr *msg)
 	}
 }
 
-int host_get_interface_type(struct topologyd_private *priv, char *mac_str, struct host_node *p)
+int host_get_interface_type(struct topologyd_private *priv, struct host_node *p)
 {
 	struct u_list c;
 	int i = 0;
 	int ret = 0;
+	char mac_str[18] = { 0 };
+        time_t tmp_t;
+        struct tm *info;
+        char str_tm[20];
 
 	host_get_wifi_nodes(priv->ctx, &c);
 	
@@ -627,12 +667,254 @@ int host_get_interface_type(struct topologyd_private *priv, char *mac_str, struc
                         err("Unable to get the assoclist \n");
 			return -1;
 		}
-		if (p->intf_type == HOST_TYPE_WIFI)
+		if (p->intf_type == HOST_TYPE_WIFI) {
+#if 0
+			if (p->active == 0) {
+				p->active = 1;
+                        	p->active_last_change = time(NULL);
+                        	//here we need to write this info in the config file
+                        	hwaddr_ntoa(p->hwaddr, mac_str);
+                        	config_add_default_host_mac("hosts", "host", mac_str);
+                        	config_set_host_option("hosts", "host", "macaddr", mac_str, "active", "1");
+                        	tmp_t = p->active_last_change;
+                        	info = localtime(&tmp_t);
+                       		strftime(str_tm, sizeof(str_tm), "%Y-%m-%dT%H:%M:%S", info);
+                        	config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
+			}
+#endif
 			break;
+		}
 	}
 	return ret;
 }
+
+/*Here the host periodic refresh timer does as below:
+ * 1. run the topology refresh algo such that all the new 
+ *    non -1905 neighbors can be fetched
+ * 2. Check all the nodes of type ETHER and get there status 
+ *    from the arp table.
+ */
+void host_periodic_refresh(struct uloop_timeout *t)
+{
+        struct topologyd_private *priv =
+                container_of(t, struct topologyd_private, host_refresh_timer);
+
+        dbg("Refresh host topology...\n");
+
+        //topologyd_algo_run(priv);
+	/*here we send the topology query to selfnode each*/
+        /*time the algo runs to keep self node updated */
+	topologyd_send_ieee1905_topology_query(priv, NULL);
+	host_run_status_check(priv);
+        uloop_timeout_set(&priv->host_refresh_timer, HOST_REFRESH_TIMER * 1000);
+}
+
+int host_get_arping_status(char *ipaddr_str)
+{
+        char cmd[256] = {0};
+        FILE *fp = NULL;
+        char *line = NULL;
+        size_t len = 0;
+        int found = 0;
+	int ret = -1;
+
+        dbg("Inside %s %d \n", __func__, __LINE__);
+
+        if (ipaddr_str == NULL)
+                return NULL;
+
+        snprintf(cmd, 256, ARPING_CMD, ipaddr_str);
+
+        fp = popen(cmd, "r");
+        if (fp == NULL) {
+                err("unable to execute command");
+                return -1;
+        }
+
+        dbg("Inside %s %d command is %s\n", __func__, __LINE__, cmd);
+        while (getline(&line, &len, fp) != -1) {
+                if (len < 2) {
+                        free(line);
+                        len = 0;
+                        continue;
+                }
+		ret = strncmp(line, "1", 1);
+                break;
+        }
+	free(line);
+        pclose(fp);
+	return ret;
+}
+
+int host_get_neigh_status(uint8_t *mac_addr)
+{
+        char cmd[256] = {0};
+        FILE *fp = NULL;
+        char *line = NULL;
+        size_t len = 0;
+	char macaddr_str[18];
+	int found = 0;
+
+	dbg("Inside %s %d \n", __func__, __LINE__);
+
+        if (mac_addr == NULL)
+                return NULL;
+
+	hwaddr_ntoa(mac_addr, macaddr_str);
+        snprintf(cmd, 256, NEIGH_CMD, macaddr_str);
+
+        fp = popen(cmd, "r");
+        if (fp == NULL) {
+                err("unable to execute command");
+                return -1;
+        }
+
+	dbg("Inside %s %d command is %s\n", __func__, __LINE__, cmd);
+        while (getline(&line, &len, fp) != -1) {
+                if (len < 17) {
+                        free(line);
+                        len = 0;
+                        continue;
+                }
+		found = 1;
+		break;
+        }
+
+        free(line);
+        pclose(fp);
+
+	if (found == 0)
+		return -1;
+	else 
+        	return 0;
+}
+
+
+/*Here the below are checked for each host node in case of periodic run
+ * 1. If Ipaddress is fetched from dhcp lease
+ * 2. If node is eth then check reachable
+ * 3. If node is eth and not reachable do arping
+ */ 
+void host_run_status_check(struct topologyd_private *priv)	
+{
+        struct host_node *p;
+        int i = 0, ret = -1;
+	char mac_str[18] = { 0 };
+        time_t tmp_t;
+        struct tm *info;
+        char str_tm[20];
+
+        dbg("Inside %s %d \n", __func__, __LINE__);
+
+        for (i = 0; i < NODE_HTABLE_SIZE; i++) {
+                if (hlist_empty(&priv->host.node_htable[i]))
+                        continue;
+
+                hlist_for_each_entry(p, &priv->host.node_htable[i], hlist) {
+
+                        if (hwaddr_is_zero(p->hwaddr))  // TODO: unlikely..
+                                continue;
+
+			hwaddr_ntoa(p->hwaddr, mac_str);
+			/*Here we check if the node has received the
+                                 * ip adddress*/
+                        if (p->is_ipaddr == 0) {
+                                ret = host_get_ipaddr_hostname(mac_str, p);
+                                if (ret != 0)
+                                	err("Unable to fetch ip adddress and host name \n");
+				else {
+					p->is_ipaddr = 1;
+					config_set_host_option("hosts", "host", "macaddr", mac_str, "ipaddress", p->ipv4addr);
+                        		config_set_host_option("hosts", "host", "macaddr", mac_str, "hostname", p->hostname);
+
+                        		for (i = 0; i < p->ipv4addr_count; i++) {
+                                		config_set_host_list("hosts", "host", "macaddr", mac_str, "ipv4address", p->ipv4addr_list[i]);
+                        		}
+                        		for (i = 0; i < p->ipv6addr_count; i++) {
+                                		config_set_host_list("hosts", "host", "macaddr", mac_str, "ipv6address", p->ipv6addr[i]);
+                        		}
+				}
+			}
+			/*Here we check the status of the eth node in
+			 * the ip neigh */
+		        if (p->intf_type != HOST_TYPE_ETHER)
+		       		continue;
+
+			ret = host_get_neigh_status(p->hwaddr);
+			if (ret == 0) {
+				/*Here the node is rechable so 
+				 * active status is 1 */
+				dbg("ETH node is reachable " MACFMT "\n", MAC2STR(p->hwaddr));
+				if (p->active != 1) {
+                        		p->active = 1;
+                        		p->active_last_change = time(NULL);
+                        		//here we need to write this info in the config file
+                        		config_add_default_host_mac("hosts", "host", mac_str);
+                        		config_set_host_option("hosts", "host", "macaddr", mac_str, "active", "1");
+                        		tmp_t = p->active_last_change;
+                        		info = localtime(&tmp_t);
+                        		strftime(str_tm, sizeof(str_tm), "%Y-%m-%dT%H:%M:%S", info);
+                        		config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
+				}
+                	}
+			else {
+				/*Here as the status is not reachable
+			 	 * we need to do arping to the node 
+			 	 * to get the status and turn unreachable accordingly*/ 
+				char ipv4addr[24] = { 0 };
+				if(strncmp(p->ipv4addr, ipv4addr, 24)) {
+				ret = host_get_arping_status(p->ipv4addr);
+				if (ret != 0) {
+					dbg("ETH node is unreachable " MACFMT "\n", MAC2STR(p->hwaddr));
+					if (p->active != 0) {
+                        			p->active = 0;
+                                		p->active_last_change = time(NULL);
+                                		//here we need to write this info in the config file
+                                		config_add_default_host_mac("hosts", "host", mac_str);
+                                		config_set_host_option("hosts", "host", "macaddr", mac_str, "active", "0");
+                                		tmp_t = p->active_last_change;
+                                		info = localtime(&tmp_t);
+                                		strftime(str_tm, sizeof(str_tm), "%Y-%m-%dT%H:%M:%S", info);
+                                		config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
+					}
+				} else {
+					if (p->active != 1) {
+                                        	p->active = 1;
+                                        	p->active_last_change = time(NULL);
+                                        	//here we need to write this info in the config file
+                                        	config_add_default_host_mac("hosts", "host", mac_str);
+                                        	config_set_host_option("hosts", "host", "macaddr", mac_str, "active", "1");
+                                        	tmp_t = p->active_last_change;
+                                        	info = localtime(&tmp_t);
+                                        	strftime(str_tm, sizeof(str_tm), "%Y-%m-%dT%H:%M:%S", info);
+                                        	config_set_host_option("hosts", "host", "macaddr", mac_str, "active_last_change", str_tm);
+					}
+				}
+				}
+                        }
+		}
+	}
+}
 #if 0
+int host_fill_assoclist(struct topologyd_private *priv, uint8_t macaddr[][6])
+{
+        struct u_list c;
+        int i = 0;
+        int ret = 0;
+
+        host_get_wifi_nodes(priv->ctx, &c);
+
+        p->intf_type = HOST_TYPE_ETHER;
+        for (i = 0; i< c.count; i++) {
+                ret = host_get_assoclist(priv, c.ifname[i], NULL, macaddr);
+                if (ret != 0) {
+                        err("Unable to get the assoclist \n");
+                        return -1;
+                }
+        }
+        return ret;
+}
+
 int host_add_netlink(int *fd)
 {
 	struct nl_sock *sk;
diff --git a/src/host.h b/src/host.h
index 27e0699..28e0719 100644
--- a/src/host.h
+++ b/src/host.h
@@ -28,6 +28,9 @@
 #define HOST_MAX_IPV6ADDR 20
 #define HOST_MAX_IPV4ADDR 20
 #define WIFI_EVENTS	"wifi.sta"
+#define HOST_REFRESH_TIMER 15
+#define NEIGH_CMD "ip neigh show nud reachable|awk '{print $5}'|grep %s"
+#define ARPING_CMD "arping -I br-lan -c 1 -w 1 -D %s| grep Received| awk '{print $2}'"
 
 enum host_types {HOST_TYPE_ETHER = 0, HOST_TYPE_WIFI} host_type;
 
@@ -36,6 +39,7 @@ struct host_node {
 	struct hlist_node hlist;
 	uint8_t active;
 	time_t active_last_change;
+	uint8_t is_ipaddr; /*param to check if the ip address is filled*/
 	char ipv4addr[24];
 	char hostname[64];
 	uint32_t ipv6addr_count;
@@ -43,9 +47,10 @@ struct host_node {
 	uint32_t ipv4addr_count;
 	char ipv4addr_list[HOST_MAX_IPV4ADDR][24];
 	enum host_types intf_type;
+	uint8_t is_ieee1905_node;
 };
 
-int host_topo_node_init(struct topologyd_private *priv,
+struct host_node* host_topo_node_init(struct topologyd_private *priv,
 		uint8_t *mac_addr);
 int host_nodes(struct ubus_context *ctx,
 		struct ubus_object *obj,
@@ -67,5 +72,6 @@ void host_event_handler(struct ubus_context *ctx,
 int host_add_netlink(int *fd);
 void host_netlink_cb(struct uloop_fd *fd, unsigned int events);
 //int host_netlink_cb(struct nl_msg *msg, void *arg);
-
+void host_run_status_check(struct topologyd_private *priv);
+void host_periodic_refresh(struct uloop_timeout *t);
 #endif /* HOSTD_H */
diff --git a/src/host_config.c b/src/host_config.c
index 6ac7585..2ad747d 100644
--- a/src/host_config.c
+++ b/src/host_config.c
@@ -29,6 +29,7 @@
 #include <uci.h>
 
 #include "debug.h"
+#include "host.h"
 
 struct uci_section *config_get_section(struct uci_context *ctx,
 		struct uci_package *pkg, const char *type, const char *key,
@@ -197,31 +198,57 @@ bool config_set_host_option(char *package_name,
 	uci_free_context(ctx);
 	return false;
 }
-#if 0
-static void config_update_entry(struct uci_context *ctx, struct uci_package *p,
-                                struct uci_section *s, const char *optname,
-                                int add, void *val, int len)
+
+bool config_del_host_list(char *package_name,
+                char *section_type, char *search_key, char *search_val,
+                char *option, char *value)
 {
-        struct uci_ptr ptr;
-
-        memset(&ptr, 0, sizeof(struct uci_ptr));
-        ptr.p = p;
-        ptr.s = s;
-        ptr.package = p->e.name;
-        ptr.section = s->e.name;
-        ptr.option = optname;
-        ptr.target = UCI_TYPE_OPTION;
-        ptr.flags |= UCI_LOOKUP_EXTENDED;
-        ptr.value = (char *)val;
-
-        if (add) {
-                dbg("config: add list option: %s\n", (char *)val);
-                uci_add_list(ctx, &ptr);
-        } else {
-                dbg("config: del list option: %s\n", (char *)val);
-                uci_del_list(ctx, &ptr);
+        struct uci_context *ctx;
+        struct uci_package *pkg;
+        struct uci_element *e, *x;
+
+        dbg("Inside %s %d \n", __func__, __LINE__);
+
+        if (!package_name || !search_val || !option || !value)
+                return false;
+
+        ctx = uci_alloc_context();
+        if (!ctx)
+                return false;
+
+        if (uci_load(ctx, package_name, &pkg)) {
+                uci_free_context(ctx);
+                return false;
         }
-        uci_commit(ctx, &p, false);
+
+        uci_foreach_element(&pkg->sections, e) {
+                struct uci_section *s = uci_to_section(e);
+
+                if (!strcmp(s->type, section_type)) {
+                        struct uci_option *opt = uci_lookup_option(ctx, s,
+					search_key);
+                        if (!opt || opt->type != UCI_TYPE_STRING)
+                                continue;
+                        if (strcmp(opt->v.string, search_val) == 0) {
+				//uci_foreach_element(&opt->v.list, x) {
+                                //        if (!strcmp(x->name, option)) {
+				struct uci_ptr ptr = {0};
+
+                                ptr.value = value;
+                                ptr.package = package_name;
+                                ptr.section = s->e.name;
+                                ptr.option = option;
+                                ptr.target = UCI_TYPE_OPTION;
+                                if (uci_del_list(ctx, &ptr) == UCI_OK)
+                                        uci_save(ctx, ptr.p);
+                                break;
+                        }
+                }
+        }
+        uci_commit(ctx, &pkg, false);
+        uci_unload(ctx, pkg);
+        uci_free_context(ctx);
+        return false;
 }
 
 bool config_set_host_list(char *package_name,
@@ -252,24 +279,21 @@ bool config_set_host_list(char *package_name,
                 if (!strcmp(s->type, section_type)) {
                         struct uci_option *opt = uci_lookup_option(ctx, s,
                                                         search_key);
-			if (!opt || opt->type != UCI_TYPE_LIST)
+			if (!opt || opt->type != UCI_TYPE_STRING)
                                 continue;
-			uci_foreach_element(&op->v.list, x) {
-                                        if (!strncmp(x->name, value, len)) {
-                                                if (!add) {
-                                                        config_update_entry(ctx,
-                                                                pkg, s, option,
-                                                                0, value, len);
-                                                }
-
-                                                goto out_exit;
-                                        }
-                                }
-                                /* add new 'option' at end of list */
-                                if (add) {
-                                        config_update_entry(ctx, pkg, s, option,
-                                                                1, value, len);
-                                }
+                        if (strcmp(opt->v.string, search_val) == 0) {
+				struct uci_ptr ptr = {0};
+
+                                ptr.value = value;
+                                ptr.package = package_name;
+                                ptr.section = s->e.name;
+                                ptr.option = option;
+                                ptr.target = UCI_TYPE_OPTION;
+                                if (uci_add_list(ctx, &ptr) == UCI_OK)
+                                        uci_save(ctx, ptr.p);
+                                break;
+
+			}
                 }
         }
         uci_commit(ctx, &pkg, false);
@@ -277,7 +301,7 @@ bool config_set_host_list(char *package_name,
         uci_free_context(ctx);
         return false;
 }
-#endif
+
 bool config_init_host_data(char *package_name, char *section, struct topologyd_private *priv)
 {
 
@@ -286,12 +310,9 @@ bool config_init_host_data(char *package_name, char *section, struct topologyd_p
 	struct uci_package *pkg;
 	struct uci_element *e;
 	char mac_address[18];
-	char active_str[10];
-	char active_last_change_str[30];
-	uint8_t active = 0;
-	time_t active_last_change;
-	struct tm tm;
 	uint8_t mac[6];
+	struct host_node *p = NULL;
+	char intf_type[20];
 
 	dbg("Inside %s %d \n", __func__, __LINE__);
 
@@ -319,26 +340,30 @@ bool config_init_host_data(char *package_name, char *section, struct topologyd_p
 			strncpy(mac_address, opt->v.string, 18);
 			hwaddr_aton(mac_address, mac);
 
-			opt = uci_lookup_option(ctx, s, "active");
+			//Here lookup and add to the host node
+                        p = host_topo_node_init(priv, mac);
+
+			opt = uci_lookup_option(ctx, s, "ip_address");
 			if (!opt || opt->type != UCI_TYPE_STRING)
 				continue;
-			strncpy(active_str, opt->v.string, 10);
-			if (!strcmp(active_str, "0"))
-				active = 0;
-			else
-				active = 1;
+			strncpy(p->ipv4addr, opt->v.string, 24);
 
 			opt = uci_lookup_option(ctx, s,
-				"active_last_change");
+				"hostname");
 			if (!opt || opt->type != UCI_TYPE_STRING)
 				continue;
-			strncpy(active_last_change_str, opt->v.string, 30);
-			memset(&tm, 0, sizeof(tm));
-			strptime(active_last_change_str, "%Y-%m-%dT%H:%M:%S", &tm);
-			active_last_change = mktime(&tm);
+			strncpy(p->hostname, opt->v.string, 64);
 
-			//Here lookup and add to the host node
-			host_topo_node_init(priv, mac);
+			opt = uci_lookup_option(ctx, s,
+                                "interface_type");
+                        if (!opt || opt->type != UCI_TYPE_STRING)
+                                continue;
+                        strncpy(intf_type, opt->v.string, 20);
+			if (!strcmp(intf_type, "0"))
+                                p->intf_type = HOST_TYPE_ETHER;
+                        else
+                                p->intf_type = HOST_TYPE_WIFI;
+			
 		}
 	}
 	uci_unload(ctx, pkg);
diff --git a/src/host_config.h b/src/host_config.h
index 5a0a7eb..30d4c5c 100644
--- a/src/host_config.h
+++ b/src/host_config.h
@@ -23,5 +23,10 @@ bool config_set_host_option(char *package_name,
 		char *option, char *value);
 void config_get_hostname_from_dhcp(const char *mac_in,
 	       	char *hostname);
-
+bool config_set_host_list(char *package_name,
+                char *section_type, char *search_key, char *search_val,
+                char *option, char *value);
+bool config_del_host_list(char *package_name,
+                char *section_type, char *search_key, char *search_val,
+                char *option, char *value);
 #endif /* HOSTD_CONFIG_H */
diff --git a/src/topo_ieee1905.c b/src/topo_ieee1905.c
index 043f07d..883ccf5 100644
--- a/src/topo_ieee1905.c
+++ b/src/topo_ieee1905.c
@@ -151,6 +151,10 @@ int topologyd_node_add(struct topologyd_private *priv, struct node *node)
 		topologyd_copy_update_node(p, node);
 		if (first_run_flag == 0) {
 			topologyd_update_changelog_firstentry(priv, p);
+			/* Here we need to check the status of the
+			 * hosts node that are read from the config
+			 */
+			host_run_status_check(priv);
 			if (!priv->algo_running)
 				topologyd_algo_run(priv);
 			first_run_flag = 1;
diff --git a/src/topologyd.c b/src/topologyd.c
index 3456bc8..f1baec3 100644
--- a/src/topologyd.c
+++ b/src/topologyd.c
@@ -1319,6 +1319,7 @@ static int topologyd_run(struct topologyd_private *priv)
 
 	topologyd_start_heartbeat(&priv->heartbeat);
 	topologyd_periodic_refresh(&priv->refresh_timer);
+	host_periodic_refresh(&priv->host_refresh_timer);
 
 	return 0;
 }
@@ -1439,6 +1440,9 @@ int topologyd_start(void)
 	//wifi connection events
 	priv->wifi_evh.cb = host_event_handler;
 	ubus_register_event_handler(priv->ctx, &priv->wifi_evh, WIFI_EVENTS);
+
+	//Here start the host refresh timer
+	priv->host_refresh_timer.cb = host_periodic_refresh;
 #if 0
 	//Here we add event for the netlink this is 
 	//for ipv4 adddress add for eth link
@@ -1452,6 +1456,7 @@ int topologyd_start(void)
 		goto out_and_exit;
 	}
 #endif
+	
 	priv->refresh_timer.cb = topologyd_periodic_refresh;
 	priv->heartbeat.cb = topologyd_start_heartbeat;
 	priv->topo.changelog = (struct topology_changelog *) calloc
diff --git a/src/topologyd.h b/src/topologyd.h
index 040758e..ecdb6cb 100644
--- a/src/topologyd.h
+++ b/src/topologyd.h
@@ -226,6 +226,7 @@ struct topologyd_private {
 	struct node selfnode;
 	struct topology topo;
 	struct host_ntwk host;
+	struct uloop_timeout host_refresh_timer;
 	void *avahi_serv;
 	void *simple_poll;
 };
-- 
GitLab