From 6e159b1fe1e52b745989d7db7b34d0c7034e42c5 Mon Sep 17 00:00:00 2001
From: Filip Matusiak <filip.matusiak@iopsys.eu>
Date: Fri, 20 May 2022 14:12:08 +0200
Subject: [PATCH] wifi_dataelements: wifi_bss_element improvements

* keep measurement time for bss and sta up to date
* mark unused netif_iface fields for deprecation
* keep netifs type in dataelement
* shorten de_bss field of netif_iface
* allow removal of netif_iface's channel field
---
 src/cntlr.c             | 48 +++++++++++++-------------
 src/cntlr.h             | 25 ++++++--------
 src/cntlr_acs.c         |  7 ++--
 src/cntlr_map.c         | 74 +++++++++++++++++++++++------------------
 src/cntlr_tlv.c         | 18 +++++-----
 src/cntlr_ubus.c        | 14 ++++----
 src/utils/utils.c       | 30 +++++++++++++++++
 src/utils/utils.h       |  2 +-
 src/wifi_dataelements.h |  5 ++-
 9 files changed, 130 insertions(+), 93 deletions(-)

diff --git a/src/cntlr.c b/src/cntlr.c
index 25f3018f..293154a6 100644
--- a/src/cntlr.c
+++ b/src/cntlr.c
@@ -62,7 +62,7 @@ struct netif_iface *find_interface_by_mac_nor(struct controller *c,
 	list_for_each_entry(n, &c->nodelist, list) {
 		list_for_each_entry(r, &n->radiolist, list) {
 			list_for_each_entry(p, &r->iflist, list) {
-				if (!memcmp(p->de_bss->bssid, hwaddr, 6))
+				if (!memcmp(p->bss->bssid, hwaddr, 6))
 					return p;
 			}
 		}
@@ -78,7 +78,7 @@ struct netif_iface *find_interface_by_mac(struct controller *c,
 	struct netif_iface *p = NULL;
 
 	list_for_each_entry(p, &r->iflist, list) {
-		if (!memcmp(p->de_bss->bssid, hwaddr, 6))
+		if (!memcmp(p->bss->bssid, hwaddr, 6))
 			return p;
 	}
 
@@ -96,7 +96,7 @@ struct netif_radio *find_radio_by_ssid(struct controller *c,
 		struct netif_iface *p = NULL;
 
 		list_for_each_entry(p, &r->iflist, list) {
-			if (!memcmp(p->de_bss->ssid, ssid, 33))
+			if (!memcmp(p->bss->ssid, ssid, 33))
 				return r;
 		}
 	}
@@ -115,7 +115,7 @@ struct netif_iface *find_interface_by_ssid(struct controller *c,
 		struct netif_iface *p = NULL;
 
 		list_for_each_entry(p, &r->iflist, list) {
-			if (!memcmp(p->de_bss->ssid, ssid, 33))
+			if (!memcmp(p->bss->ssid, ssid, 33))
 				return p;
 		}
 	}
@@ -147,7 +147,7 @@ struct netif_radio *find_radio_by_bssid(struct controller *c, uint8_t *bssid)
 	list_for_each_entry(n, &c->nodelist, list) {
 		list_for_each_entry(r, &n->radiolist, list) {
 			list_for_each_entry(p, &r->iflist, list) {
-				if (!memcmp(p->de_bss->bssid, bssid, 6))
+				if (!memcmp(p->bss->bssid, bssid, 6))
 					return r;
 			}
 		}
@@ -162,8 +162,8 @@ struct netif_link *find_link_by_mac(struct controller *c, uint8_t *upstream, uin
 	struct netif_link *l = NULL;
 
 	list_for_each_entry(l, &c->linklist, list) {
-		if (!memcmp(l->upstream->de_bss->bssid, upstream, 6)
-				&& !memcmp(l->downstream->de_bss->bssid, downstream, 6))
+		if (!memcmp(l->upstream->bss->bssid, upstream, 6)
+				&& !memcmp(l->downstream->bss->bssid, downstream, 6))
 			return l;
 	}
 
@@ -218,7 +218,7 @@ struct netif_iface *cntlr_get_fbss_by_mac(struct controller *c, struct node *n,
 	struct netif_iface *p;
 
 	list_for_each_entry(p, &n->iflist, list) {
-		if (!memcmp(p->de_bss->bssid, mac, 6))
+		if (!memcmp(p->bss->bssid, mac, 6))
 			return p;
 	}
 
@@ -235,7 +235,7 @@ struct netif_iface *cntlr_iterate_fbss(struct controller *c, uint8_t *mac)
 	list_for_each_entry(n, &c->nodelist, list) {
 		list_for_each_entry(r, &n->radiolist, list) {
 			list_for_each_entry(p, &r->iflist, list) {
-				if (!memcmp(p->de_bss->bssid, mac, 6))
+				if (!memcmp(p->bss->bssid, mac, 6))
 					return p;
 			}
 		}
@@ -256,7 +256,7 @@ struct node *find_node_by_iface(struct controller *c, uint8_t *bssid)
 			struct netif_iface *p = NULL;
 
 			list_for_each_entry(p, &r->iflist, list) {
-				if (!memcmp(p->de_bss->bssid, bssid, 6))
+				if (!memcmp(p->bss->bssid, bssid, 6))
 					return n;
 			}
 		}
@@ -324,7 +324,7 @@ struct node *get_node_by_bssid(struct controller *c, unsigned char *bssid)
 
 	list_for_each_entry(n, &c->nodelist, list) {
 		list_for_each_entry(p, &n->iflist, list) {
-			if (memcmp(bssid, p->de_bss->bssid, 6))
+			if (memcmp(bssid, p->bss->bssid, 6))
 				continue;
 
 			return n;
@@ -630,8 +630,8 @@ struct netif_iface *cntlr_radio_add_interface(struct controller *c,
 
 	n = find_interface_by_mac(c, r, hwaddr);
 	if (n) {
-		n->de_bss->enabled = true;
-		n->band = r->band;
+		n->bss->enabled = true;
+		n->band = r->band; /* TODO unused: deprecate */
 		return n;
 	}
 
@@ -639,17 +639,18 @@ struct netif_iface *cntlr_radio_add_interface(struct controller *c,
 	if (!n)
 		return NULL;
 
-	n->de_bss = cntlr_wifi_bss(c, hwaddr);
-	if (!n->de_bss) {
+	n->bss = cntlr_wifi_bss(c, hwaddr);
+	if (!n->bss) {
 		free(n);
 		return NULL;
 	}
 
-	n->type = NETIF_FHBSS;
-	n->de_bss->enabled = true;
+	n->bss->is_fbss = true;
+	n->bss->is_bbss = false;
+	n->bss->enabled = true;
 	list_add(&n->list, &r->iflist);
 	n->agent = r->agent;
-	n->band = r->band;
+	n->band = r->band; /* TODO unused: deprecate */
 
 	return n;
 }
@@ -989,7 +990,7 @@ static void radio_clean_iflist(struct netif_radio *r)
 	struct netif_iface *ni = NULL, *tmp;
 
 	list_for_each_entry_safe(ni, tmp, &r->iflist, list) {
-		free(ni->de_bss);
+		free(ni->bss);
 		list_del(&ni->list);
 		free(ni);
 	}
@@ -1064,8 +1065,8 @@ struct netif_link *alloc_link_init(struct controller *c,
 		goto out_metrics;
 
 	trace("Adding link | " MACFMT " <---> " MACFMT " |\n",
-		  MAC2STR(l->upstream->de_bss->bssid),
-		  MAC2STR(l->downstream->de_bss->bssid));
+		  MAC2STR(l->upstream->bss->bssid),
+		  MAC2STR(l->downstream->bss->bssid));
 	list_add(&l->list, &c->linklist);
 
 	return l;
@@ -1397,7 +1398,8 @@ static void combined_link_metric_periodic_collection(struct controller *c)
 
 			/* For each bss in radio */
 			list_for_each_entry(bss, &radio->iflist, list) {
-				if (bss->type) /*if bss is bsta */
+				if (!bss->bss->is_fbss && !bss->bss->is_bbss)
+					/* if bss is a bsta */
 					continue;
 
 				/* Building a bsslist of all BSS */
@@ -1412,7 +1414,7 @@ static void combined_link_metric_periodic_collection(struct controller *c)
 				bsslist = new_bsslist;
 				num_bss++;
 				bss_index = (num_bss - 1) * 6;
-				memcpy(bsslist + bss_index, bss->de_bss->bssid, 6);
+				memcpy(bsslist + bss_index, bss->bss->bssid, 6);
 			}
 		}
 		cmdu = cntlr_gen_ap_metrics_query(c, hwaddr, num_bss, bsslist, num_radio, radiolist);
diff --git a/src/cntlr.h b/src/cntlr.h
index e75c140c..b6307bad 100644
--- a/src/cntlr.h
+++ b/src/cntlr.h
@@ -25,12 +25,6 @@ extern const char *ubus_socket;
 typedef uint32_t object_t;
 #define OBJECT_INVALID	((uint32_t)-1)
 
-enum iface_type {
-	NETIF_FHBSS,
-	NETIF_BKBSS,
-	NETIF_BSTA
-};
-
 enum device_type {
 	NON_IEEE1905,
 	IEEE1905
@@ -111,18 +105,19 @@ enum media_type {
  */
 struct netif_iface {
 	char ifname[16];
-	int band;
-	enum media_type med_type;
-	uint32_t bssid_info;
-	uint8_t reg;
-	uint8_t phy;
-	int channel;
-	int capacity;
-	int type;
+
+	int band;					/* TODO unused: deprecate */
+	enum media_type med_type;	/* TODO unused: deprecate */
+	uint32_t bssid_info;		/* TODO unused: deprecate */
+	uint8_t reg;				/* TODO unused: deprecate */
+	uint8_t phy;				/* TODO unused: deprecate */
+	int channel;				/* TODO unused: deprecate */
+	int capacity;				/* TODO unused: deprecate */
+
 	struct node *agent;
 	uint8_t upstream_bssid[6]; /* in the case of the interface is a bsta interface */
 
-	struct wifi_bss_element *de_bss;
+	struct wifi_bss_element *bss;
 
 	struct list_head list;
 };
diff --git a/src/cntlr_acs.c b/src/cntlr_acs.c
index 4be4e000..547e08ed 100644
--- a/src/cntlr_acs.c
+++ b/src/cntlr_acs.c
@@ -160,8 +160,9 @@ static bool cntlr_acs_radio_is_bsta_connected(struct netif_radio *radio)
 
 	list_for_each_entry(iface, &radio->iflist, list) {
 		/* Check if sta iface connected */
-		if (iface->type != NETIF_BSTA)
+		if (iface->bss->is_bbss || iface->bss->is_fbss)
 			continue;
+
 		if (hwaddr_is_zero(iface->upstream_bssid))
 			continue;
 
@@ -265,9 +266,9 @@ static bool cntrlr_radio_is_ap_iface(struct netif_radio *radio)
 
 	list_for_each_entry(iface, &radio->iflist, list) {
 		/* Check if AP iface connected */
-		if (iface->type == NETIF_FHBSS)
+		if (iface->bss->is_fbss)
 			return true;
-		if (iface->type == NETIF_BKBSS)
+		if (iface->bss->is_bbss)
 			return true;
 	}
 
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index cfccce0d..b8a5f43c 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -104,8 +104,8 @@ static void cntlr_update_steer_params(struct controller *c, struct sta *s)
     list_for_each_entry(n, &c->nodelist, list) {
         list_for_each_entry(r, &n->radiolist, list) {
             list_for_each_entry(p, &r->iflist, list) {
-				if (p->de_bss->ssid && s->fh && s->fh->de_bss->ssid
-				    && !memcmp(p->de_bss->ssid, s->fh->de_bss->ssid, 33))
+				if (p->bss->ssid && s->fh && s->fh->bss->ssid
+				    && !memcmp(p->bss->ssid, s->fh->bss->ssid, 33))
 					_cntlr_update_steer_params(c, &r->cur_opclass);
             }
         }
@@ -157,10 +157,12 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu)
 
 			/* disable all prior stored fh/bh interfaces */
 			list_for_each_entry(p, &r->iflist, list) {
-				if (p->type == NETIF_BSTA)
+				if (!p->bss->is_fbss && !p->bss->is_bbss)
+					/* it is a bsta */
 					continue;
-				p->de_bss->enabled = false;
-				p->type = NETIF_FHBSS;
+				p->bss->enabled = false;
+				p->bss->is_fbss = true;
+				p->bss->is_bbss = false;
 			}
 
 			memcpy(&num_bss, &tv_data[offset], 1);
@@ -181,14 +183,15 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu)
 
 				offset += 1; /* ssidlen */
 
-				memset(fh->de_bss->ssid, 0, sizeof(fh->de_bss->ssid));
-				len = (ssidlen > sizeof(fh->de_bss->ssid) - 1
-						? sizeof(fh->de_bss->ssid) - 1 : ssidlen);
-				memcpy(fh->de_bss->ssid, &tv_data[offset], len);
+				memset(fh->bss->ssid, 0, sizeof(fh->bss->ssid));
+				len = (ssidlen > sizeof(fh->bss->ssid) - 1
+						? sizeof(fh->bss->ssid) - 1 : ssidlen);
+				memcpy(fh->bss->ssid, &tv_data[offset], len);
 
 				offset += ssidlen; /* ssid */
 
-				/* TODO: update fh->de_bss->tsp here */
+				/* Update measurement time */
+				time(&fh->bss->tsp);
 			}
 		}
 	}
@@ -238,7 +241,8 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu)
 				if (!fh)
 					return -1; /* FIXME: continue + proper offset shift */
 
-				fh->type = NETIF_BKBSS;
+				fh->bss->is_bbss = true;
+				fh->bss->is_fbss = false;
 
 				offset += 6; /* macaddr */
 			}
@@ -308,8 +312,10 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu)
 				if (bsta) {
 					/* The client is an agent and the iface is a bSTA */
 					memcpy(bsta->upstream_bssid, bssid, 6);
-					bsta->type = NETIF_BSTA;
-					bsta->de_bss->enabled = true;
+					/* bsta - unmark bbss & fbss */
+					fh->bss->is_bbss = false;
+					fh->bss->is_fbss = false;
+					bsta->bss->enabled = true;
 					s->type = IEEE1905;
 					s->agent = bsta->agent;
 					//s->de_sta->mapsta.stats.failed_steer_attempts = 0;
@@ -1153,7 +1159,7 @@ int handle_ap_metrics_response(void *cntlr, struct cmdu_buff *cmdu)
 		if (!ifc)
 			continue;
 
-		b = ifc->de_bss;
+		b = ifc->bss;
 		b->ch_util = p->channel_utilization;
 		b->num_stations = p->num_station;
 		/* Estimated service parameter fields for AC */
@@ -1187,7 +1193,7 @@ int handle_ap_metrics_response(void *cntlr, struct cmdu_buff *cmdu)
 		// list_for_each_entry(r, &n->radiolist, list) {
 		// list_for_each_entry(ifc, &r->iflist, list) {
 
-		// b = ifc->de_bss;
+		// b = ifc->bss;
 		// unsigned char est_str[16];
 		// trace("STORED:\n");
 		// trace("\tbssid: " MACFMT "\n", MAC2STR(p->bssid));
@@ -1247,14 +1253,15 @@ static int cntlr_request_usta_metrics(struct controller *c,
 
 	if (n->ap_cap & UNASSOC_STA_REPORTING_ONCHAN) {
 
-		r = find_radio_by_ssid(c, n, s->fh->de_bss->ssid);
-		fh = find_interface_by_ssid(c, n, s->fh->de_bss->ssid);
+		r = find_radio_by_ssid(c, n, s->fh->bss->ssid);
+		fh = find_interface_by_ssid(c, n, s->fh->bss->ssid);
 
 		if (!r || !fh)
 			return -1;
 
 		for (j = 0; j < r->cur_opclass.opclass_entry_num; j++) {
-			metrics[0].channel = fh->channel;
+			/* TODO: refactor to allow more than one channel */
+			metrics[0].channel = r->cur_opclass.opclass_entry[0].channels[0].channel;
 			metrics[0].num_sta = 1;
 			memcpy(metrics[0].sta[0].macaddr, s->de_sta->macaddr, 6);
 
@@ -1284,7 +1291,7 @@ static void cntlr_request_bcn_metrics_bsta(struct controller *c, struct sta *s)
 
 	bcn_cmdu = cntlr_gen_beacon_metrics_query(c,
 			s->fh->agent->alid, s->de_sta->macaddr, 0, 0,
-			wildcard, 0, s->fh->de_bss->ssid, 0, NULL, 0, NULL);
+			wildcard, 0, s->fh->bss->ssid, 0, NULL, 0, NULL);
 
 	if (bcn_cmdu) {
 		send_cmdu(c, bcn_cmdu);
@@ -1384,7 +1391,7 @@ static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s)
 	bcn_cmdu = cntlr_gen_beacon_metrics_query(c,
 			s->fh->agent->alid, s->de_sta->macaddr,
 			opclass, channel,
-			wildcard, 0, s->fh->de_bss->ssid,
+			wildcard, 0, s->fh->bss->ssid,
 			num_report, reports, 0, NULL);
 
 	if (bcn_cmdu) {
@@ -1420,8 +1427,8 @@ static int update_txlink_metric_data(struct controller *c, struct tlv_tx_linkmet
 		}
 		metrics = txlink->metrics;
 		metrics->l = txlink;
-		memcpy(metrics->l->upstream->de_bss->bssid, txlinfo->local_macaddr, 6);
-		memcpy(metrics->l->downstream->de_bss->bssid, txlinfo->neighbor_macaddr, 6);
+		memcpy(metrics->l->upstream->bss->bssid, txlinfo->local_macaddr, 6);
+		memcpy(metrics->l->downstream->bss->bssid, txlinfo->neighbor_macaddr, 6);
 		metrics->type = BUF_GET_BE16(txlinfo->mediatype);
 		metrics->bridge = txlinfo->has_bridge;
 		metrics->packet_tx_error = BUF_GET_BE32(txlinfo->errors);
@@ -1455,8 +1462,8 @@ static int update_rxlink_metric_data(struct controller *c, struct tlv_rx_linkmet
 		}
 		metrics = rxlink->metrics;
 		metrics->l = rxlink;
-		memcpy(metrics->l->upstream->de_bss->bssid, rxlinfo->local_macaddr, 6);
-		memcpy(metrics->l->downstream->de_bss->bssid, rxlinfo->neighbor_macaddr, 6);
+		memcpy(metrics->l->upstream->bss->bssid, rxlinfo->local_macaddr, 6);
+		memcpy(metrics->l->downstream->bss->bssid, rxlinfo->neighbor_macaddr, 6);
 		metrics->type = BUF_GET_BE16(rxlinfo->mediatype);
 		metrics->packet_rec = BUF_GET_BE32(rxlinfo->packets);
 		metrics->packet_rx_error = BUF_GET_BE32(rxlinfo->errors);
@@ -1573,7 +1580,8 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu)
 			s->de_sta->dl_est_thput = BUF_GET_BE32(b->dl_thput);
 			s->de_sta->ul_est_thput = BUF_GET_BE32(b->ul_thput);
 			s->time_delta = BUF_GET_BE32(b->time_delta);
-			/* TODO: update s->de_sta->tsp here */
+			/* Update measurement time */
+			time(&s->de_sta->tsp);
 			s->de_sta->rcpi = b->ul_rcpi;
 
 			offset += sizeof(*b);
@@ -1761,10 +1769,10 @@ void cntlr_check_usta_steer(struct controller *c, struct sta *s)
 		return;
 
 	/* Get appropriate netif on best node based on current ssid */
-	best_fh = find_interface_by_ssid(c, best->agent, s->fh->de_bss->ssid);
+	best_fh = find_interface_by_ssid(c, best->agent, s->fh->bss->ssid);
 
-	if (best_fh && !hwaddr_is_zero(best_fh->de_bss->bssid)
-			&& memcmp(best_fh->de_bss->bssid, s->bssid, 6)) {
+	if (best_fh && !hwaddr_is_zero(best_fh->bss->bssid)
+			&& memcmp(best_fh->bss->bssid, s->bssid, 6)) {
 
 		struct cmdu_buff *cmdu;
 
@@ -1780,16 +1788,16 @@ void cntlr_check_usta_steer(struct controller *c, struct sta *s)
 		    from " MACFMT " to " MACFMT "\n",
 		    __func__, __LINE__,
 		    MAC2STR(s->de_sta->macaddr), MAC2STR(s->bssid),
-		    MAC2STR(best_fh->de_bss->bssid));
+		    MAC2STR(best_fh->bss->bssid));
 
 		if (s->type == IEEE1905)
 			cmdu = cntlr_gen_backhaul_steer_request(c, s->agent->alid,
-					s->de_sta->macaddr, best_fh->de_bss->bssid, 0, 0);
+					s->de_sta->macaddr, best_fh->bss->bssid, 0, 0);
 		else
 			cmdu = cntlr_gen_client_steer_request(c, s->fh->agent->alid,
 					s->bssid, 0,
 					1, (uint8_t (*)[6])s->de_sta->macaddr,
-					1, (uint8_t (*)[6])best_fh->de_bss->bssid,
+					1, (uint8_t (*)[6])best_fh->bss->bssid,
 					1);
 
 		if (cmdu) {
@@ -2414,7 +2422,9 @@ int handle_backhaul_sta_caps_report(void *cntlr, struct cmdu_buff *cmdu)
 			if (!fh)
 				continue;
 
-			fh->type = NETIF_BSTA;
+			/* bsta - unmark bbss & fbss */
+			fh->bss->is_bbss = false;
+			fh->bss->is_fbss = false;
 		}
 
 		num++;
diff --git a/src/cntlr_tlv.c b/src/cntlr_tlv.c
index a27fc984..c4ed15b9 100644
--- a/src/cntlr_tlv.c
+++ b/src/cntlr_tlv.c
@@ -1006,7 +1006,7 @@ int cntlr_gen_ap_metrics_tlv(struct controller *c,
 		trace("Incorrect bssid!\n");
 		return -1;
 	}
-	bss = ifc->de_bss;
+	bss = ifc->bss;
 	memcpy(data->bssid, bss->bssid, 6);
 	data->channel_utilization = bss->ch_util;
 	data->num_station = bss->num_stations;
@@ -1057,15 +1057,15 @@ int cntlr_gen_tx_link_metric_tlv(struct controller *c,
 
 	t->type = TLV_TYPE_TRANSMITTER_LINK_METRIC;
 	data = (struct tlv_tx_linkmetric *) t->data;
-	n = find_node_by_iface(c, link_info->upstream->de_bss->bssid);
+	n = find_node_by_iface(c, link_info->upstream->bss->bssid);
 	memcpy(data->aladdr, n->alid, 6);
-	n = find_node_by_iface(c, link_info->downstream->de_bss->bssid);
+	n = find_node_by_iface(c, link_info->downstream->bss->bssid);
 	memcpy(data->neighbor_aladdr, n->alid, 6);
 	t->len = 12; /* link */
 	for (int i = 0; i < c->num_tx_links; i++) {
 		info = (struct tx_link_info *)&data->link[i];
-		memcpy(info->local_macaddr, link_info->upstream->de_bss->bssid, 6);
-		memcpy(info->neighbor_macaddr, link_info->downstream->de_bss->bssid, 6);
+		memcpy(info->local_macaddr, link_info->upstream->bss->bssid, 6);
+		memcpy(info->neighbor_macaddr, link_info->downstream->bss->bssid, 6);
 		BUF_PUT_BE16(info->mediatype, link_info->metrics->type);
 		info->has_bridge = link_info->metrics->bridge;
 		BUF_PUT_BE32(info->errors, link_info->metrics->packet_tx_error);
@@ -1100,15 +1100,15 @@ int cntlr_gen_rx_link_metric_tlv(struct controller *c,
 
 	t->type = TLV_TYPE_RECEIVER_LINK_METRIC;
 	data = (struct tlv_rx_linkmetric *) t->data;
-	n = find_node_by_iface(c, link_info->upstream->de_bss->bssid);
+	n = find_node_by_iface(c, link_info->upstream->bss->bssid);
 	memcpy(data->aladdr, n->alid, 6);
-	n = find_node_by_iface(c, link_info->downstream->de_bss->bssid);
+	n = find_node_by_iface(c, link_info->downstream->bss->bssid);
 	memcpy(data->neighbor_aladdr, n->alid, 6);
 	t->len = 12; /* link */
 	for (int i = 0; i < c->num_rx_links; i++) {
 		info = (struct rx_link_info *)&data->link[i];
-		memcpy(info->local_macaddr, link_info->upstream->de_bss->bssid, 6);
-		memcpy(info->neighbor_macaddr, link_info->downstream->de_bss->bssid, 6);
+		memcpy(info->local_macaddr, link_info->upstream->bss->bssid, 6);
+		memcpy(info->neighbor_macaddr, link_info->downstream->bss->bssid, 6);
 		BUF_PUT_BE16(info->mediatype, link_info->metrics->type);
 		BUF_PUT_BE32(info->errors, link_info->metrics->packet_rx_error);
 		BUF_PUT_BE32(info->packets, link_info->metrics->packet_rec);
diff --git a/src/cntlr_ubus.c b/src/cntlr_ubus.c
index f16d77b7..2ce7adcb 100644
--- a/src/cntlr_ubus.c
+++ b/src/cntlr_ubus.c
@@ -530,21 +530,21 @@ static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj,
 			list_for_each_entry(fh, &p->iflist, list) {
 				char type[32] = {0};
 
-				if (!fh->de_bss->enabled)
+				if (!fh->bss->enabled)
 					continue;
 
 				memset(bssidstr, 0, sizeof(bssidstr));
-				hwaddr_ntoa(fh->de_bss->bssid, bssidstr);
+				hwaddr_ntoa(fh->bss->bssid, bssidstr);
 				ttttt = blobmsg_open_table(&bb, "");
-				if (fh->type == NETIF_FHBSS) {
+				if (fh->bss->is_fbss) {
 					blobmsg_add_string(&bb, "bssid", bssidstr);
 					strcpy(type, "fronthaul");
-					blobmsg_add_string(&bb, "ssid", fh->de_bss->ssid);
-				} else if (fh->type == NETIF_BKBSS) {
+					blobmsg_add_string(&bb, "ssid", fh->bss->ssid);
+				} else if (fh->bss->is_bbss) {
 					blobmsg_add_string(&bb, "bssid", bssidstr);
 					strcpy(type, "backhaul");
-					blobmsg_add_string(&bb, "ssid", fh->de_bss->ssid);
-				} else if (fh->type == NETIF_BSTA) {
+					blobmsg_add_string(&bb, "ssid", fh->bss->ssid);
+				} else {
 					blobmsg_add_string(&bb, "macaddr", bssidstr);
 					strcpy(type, "station");
 				}
diff --git a/src/utils/utils.c b/src/utils/utils.c
index ee2effbc..f8dbdbf3 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -188,6 +188,36 @@ int timestamp_expired(struct timespec *a, unsigned int tmo_ms)
 	return 0;
 }
 
+char *time_to_timestamp(time_t *t, char *tsp)
+{
+	char tmpbuf[64] = {0};
+	struct tm res;
+	char sign;
+	long int toff, toff_hour, toff_min;
+
+	if (!tsp)
+		return NULL;
+
+	/* E.g. "2019-02-11T06:42:31.23039-08:00" */
+
+	localtime_r(t, &res);
+	tzset();
+	toff = timezone;
+	sign = toff > 0 ? '-' : '+';
+	toff *= -1L;
+
+	toff_hour = toff / 3600;
+	toff_min = (toff % 3600) / 60;
+
+	snprintf(tmpbuf, sizeof(tmpbuf), "%04d-%02d-%02dT%02d:%02d:%02d%c%02ld:%02ld",
+			 res.tm_year + 1900, res.tm_mon + 1, res.tm_mday,
+			 res.tm_hour, res.tm_min, res.tm_sec,
+			 sign, toff_hour, toff_min);
+
+	snprintf(tsp, 64, "%s", tmpbuf);
+	return tsp;
+}
+
 /** list utility functions */
 /**
  * list_num_entries - gets number of entries on the list
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 2646a236..4299b21d 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -66,6 +66,7 @@ static inline int timestamp_invalid(struct timespec *ts)
 
 uint32_t timestamp_elapsed_sec(struct timespec *ts);
 int timestamp_expired(struct timespec *a, unsigned int tmo_ms);
+char *time_to_timestamp(time_t *t, char *tsp);
 
 /* bytes from-to hexstring helper functions */
 int hex2byte(const char *hex);
@@ -170,5 +171,4 @@ void do_daemonize(const char *pidfile);
 
 int writeto_configfile(const char *filename, void *in, size_t len);
 int readfrom_configfile(const char *filename, uint8_t **out, uint32_t *olen);
-
 #endif /* UTILS_H */
diff --git a/src/wifi_dataelements.h b/src/wifi_dataelements.h
index ea0ef759..769b9cf4 100644
--- a/src/wifi_dataelements.h
+++ b/src/wifi_dataelements.h
@@ -61,7 +61,6 @@ enum wifi_security_type {
 };
 #endif
 
-
 typedef char timestamp_t[32];
 typedef uint8_t guid_t[16];
 typedef uint8_t macaddr_t[6], node_id_t[6];
@@ -295,7 +294,7 @@ struct wifi_multiap_sta {
 
 struct wifi_sta_element {
 	struct list_head list;
-	timestamp_t tsp;
+	time_t tsp;
 	uint8_t macaddr[6];
 	//wifi6caps
 	//clientcaps
@@ -337,7 +336,7 @@ enum counter_unit { COUNTER_UNIT_KB = 1, COUNTER_UNIT_MB = 2 };
 
 struct wifi_bss_element {
 	struct list_head list;
-	timestamp_t tsp;
+	time_t tsp;
 	uint8_t bssid[6];
 	char ssid[33];
 	bool enabled;
-- 
GitLab