diff --git a/src/cntlr.c b/src/cntlr.c index d2d619aa5da59306ad6121c7fde837f2071c1aa7..67d6eb5c1c558348937c8ad1c6cbfa831769d106 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -430,6 +430,10 @@ struct node *cntlr_add_node(struct controller *c, uint8_t *almac) cntlr_resync_config(c, true); } + /* update the timestamp of the node */ + if (n) + timestamp_update(&n->last_tsp_seen); + #ifdef CONTROLLER_SYNC_DYNAMIC_CNTLR_CONFIG if (!hwaddr_equal(c->almac, almac)) cntlr_sync_dyn_controller_config(c, almac); @@ -1382,8 +1386,17 @@ void node_clean_linklist(struct controller *c) static void radio_clean_iflist(struct controller *c, struct netif_radio *r) { struct netif_iface *ni = NULL, *tmp; + struct netif_link *l = NULL, *temp; list_for_each_entry_safe(ni, tmp, &r->iflist, list) { + /* Here we need to clean the linklist */ + list_for_each_entry_safe(l, temp, &c->linklist, list) { + if (l->upstream == ni || l->downstream == ni) { + free(l->metrics); + list_del(&l->list); + free(l); + } + } cntlr_clean_stalist_from_bssid(c, ni->bss->bssid); allmac_clean_entry(&c->mac_table, ni->bss->bssid, MAC_ENTRY_FBSS); free(ni->bss); @@ -1867,6 +1880,29 @@ static void renew_nodes_configuration(struct controller *c) } } +static void cntlr_ageout_nodes(struct controller *c) +{ + struct node *n = NULL, *tmp; + struct netif_radio *r = NULL, *temp; + trace("%s: --->\n", __func__); + /* Here we need to see that all nodes in nodelist */ + /* and check there timestamp */ + list_for_each_entry_safe(n, tmp, &c->nodelist, list) { + if (timestamp_expired(&n->last_tsp_seen, NODE_EXPIRE_TIME * 1000)) { + list_for_each_entry_safe(r, temp, &n->radiolist, list) { + cntlr_config_del_radio(n->alid); + } + cntlr_config_del_node(n->alid); + remove_bh_topology_device(n->alid); + node_clean_radiolist(c, n); + allmac_clean_entry(&c->mac_table, n->alid, MAC_ENTRY_ALID); + list_del(&n->list); + free(n); + if (c->num_nodes > 0) + c->num_nodes--; + } + } +} static void combined_link_metric_periodic_collection(struct controller *c) { trace("%s: --->\n", __func__); @@ -1960,10 +1996,8 @@ error: free(bsslist); } -static void cntlr_periodic_run(atimer_t *t) +static void cntlr_metric_collection(struct controller *c) { - struct controller *c = container_of(t, struct controller, heartbeat); - cntlr_log_nodes(c); //forall_node_get_fhinfo(c); /* replaced from per-node refresh bss */ @@ -1979,10 +2013,8 @@ static void cntlr_periodic_run(atimer_t *t) /* Call AP metrics query and 1905 link metrics query for data collection */ combined_link_metric_periodic_collection(c); - renew_nodes_configuration(c); - timer_set(&c->heartbeat, 10 * 1000); } static void cntlr_acs_run(atimer_t *t) @@ -2225,6 +2257,20 @@ static void cntlr_event_handler(struct ubus_context *ctx, free(str); } +static void cntlr_periodic_run(atimer_t *t) +{ + struct controller *c = container_of(t, struct controller, heartbeat); + + c->uptime += 1; + + trace("|%s:%d| periodic time (elapsed:%"PRIu64")\n", __func__, __LINE__, c->uptime); + + if ((c->uptime % METRIC_REP_INTERVAL) == 0) + cntlr_metric_collection(c); + + cntlr_ageout_nodes(c); + timer_set(&c->heartbeat, 1 * 1000); +} void run_controller(void *opts) { @@ -2346,9 +2392,9 @@ void run_controller(void *opts) timer_init(&c->acs, cntlr_acs_run); timer_init(&c->dfs_cleanup, cntlr_dfs_cleanup_run); - timer_set(&c->heartbeat, 5 * 1000); - timer_set(&c->start_timer, waitext ? 5 * 1000 : 0); + timer_set(&c->heartbeat, 1 * 1000); timer_set(&c->discovery_timer, 0); + timer_set(&c->start_timer, waitext ? 5 * 1000 : 0); timer_set(&c->signal_handler, 5 * 1000); timer_set(&c->query_nodes, 60 * 1000); diff --git a/src/cntlr.h b/src/cntlr.h index 96ee5b102e8c47bb8cada078495d0a28d49c0886..449e167cce66919e1ca5875c9a059b212d66407d 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -32,6 +32,9 @@ #define EASYMESH_VENDOR_EXT_OUI_DEFAULT 0xB456FA /* IOPSYS OUI */ #endif +#define NODE_EXPIRE_TIME 65 +#define METRIC_REP_INTERVAL 10 + extern const char *ubus_socket; typedef uint32_t object_t; @@ -274,7 +277,7 @@ struct node { uint8_t map_profile; /** profile info of agent node */ struct timespec last_config; /** timestamp of most-recent config sent to agent */ struct timespec last_cmdu; /** timestamp of last CMDU received from agent */ - + struct timespec last_tsp_seen; /** last seen tsp */ struct list_head radiolist; /** list of netif_radio */ struct list_head stalist; struct list_head list; @@ -290,6 +293,7 @@ enum cntlr_state { struct controller { struct log_options log; + uint64_t uptime; /* uptime in seconds */ enum cntlr_state state; unsigned char almac[6]; void *comm; diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 51dde44be9804f869d97d9169d5d06a3076328b0..95cd5e16e4cb5d60f7293d36548aa81a17915d69 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -2536,7 +2536,11 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu, /* Get bcn metrics */ if (scc->use_bcn_metrics) { - cntlr_get_bcn_metrics(c,s, !scc->bandsteer); + /* check that if only one agent and bandsteer disabled + * then dont send request for bcn metrics + */ + if (c->num_nodes > 1 || scc->bandsteer) + cntlr_get_bcn_metrics(c,s, !scc->bandsteer); } /* Get usta metrics for each agent in mesh */ @@ -4225,6 +4229,10 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid, return -1; } + /*update the timestamp of the node*/ + if (n) + timestamp_update(&n->last_tsp_seen); + cmdu = cmdu_alloc_custom(cmdutype, &mid, rxif, src, tlvs, len); if (!cmdu) { dbg("%s: cmdu_alloc_custom() failed!\n", __func__); diff --git a/src/config.c b/src/config.c index 2d5f8d65ef9485b0bc117dfda37999ec4cde1d60..301299f006cfee02b8c7f13c254ad1a74a039e7a 100644 --- a/src/config.c +++ b/src/config.c @@ -375,6 +375,68 @@ struct uci_section *config_get_section(struct uci_context *ctx, return NULL; } +int cntlr_config_del_node(uint8_t *almac) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_section *section; + struct uci_ptr ptr = {0}; + int ret = -1; + char mac_str[18] = {0}; + + if (!hwaddr_ntoa(almac, mac_str)) + return ret; + + pkg = uci_load_pkg(&ctx, "mapcontroller"); + if (!pkg) + return ret; + + section = config_get_section(ctx, pkg, "node", "agent_id", mac_str); + if (!section) + goto out_pkg; + + ptr.p = pkg; + ptr.s = section; + + uci_delete(ctx, &ptr); + uci_commit(ctx, &pkg, false); +out_pkg: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return 0; +} + +int cntlr_config_del_radio(uint8_t *almac) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_section *section; + struct uci_ptr ptr = {0}; + int ret = -1; + char mac_str[18] = {0}; + + if (!hwaddr_ntoa(almac, mac_str)) + return ret; + + pkg = uci_load_pkg(&ctx, "mapcontroller"); + if (!pkg) + return ret; + + section = config_get_section(ctx, pkg, "radio", "agent_id", mac_str); + if (!section) + goto out_pkg; + + ptr.p = pkg; + ptr.s = section; + + uci_delete(ctx, &ptr); + uci_commit(ctx, &pkg, false); +out_pkg: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return 0; +} + int cntlr_config_add_node(struct controller_config *c, char *al_mac) { struct uci_context *ctx = NULL; diff --git a/src/config.h b/src/config.h index cafd5437a8aebe4c0230cd0d2d5cc4b7f91e6020..9d68a00851f6f886e0fbff393ad3f86527820566 100644 --- a/src/config.h +++ b/src/config.h @@ -265,6 +265,8 @@ uint8_t cntlr_config_reload(struct controller_config *cfg); int cntlr_config_defaults(struct controller *c, struct controller_config *cfg); void cntlr_config_dump(struct controller_config *cfg); int cntlr_config_clean(struct controller_config *cfg); +int cntlr_config_del_node(uint8_t *almac); +int cntlr_config_del_radio(uint8_t *almac); #if (EASYMESH_VERSION > 2) /* QoS functions */