From 82b9771fe38debb3acb9109f5938c5011da373e9 Mon Sep 17 00:00:00 2001 From: Filip Matusiak <filip.matusiak@iopsys.eu> Date: Thu, 12 May 2022 12:20:43 +0200 Subject: [PATCH] wifi_dataelements: update and adapt to new structs store STA conntime in dataelement Move associated sta link metrics to data elements leverage wifi_sta_meas_report to store bcn metrics implement update of extended link metrics add TODOs for implementation gaps move steer summary to dataelements use dataelements for per network steer stats use dataelements to store steer history use wifi_sta_meas_report in steer plugin --- src/cntlr.c | 106 ++++++++++++++++---------- src/cntlr.h | 66 ++-------------- src/cntlr_map.c | 139 ++++++++++++++++++++++------------ src/cntlr_ubus.c | 122 ++++++++++------------------- src/plugins/steer/rcpi/rcpi.c | 8 +- src/steer.h | 15 +--- src/wifi_dataelements.h | 44 ++++++++--- 7 files changed, 242 insertions(+), 258 deletions(-) diff --git a/src/cntlr.c b/src/cntlr.c index 618d3cf5..94f5fe9a 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -189,7 +189,7 @@ struct sta *cntlr_find_sta(struct controller *c, uint8_t *mac) struct sta *s = NULL; list_for_each_entry(s, &c->stalist, list) { - if (!memcmp(s->macaddr, mac, 6)) + if (!memcmp(s->de_sta->macaddr, mac, 6)) return s; } @@ -363,8 +363,9 @@ void cntlr_update_sta_steer_counters(struct controller *c, { trace("%s:--->\n", __func__); - struct steer_attempt *a; + struct wifi_apsta_steer_history *a; struct sta *s = cntlr_find_sta(c, sta_mac); + struct wifi_multiap_sta *mapsta; if (!s) { dbg("|%s:%d| Unrecognized STA "MACFMT", skip!\n", @@ -372,17 +373,17 @@ void cntlr_update_sta_steer_counters(struct controller *c, return; } - /* TODO: tr-181: use STA.{i}.MultiAPSTA.SteeringHistory.{i} */ - if (s->num_steer_attempts >= MAX_LOG_STEER_ATTEMPTS) { + mapsta = &s->de_sta->mapsta; + if (mapsta->num_steer_hist >= MAX_STEER_HISTORY) { int i; - for (i = 0; i < MAX_LOG_STEER_ATTEMPTS - 1; i++) { - memcpy(&s->attempts[i], &s->attempts[(i+1)], - sizeof(struct steer_attempt)); + for (i = 0; i < MAX_STEER_HISTORY - 1; i++) { + memcpy(&mapsta->steer_history[i], &mapsta->steer_history[i+1], + sizeof(struct wifi_apsta_steer_history)); } - a = &s->attempts[MAX_LOG_STEER_ATTEMPTS - 1]; + a = &mapsta->steer_history[MAX_STEER_HISTORY - 1]; } else { - a = &s->attempts[s->num_steer_attempts]; + a = &mapsta->steer_history[mapsta->num_steer_hist]; } /* Update SteeringHistory */ @@ -397,19 +398,20 @@ void cntlr_update_sta_steer_counters(struct controller *c, a->trigger = trigger; a->method = method; a->duration = 0; - a->answered = false; - a->auto_bssid = dst_bssid ? false : true; - /* Update SteeringSummaryStats */ - /*TODO: split counter for opportunity & mandate */ - s->stats.btm_attempt_cnt++; + /* Update SteeringSummaryStats - per STA & per Network */ + s->de_sta->mapsta.stats.btm_attempt_cnt++; + c->dlem.network.steer_summary.btm_attempt_cnt++; + + /*TODO: add counter for opportunity (incl blacklis count) */ + /* Record tsp for most recent steer attempt */ - timestamp_update(&s->stats.last_steer_time); - s->num_steer_attempts += 1; + timestamp_update(&s->de_sta->mapsta.stats.last_tsp); + mapsta->num_steer_hist += 1; } static int cntlr_steer_sta(struct controller *c, struct sta *s, - struct steer_target *to, uint32_t mode, + struct wifi_sta_meas_report *to, uint32_t mode, uint32_t reason) { struct cmdu_buff *cmdu; @@ -421,21 +423,22 @@ static int cntlr_steer_sta(struct controller *c, struct sta *s, } if (!memcmp(to->bssid, s->bssid, 6)) { - s->stats.no_candidate_cnt++; + s->de_sta->mapsta.stats.no_candidate_cnt++; + c->dlem.network.steer_summary.no_candidate_cnt++; dbg("%s: " MACFMT " connected to best AP! No steer needed.\n", __func__); return 0; } dbg("%s: Try to steer " MACFMT " from " MACFMT " to " MACFMT "\n", - __func__, MAC2STR(s->macaddr), MAC2STR(s->bssid), MAC2STR(to->bssid)); + __func__, MAC2STR(s->de_sta->macaddr), MAC2STR(s->bssid), MAC2STR(to->bssid)); UNUSED(mode); //TODO UNUSED(reason); cmdu = cntlr_gen_client_steer_request(c, s->fh->agent->alid, s->bssid, 0, - 1, (uint8_t (*)[6])s->macaddr, + 1, (uint8_t (*)[6])s->de_sta->macaddr, 1, (uint8_t (*)[6])to->bssid, 1); /* mandate */ if (!cmdu) { @@ -443,7 +446,7 @@ static int cntlr_steer_sta(struct controller *c, struct sta *s, return -1; } - cntlr_update_sta_steer_counters(c, s->macaddr, s->bssid, to->bssid, + cntlr_update_sta_steer_counters(c, s->de_sta->macaddr, s->bssid, to->bssid, STEER_METHOD_BTM_REQ, STEER_TRIGGER_LINK_QUALITY); send_cmdu(c, cmdu); cmdu_free(cmdu); @@ -459,20 +462,20 @@ static void cntlr_bcn_metrics_parse(struct uloop_timeout *t) struct node *n = s->fh->agent; struct controller *c = n->cntlr; struct netif_iface *bss = NULL; - struct bcn_metrics *b = NULL, *tmp; + struct wifi_sta_meas_report *b = NULL, *tmp; struct steer_sta candidate = { .s = s, .nbrlist = NULL, - .bcnlist = &s->bcnlist, + .meas_reportlist = &s->de_sta->meas_reportlist, .best = NULL, }; int ret; dbg("%s: STA " MACFMT" connected to " MACFMT " in Node " MACFMT"\n", - __func__, MAC2STR(s->macaddr), MAC2STR(s->bssid), MAC2STR(n->alid)); + __func__, MAC2STR(s->de_sta->macaddr), MAC2STR(s->bssid), MAC2STR(n->alid)); - list_for_each_entry_safe(b, tmp, &s->bcnlist, list) { + list_for_each_entry_safe(b, tmp, &s->de_sta->meas_reportlist, list) { dbg("bcn-report from " MACFMT "\n", MAC2STR(b->bssid)); /* Skip entry not in our network */ @@ -496,7 +499,7 @@ static void cntlr_bcn_metrics_parse(struct uloop_timeout *t) switch (candidate.verdict) { case STEER_VERDICT_OK: - if (!timestamp_expired(&s->stats.last_steer_time, STEER_ATTEMPT_MIN_INTV)) { + if (!timestamp_expired(&s->de_sta->mapsta.stats.last_tsp, STEER_ATTEMPT_MIN_INTV)) { dbg("%s: last steer attempt < %us ago; skip steering\n", __func__, STEER_ATTEMPT_MIN_INTV / 1000); return; @@ -519,20 +522,30 @@ static void cntlr_bcn_metrics_parse(struct uloop_timeout *t) dbg("%s exiting\n", __func__); } +/* TODO: deprecate after assoc control steering added */ static void cntlr_init_sta_steer_counters(struct sta *s) { - memset(&s->stats, 0, sizeof(struct steer_stats)); + memset(&s->de_sta->mapsta.stats, 0, sizeof(struct wifi_steer_summary)); /* TODO: implement stats marked as NO_DATA */ - s->stats.blacklist_attempt_cnt = STEER_STATS_NO_DATA; - s->stats.blacklist_success_cnt = STEER_STATS_NO_DATA; - s->stats.blacklist_failure_cnt = STEER_STATS_NO_DATA; - //s->stats.no_candidate_cnt = 0; - //s->stats.btm_attempt_cnt = 0; - //s->stats.btm_success_cnt = 0; - //s->stats.btm_failure_cnt = 0; - //s->stats.btm_query_resp_cnt = 0; - //s->stats.last_steer_time = 0; + s->de_sta->mapsta.stats.blacklist_attempt_cnt = STEER_STATS_NO_DATA; + s->de_sta->mapsta.stats.blacklist_success_cnt = STEER_STATS_NO_DATA; + s->de_sta->mapsta.stats.blacklist_failure_cnt = STEER_STATS_NO_DATA; +} + +struct wifi_sta_element *cntlr_wifi_sta(struct controller *c, + uint8_t *macaddr) +{ + struct wifi_sta_element *wse = NULL; + + wse = calloc(1, sizeof(struct wifi_sta_element)); + if (!wse) + return NULL; + + INIT_LIST_HEAD(&wse->meas_reportlist); + memcpy(wse->macaddr, macaddr, 6); + + return wse; } struct sta *cntlr_add_sta(struct controller *c, uint8_t *macaddr) @@ -547,13 +560,17 @@ struct sta *cntlr_add_sta(struct controller *c, uint8_t *macaddr) if (!s) return NULL; - INIT_LIST_HEAD(&s->bcnlist); INIT_LIST_HEAD(&s->unassoclist); - memcpy(s->macaddr, macaddr, 6); list_add(&s->list, &c->stalist); s->bcn_metrics_timer.cb = cntlr_bcn_metrics_parse; cntlr_init_sta_steer_counters(s); + s->de_sta = cntlr_wifi_sta(c, macaddr); + if (!s->de_sta) { + free(s); + return NULL; + } + return s; } @@ -594,7 +611,7 @@ static void forall_node_get_usta_metrics(struct controller *c) struct cmdu_buff *cmdu; /* TODO: */ - //cmdu = cntlr_gen_unassoc_sta_metric_query(c, s->fh->agent->alid, s->macaddr, + //cmdu = cntlr_gen_unassoc_sta_metric_query(c, s->fh->agent->alid, s->de_sta->macaddr, // opclass, num_metrics, metrics); if (!cmdu) continue; @@ -612,7 +629,7 @@ static void forall_node_get_sta_metrics(struct controller *c) list_for_each_entry(s, &c->stalist, list) { struct cmdu_buff *cmdu; - cmdu = cntlr_gen_sta_metric_query(c, s->fh->agent->alid, s->macaddr); + cmdu = cntlr_gen_sta_metric_query(c, s->fh->agent->alid, s->de_sta->macaddr); if (!cmdu) continue; @@ -1363,6 +1380,8 @@ void node_clean_stalist(struct controller *c) struct sta *s = NULL, *tmp; list_for_each_entry_safe(s, tmp, &c->stalist, list) { + /* FIXME: del s->de_sta->list */ + free(s->de_sta); list_del(&s->list); free(s); } @@ -1416,9 +1435,9 @@ static void cntlr_clean_nodelist(struct controller *c) void free_bcn_metrics(struct controller *c, struct sta *s) { - struct bcn_metrics *b = NULL, *tmp; + struct wifi_sta_meas_report *b = NULL, *tmp; - list_for_each_entry_safe(b, tmp, &s->bcnlist, list) { + list_for_each_entry_safe(b, tmp, &s->de_sta->meas_reportlist, list) { list_del(&b->list); free(b); } @@ -2558,6 +2577,9 @@ void run_controller(void) if (!list_empty(&c->sclist)) cntlr_assign_steer_module_default(c); + /* The counters in MultiAPSteeringSummaryStats are all reset on reboot. */ + memset(&c->dlem.network.steer_summary, 0, sizeof(struct wifi_steer_summary)); + uloop_run(); out_exit: diff --git a/src/cntlr.h b/src/cntlr.h index 7f20da9b..e177d851 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -44,15 +44,6 @@ struct cac_data { uint8_t cac_action; }; -struct bcn_metrics { - uint8_t opclass; - uint8_t channel; - uint8_t rcpi; - uint8_t rsni; - uint8_t bssid[6]; - struct list_head list; -}; - struct bcn_meas_element { uint8_t tag_number; uint8_t tag_length; @@ -90,55 +81,16 @@ struct una_sta_metrics { struct list_head list; }; -struct steer_attempt { - struct timespec time; - uint8_t src_bssid[6]; - uint8_t dst_bssid[6]; - enum steer_trigger trigger; - enum steer_method method; - uint32_t duration; /* seconds */ - bool auto_bssid; - bool answered; -}; - -#define STEER_STATS_NO_DATA 0xffffffffffffffff -struct steer_stats { - /* The maximum value that can be represented as an unsignedLong - * (i.e. 0xffffffffffffffff) indicates that no data is available - * for this parameter. - */ - uint64_t no_candidate_cnt; - uint64_t blacklist_attempt_cnt; - uint64_t blacklist_success_cnt; - uint64_t blacklist_failure_cnt; - uint64_t btm_attempt_cnt; - uint64_t btm_success_cnt; - uint64_t btm_failure_cnt; - uint64_t btm_query_resp_cnt; - /* Reperesents time this Associated Device was last attempted - * to be steered. Calculate delta from now (secs) for reporting - */ - struct timespec last_steer_time; -}; - struct sta { - uint8_t macaddr[6]; uint8_t bssid[6]; - uint16_t conntime; uint32_t time_delta; - uint32_t ul_thput; - uint32_t dl_thput; - uint8_t ul_rcpi; - - //uint8_t num_bcn_metrics; - //struct bcn_metrics bcns[8]; - - struct list_head bcnlist; - /* TODO: tr-181: move UnassociatedSTA to Radio */ + /* TODO: change name to match the data (e.g. umetriclist) */ struct list_head unassoclist; + struct wifi_sta_element *de_sta; + struct netif_iface *fh; /* the AP interface the sta is connected at */ enum device_type type; @@ -146,21 +98,13 @@ struct sta { struct uloop_timeout bcn_metrics_timer; struct timespec last_bcn_metrics_query; - int failed_steer_attempts; - - uint8_t num_steer_attempts; -#define MAX_LOG_STEER_ATTEMPTS 10 - struct steer_attempt attempts[MAX_LOG_STEER_ATTEMPTS]; - - struct steer_stats stats; - struct list_head list; }; /** Latest combined infra metrics data **/ struct bss_metrics { // struct node *n; - // struct list_head list; + // struct wifi_steer_summary list; uint8_t bssid[6]; // bool active; /* for add to list */ uint8_t ch_util; @@ -381,6 +325,8 @@ struct controller { struct list_head sclist; /* steer-control module list */ struct steer_control *sctrl; /* active steer-control module */ + + struct wifi_data_element dlem; /* wifi data elements */ }; struct sta_channel_report { diff --git a/src/cntlr_map.c b/src/cntlr_map.c index c4becee6..31a89004 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -298,7 +298,7 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu) memcpy(s->bssid, bssid, 6); s->fh = fh; - s->conntime = conntime; + s->de_sta->conn_time = conntime; bsta = cntlr_iterate_fbss(c, macaddr); if (bsta) { @@ -308,7 +308,7 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu) bsta->active = true; s->type = IEEE1905; s->agent = bsta->agent; - //s->failed_steer_attempts = 0; + //s->de_sta->mapsta.stats.failed_steer_attempts = 0; //timestamp_reset(s->stats.last_steer_time); } @@ -1237,7 +1237,7 @@ static int cntlr_request_usta_metrics(struct controller *c, for (j = 0; j < r->cur_opclass.opclass_entry_num; j++) { metrics[0].channel = fh->channel; metrics[0].num_sta = 1; - memcpy(metrics[0].sta[0].macaddr, s->macaddr, 6); + memcpy(metrics[0].sta[0].macaddr, s->de_sta->macaddr, 6); usta_cmdu = cntlr_gen_unassoc_sta_metric_query(c, n->alid, r->cur_opclass.opclass_entry[j].opclass, 1, metrics); @@ -1264,7 +1264,7 @@ static void cntlr_request_bcn_metrics_bsta(struct controller *c, struct sta *s) dbg("%s: --->\n", __func__); bcn_cmdu = cntlr_gen_beacon_metrics_query(c, - s->fh->agent->alid, s->macaddr, 0, 0, + s->fh->agent->alid, s->de_sta->macaddr, 0, 0, wildcard, 0, s->fh->ssid, 0, NULL, 0, NULL); if (bcn_cmdu) { @@ -1356,14 +1356,14 @@ static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s) } } - dbg("|%s:%d| alid " MACFMT " s->macaddr " MACFMT " num_report = %d\n", + dbg("|%s:%d| alid " MACFMT " s->de_sta->macaddr " MACFMT " num_report = %d\n", __func__, __LINE__, MAC2STR(s->fh->agent->alid), - MAC2STR(s->macaddr), + MAC2STR(s->de_sta->macaddr), num_report); bcn_cmdu = cntlr_gen_beacon_metrics_query(c, - s->fh->agent->alid, s->macaddr, + s->fh->agent->alid, s->de_sta->macaddr, opclass, channel, wildcard, 0, s->fh->ssid, num_report, reports, 0, NULL); @@ -1382,14 +1382,14 @@ static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s) int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) { - int i; + int i, idx = 0; int offset = 0; struct controller *c = (struct controller *) cntlr; struct tlv *tv[3][16] = { 0 }; struct node *n; struct tlv_policy sta_policy[] = { [0] = { .type = MAP_TLV_ASSOCIATED_STA_LINK_METRICS, .present = TLV_PRESENT_MORE }, - [1] = { .type = MAP_TLV_ERROR_CODE, .present = TLV_PRESENT_MORE }, + [1] = { .type = MAP_TLV_ERROR_CODE, .present = TLV_PRESENT_OPTIONAL_ONE }, [2] = { .type = MAP_TLV_ASSOCIATED_STA_EXT_LINK_METRICS, .present = TLV_PRESENT_MORE } }; @@ -1402,6 +1402,7 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) if (!n) return -1; + /* TODO: use while[0][idx]*/ if (tv[0][0]) { struct sta *s; uint8_t *tv_data = (uint8_t *)tv[0][0]->data; @@ -1420,10 +1421,11 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) (struct assoc_sta_link_metrics_bss *)&tv_data[offset]; memcpy(s->bssid, b->bssid, 6); - s->dl_thput = BUF_GET_BE32(b->dl_thput); - s->ul_thput = BUF_GET_BE32(b->ul_thput); + 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); - s->ul_rcpi = b->ul_rcpi; + /* TODO: update s->de_sta->tsp here */ + s->de_sta->rcpi = b->ul_rcpi; offset += sizeof(*b); } @@ -1436,7 +1438,7 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) if (!rp) return -1; - if (s->type == IEEE1905 && s->ul_rcpi < rp->rcpi_threshold) { + if (s->type == IEEE1905 && s->de_sta->rcpi < rp->rcpi_threshold) { if (!c->cfg.enable_bsta_steer) { dbg("|%s:%d| rcpi below %d, but will not query for any " \ @@ -1454,7 +1456,7 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) /* TODO: set timeout here (?) */ } - } else if (s->type == NON_IEEE1905 && s->ul_rcpi < rp->rcpi_threshold) { + } else if (s->type == NON_IEEE1905 && s->de_sta->rcpi < rp->rcpi_threshold) { if (!c->cfg.enable_sta_steer) { dbg("|%s:%d| rcpi below %d, but will not query for any " \ @@ -1497,6 +1499,39 @@ int handle_sta_link_metrics_response(void *cntlr, struct cmdu_buff *cmdu) } } + idx = 0; + while (tv[2][idx]) { + struct sta *s; + uint8_t *tv_data = (uint8_t *)tv[2][idx]->data; + struct tlv_sta_ext_link_metric *p = + (struct tlv_sta_ext_link_metric *)tv_data; + + s = cntlr_find_sta(c, p->macaddr); + if (!s) + return -1; + + + s = cntlr_find_sta(c, p->macaddr); + if (!s) + return -1; + + offset = sizeof(*p); + for (i = 0; i < p->num_bss; i++) { + struct sta_ext_link_metric_bss *b = + (struct sta_ext_link_metric_bss *)&tv_data[offset]; + + memcpy(s->bssid, b->bssid, 6); + + s->de_sta->dl_rate = BUF_GET_BE32(b->dl_rate); + s->de_sta->ul_rate = BUF_GET_BE32(b->ul_rate); + s->de_sta->dl_utilization = BUF_GET_BE32(b->rx_util); + s->de_sta->ul_utilization = BUF_GET_BE32(b->tx_util); + + offset += sizeof(*b); + } + idx++; + } + return 0; } @@ -1549,7 +1584,7 @@ void cntlr_check_usta_steer(struct controller *c, struct sta *s) } dbg("%s %d for "MACFMT" attached to bssid " MACFMT " node = " \ - MACFMT "\n", __func__, __LINE__, MAC2STR(s->macaddr), + MACFMT "\n", __func__, __LINE__, MAC2STR(s->de_sta->macaddr), MAC2STR(s->bssid), MAC2STR(n->alid)); list_for_each_entry(u, &s->unassoclist, list) { @@ -1588,22 +1623,22 @@ void cntlr_check_usta_steer(struct controller *c, struct sta *s) (s->type == NON_IEEE1905 && !c->cfg.enable_sta_steer)) { trace("|%s:%d| better bssid found, but will not steer "MACFMT",\ because the 'enable_(b)sta_steer' is not set!\n", - __func__, __LINE__, MAC2STR(s->macaddr)); + __func__, __LINE__, MAC2STR(s->de_sta->macaddr)); return; } dbg("%s %d better bssid found! try to steer " MACFMT " \ from " MACFMT " to " MACFMT "\n", __func__, __LINE__, - MAC2STR(s->macaddr), MAC2STR(s->bssid), MAC2STR(best_fh->bssid)); + MAC2STR(s->de_sta->macaddr), MAC2STR(s->bssid), MAC2STR(best_fh->bssid)); if (s->type == IEEE1905) cmdu = cntlr_gen_backhaul_steer_request(c, s->agent->alid, - s->macaddr, best_fh->bssid, 0, 0); + s->de_sta->macaddr, best_fh->bssid, 0, 0); else cmdu = cntlr_gen_client_steer_request(c, s->fh->agent->alid, s->bssid, 0, - 1, (uint8_t (*)[6])s->macaddr, + 1, (uint8_t (*)[6])s->de_sta->macaddr, 1, (uint8_t (*)[6])best_fh->bssid, 1); @@ -1653,6 +1688,7 @@ int handle_unassoc_sta_link_metrics_response(void *cntlr, struct una_sta_metrics *u; struct unassoc_sta_link_metrics_sta *b = (struct unassoc_sta_link_metrics_sta *)&tv_data[offset]; + /* TODO: use wifi_radio_element.unassoc_stalist */ struct sta *s = cntlr_find_sta(c, b->macaddr); if (!s) { @@ -1691,14 +1727,14 @@ int handle_unassoc_sta_link_metrics_response(void *cntlr, return ret; } -struct bcn_metrics *cntlr_find_sta_bcn_metric(struct controller *c, +struct wifi_sta_meas_report *cntlr_find_sta_bcn_metric(struct controller *c, struct sta *s, uint8_t *mac) { - struct bcn_metrics *b = NULL; + struct wifi_sta_meas_report *b = NULL; dbg("%s %d\n", __func__, __LINE__); - list_for_each_entry(b, &s->bcnlist, list) { + list_for_each_entry(b, &s->de_sta->meas_reportlist, list) { dbg("%s %d mac "MACFMT" bssid " MACFMT"\n", __func__, __LINE__, MAC2STR(b->bssid), MAC2STR(mac)); if (!memcmp(b->bssid, mac, 6)) @@ -1755,12 +1791,10 @@ int handle_beacon_metrics_response(void *cntlr, struct cmdu_buff *cmdu) return -1; } - //s->num_bcn_metrics = resp->num_element; - ppos = resp->element; for (i = 0; i < resp->num_element; i++) { struct bcn_meas_element *elem; - struct bcn_metrics *b; + struct wifi_sta_meas_report *b; elem = (struct bcn_meas_element *) ppos; @@ -1783,7 +1817,7 @@ int handle_beacon_metrics_response(void *cntlr, struct cmdu_buff *cmdu) if (!b) continue; - list_add(&b->list, &s->bcnlist); + list_add(&b->list, &s->de_sta->meas_reportlist); memcpy(b->bssid, elem->bssid, 6); } @@ -1799,23 +1833,27 @@ int handle_beacon_metrics_response(void *cntlr, struct cmdu_buff *cmdu) return ret; } -static struct steer_attempt *sta_lookup_steer_attempt(struct sta *s, - uint8_t *src, uint8_t *dst) +static struct wifi_apsta_steer_history *sta_lookup_steer_attempt( + struct sta *s, uint8_t *src, uint8_t *dst) { int i; - int size = (s->num_steer_attempts < MAX_LOG_STEER_ATTEMPTS) ? - s->num_steer_attempts : MAX_LOG_STEER_ATTEMPTS; + uint8_t num_attempts = s->de_sta->mapsta.num_steer_hist; + int size = (num_attempts < MAX_STEER_HISTORY) ? + num_attempts : MAX_STEER_HISTORY; + struct wifi_multiap_sta *mapsta; trace("%s: --->\n", __func__); + mapsta = &s->de_sta->mapsta; + /* Target BSSID is empty (error): use most recent unanswered attempt */ if (!dst) { for (i = size - 1; i >= 0 ; i--) { - if (!s->attempts[i].answered && - !memcmp(s->attempts[i].src_bssid, src, 6)) { + if (!mapsta->steer_history[i].duration && + !memcmp(mapsta->steer_history[i].src_bssid, src, 6)) { dbg("|%s:%d| empty dst bssid - updated first unused attempt!\n", __func__, __LINE__); - return &s->attempts[i]; + return &mapsta->steer_history[i]; } } return NULL; @@ -1826,21 +1864,21 @@ static struct steer_attempt *sta_lookup_steer_attempt(struct sta *s, /* Target BSSID non-empty - lookup attempt based on that */ for (i = 0; i < size; i++) { - if (!s->attempts[i].answered && - !memcmp(s->attempts[i].src_bssid, src, 6) && - !memcmp(s->attempts[i].dst_bssid, dst, 6)) - return &s->attempts[i]; + if (!mapsta->steer_history[i].duration && + !memcmp(mapsta->steer_history[i].src_bssid, src, 6) && + !memcmp(mapsta->steer_history[i].dst_bssid, dst, 6)) + return &mapsta->steer_history[i]; } dbg("|%s:%d| dst "MACFMT" not found on attempt list!\n", __func__, __LINE__, MAC2STR(dst)); - /* Target BSSID not found. Check for auto bssid attempt & ignore dst. */ + /* Target BSSID not found. Check if provided in an attempt */ for (i = 0; i < size; i++) { - if (!s->attempts[i].answered && - !memcmp(s->attempts[i].src_bssid, src, 6) && - s->attempts[i].auto_bssid) - return &s->attempts[i]; + if (!mapsta->steer_history[i].duration && + !memcmp(mapsta->steer_history[i].src_bssid, src, 6) && + !mapsta->steer_history[i].dst_bssid) + return &mapsta->steer_history[i]; } dbg("|%s:%d| auto bssid not found on attempt list!\n", @@ -1858,7 +1896,7 @@ int handle_sta_steer_btm_report(void *cntlr, struct cmdu_buff *cmdu) struct tlv_steer_btm_report *resp; struct tlv *tv[1][16] = {0}; struct sta *s; - struct steer_attempt *attempt; + struct wifi_apsta_steer_history *attempt; int ret = 0; trace("%s: --->\n", __func__); @@ -1891,21 +1929,21 @@ int handle_sta_steer_btm_report(void *cntlr, struct cmdu_buff *cmdu) if (!attempt) dbg("|%s:%d| could not find an attempt matching this btm report\n", __func__, __LINE__); - else - attempt->answered = true; if (resp->status) { - s->failed_steer_attempts++; + s->de_sta->mapsta.stats.failed_steer_attempts++; /* Update Steering Summary Stats */ - s->stats.btm_failure_cnt++; + s->de_sta->mapsta.stats.btm_failure_cnt++; + c->dlem.network.steer_summary.btm_failure_cnt++; if (attempt) /* 'A failed steering attempt will leave this parameter 0' */ attempt->duration = 0; } else { - s->failed_steer_attempts = 0; + s->de_sta->mapsta.stats.failed_steer_attempts = 0; /* Update Steering Summary Stats */ - s->stats.btm_success_cnt++; + s->de_sta->mapsta.stats.btm_success_cnt++; + c->dlem.network.steer_summary.btm_success_cnt++; if (attempt) attempt->duration = timestamp_elapsed_sec(&attempt->time); @@ -1914,7 +1952,8 @@ int handle_sta_steer_btm_report(void *cntlr, struct cmdu_buff *cmdu) /* Number of asynchronous BTM Queries for which a BTM * Request was issued to this Associated Device. */ - s->stats.btm_query_resp_cnt++; + s->de_sta->mapsta.stats.btm_query_resp_cnt++; + c->dlem.network.steer_summary.btm_query_resp_cnt++; return ret; } diff --git a/src/cntlr_ubus.c b/src/cntlr_ubus.c index 01b24f14..823ff46c 100644 --- a/src/cntlr_ubus.c +++ b/src/cntlr_ubus.c @@ -569,29 +569,32 @@ static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj, a = blobmsg_open_array(&bb, "stations"); list_for_each_entry(s, &c->stalist, list) { - struct bcn_metrics *bcn; + struct wifi_sta_meas_report *bcn; void *ttt, *tttt; char stastr[18] = {0}; char bssstr[18] = {0}; - hwaddr_ntoa(s->macaddr, stastr); + hwaddr_ntoa(s->de_sta->macaddr, stastr); hwaddr_ntoa(s->bssid, bssstr); ttt = blobmsg_open_table(&bb, ""); blobmsg_add_string(&bb, "macaddr", stastr); blobmsg_add_string(&bb, "bssid", bssstr); - blobmsg_add_u16(&bb, "conntime", s->conntime); + blobmsg_add_u16(&bb, "conntime", s->de_sta->conn_time); blobmsg_add_u32(&bb, "time_delta", s->time_delta); - blobmsg_add_u32(&bb, "ul_thput", s->ul_thput); - blobmsg_add_u32(&bb, "dl_thput", s->dl_thput); - blobmsg_add_u32(&bb, "ul_rcpi", s->ul_rcpi); + blobmsg_add_u32(&bb, "dl_rate", s->de_sta->dl_rate); + blobmsg_add_u32(&bb, "ul_rate", s->de_sta->ul_rate); + blobmsg_add_u32(&bb, "dl_utilization", s->de_sta->dl_utilization); + blobmsg_add_u32(&bb, "ul_utilization", s->de_sta->ul_utilization); + blobmsg_add_u32(&bb, "dl_est_thput", s->de_sta->dl_est_thput); + blobmsg_add_u32(&bb, "ul_est_thput", s->de_sta->ul_est_thput); + blobmsg_add_u32(&bb, "ul_rcpi", s->de_sta->rcpi); //blobmsg_add_u32(&bb, "last_steer_time", s->stats.last_steer_time); - blobmsg_add_u32(&bb, "failed_steer_attempts", s->failed_steer_attempts); - //blobmsg_add_u16(&bb, "num_bcn_metrics", s->num_bcn_metrics); + blobmsg_add_u32(&bb, "failed_steer_attempts", s->de_sta->mapsta.stats.failed_steer_attempts); - tttt = blobmsg_open_array(&bb, "bcn_metrics"); - list_for_each_entry(bcn, &s->bcnlist, list) { + tttt = blobmsg_open_array(&bb, "meas_reportlist"); + list_for_each_entry(bcn, &s->de_sta->meas_reportlist, list) { void *ttttt; ttttt = blobmsg_open_table(&bb, ""); @@ -697,20 +700,24 @@ static int cntlr_steer_history(struct ubus_context *ctx, struct ubus_object *obj struct tm *info; char macstr[18] = {0}; char str_tm[32] = {0}; + uint8_t num_attempts; int size; int i; - if (!hwaddr_is_zero(macaddr) && memcmp(s->macaddr, macaddr, 6)) + if (!hwaddr_is_zero(macaddr) && + memcmp(s->de_sta->macaddr, macaddr, 6)) continue; t = blobmsg_open_table(&bb, ""); - hwaddr_ntoa(s->macaddr, macstr); + hwaddr_ntoa(s->de_sta->macaddr, macstr); ttt = blobmsg_open_array(&bb, macstr); - size = s->num_steer_attempts < MAX_LOG_STEER_ATTEMPTS ? - s->num_steer_attempts : MAX_LOG_STEER_ATTEMPTS; + num_attempts = s->de_sta->mapsta.num_steer_hist; + size = num_attempts < MAX_STEER_HISTORY ? + num_attempts : MAX_STEER_HISTORY; for (i = 0; i < size; i++) { - struct steer_attempt *attempt = &s->attempts[i]; + struct wifi_apsta_steer_history *attempt = + &s->de_sta->mapsta.steer_history[i]; tttt = blobmsg_open_table(&bb, ""); /* TODO: fix dummy values */ @@ -738,18 +745,6 @@ static int cntlr_steer_history(struct ubus_context *ctx, struct ubus_object *obj return UBUS_STATUS_OK; } -static void cntlr_update_steer_summary(uint64_t *sum, uint64_t elem) -{ - if (*sum == STEER_STATS_NO_DATA) - /* at least one subelement was unspecified */ - return; - - if (elem == STEER_STATS_NO_DATA) - *sum = STEER_STATS_NO_DATA; - else - *sum += elem; -} - static int cntlr_steer_summary(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) @@ -785,80 +780,47 @@ static int cntlr_steer_summary(struct ubus_context *ctx, struct ubus_object *obj blobmsg_add_string(&bb, "macaddr", sta); s = cntlr_find_sta(c, macaddr); - /* TODO: tr-181: store in STA.{i}.MultiAPSTA.SteeringSummaryStats */ if (s) { blobmsg_add_u64(&bb, "fail_no_candidate", - s->stats.no_candidate_cnt); + s->de_sta->mapsta.stats.no_candidate_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_attempts", - s->stats.blacklist_attempt_cnt); + s->de_sta->mapsta.stats.blacklist_attempt_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_success", - s->stats.blacklist_success_cnt); + s->de_sta->mapsta.stats.blacklist_success_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_fail", - s->stats.blacklist_failure_cnt); + s->de_sta->mapsta.stats.blacklist_failure_cnt); blobmsg_add_u64(&bb, "btm_attempts", - s->stats.btm_attempt_cnt); + s->de_sta->mapsta.stats.btm_attempt_cnt); blobmsg_add_u64(&bb, "btm_success", - s->stats.btm_success_cnt); + s->de_sta->mapsta.stats.btm_success_cnt); blobmsg_add_u64(&bb, "btm_fail", - s->stats.btm_failure_cnt); + s->de_sta->mapsta.stats.btm_failure_cnt); blobmsg_add_u64(&bb, "btm_query_resp", - s->stats.btm_query_resp_cnt); + s->de_sta->mapsta.stats.btm_query_resp_cnt); if (!hwaddr_is_zero(macaddr)) blobmsg_add_u32(&bb, "time_since_steer", - timestamp_elapsed_sec(&s->stats.last_steer_time)); + timestamp_elapsed_sec(&s->de_sta->mapsta.stats.last_tsp)); } - } else { - - /* The summary of statistics for Wi-Fi network. */ - - uint64_t sum_no_candidate_cnt = 0; - uint64_t sum_blacklist_attempt_cnt = 0; - uint64_t sum_blacklist_success_cnt = 0; - uint64_t sum_blacklist_failure_cnt = 0; - uint64_t sum_btm_attempt_cnt = 0; - uint64_t sum_btm_success_cnt = 0; - uint64_t sum_btm_failure_cnt = 0; - uint64_t sum_btm_query_resp_cnt = 0; - struct sta *t = NULL; - - /* TODO: tr-181: store in data elements; periodic upd */ - list_for_each_entry(t, &c->stalist, list) { - cntlr_update_steer_summary(&sum_no_candidate_cnt, - t->stats.no_candidate_cnt); - cntlr_update_steer_summary(&sum_blacklist_attempt_cnt, - t->stats.blacklist_attempt_cnt); - cntlr_update_steer_summary(&sum_blacklist_success_cnt, - t->stats.blacklist_success_cnt); - cntlr_update_steer_summary(&sum_blacklist_failure_cnt, - t->stats.blacklist_failure_cnt); - cntlr_update_steer_summary(&sum_btm_attempt_cnt, - t->stats.btm_attempt_cnt); - cntlr_update_steer_summary(&sum_btm_success_cnt, - t->stats.btm_success_cnt); - cntlr_update_steer_summary(&sum_btm_failure_cnt, - t->stats.btm_failure_cnt); - cntlr_update_steer_summary(&sum_btm_query_resp_cnt, - t->stats.btm_query_resp_cnt); - } + /* The summary of statistics per Wi-Fi network. */ blobmsg_add_u64(&bb, "fail_no_candidate", - sum_no_candidate_cnt); + c->dlem.network.steer_summary.no_candidate_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_attempts", - sum_blacklist_attempt_cnt); + c->dlem.network.steer_summary.blacklist_attempt_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_success", - sum_blacklist_success_cnt); + c->dlem.network.steer_summary.blacklist_success_cnt); blobmsg_add_u64(&bb, "assoc_cntlr_fail", - sum_blacklist_failure_cnt); + c->dlem.network.steer_summary.blacklist_failure_cnt); blobmsg_add_u64(&bb, "btm_attempts", - sum_btm_attempt_cnt); + c->dlem.network.steer_summary.btm_attempt_cnt); blobmsg_add_u64(&bb, "btm_success", - sum_btm_success_cnt); + c->dlem.network.steer_summary.btm_success_cnt); blobmsg_add_u64(&bb, "btm_fail", - sum_btm_failure_cnt); + c->dlem.network.steer_summary.btm_failure_cnt); blobmsg_add_u64(&bb, "btm_query_resp", - sum_btm_query_resp_cnt); + c->dlem.network.steer_summary.btm_query_resp_cnt); } ubus_send_reply(ctx, req, bb.head); @@ -1154,12 +1116,12 @@ static void cntlr_update_sta_steering_stats(struct controller *c, uint8_t *bssid } /* No STA provided, request applies to ALL associated STAs */ else if (sta_nr == 0 && bssid_nr == 1) { - struct sta *s; + struct sta *s = NULL; list_for_each_entry(s, &c->stalist, list) { if (!memcmp(s->bssid, bssid, 6)) { cntlr_update_sta_steer_counters(c, - s->macaddr, + s->de_sta->macaddr, bssid, target_bbsid[0], STEER_METHOD_BTM_REQ, diff --git a/src/plugins/steer/rcpi/rcpi.c b/src/plugins/steer/rcpi/rcpi.c index 1c35d47a..1bdb264a 100644 --- a/src/plugins/steer/rcpi/rcpi.c +++ b/src/plugins/steer/rcpi/rcpi.c @@ -32,7 +32,7 @@ static int rcpi_steer_exit(void *priv); int rcpi_steer(void *priv, struct steer_sta *s) { struct rcpi_steer_control *p = (struct rcpi_steer_control *)priv; - struct steer_target *b; + struct wifi_sta_meas_report *b; trace("%s: --------->\n", __func__); UNUSED(p); //TODO @@ -40,11 +40,11 @@ int rcpi_steer(void *priv, struct steer_sta *s) s->verdict = STEER_VERDICT_UNDECIDED; s->reason = 2; //STEER_TRIGGER_LINK_QUALITY - if (list_empty(s->bcnlist)) + if (list_empty(s->meas_reportlist)) return 0; - s->best = list_first_entry(s->bcnlist, struct steer_target, list); - list_for_each_entry(b, s->bcnlist, list) { + s->best = list_first_entry(s->meas_reportlist, struct wifi_sta_meas_report, list); + list_for_each_entry(b, s->meas_reportlist, list) { if ((b->rcpi - s->best->rcpi) > p->diffsnr) { dbg("%s: new best bcn from "MACFMT" with rcpi %d\n", __func__, MAC2STR(b->bssid), b->rcpi); diff --git a/src/steer.h b/src/steer.h index 2f99fa65..52af628e 100644 --- a/src/steer.h +++ b/src/steer.h @@ -15,6 +15,8 @@ #include <stdint.h> #include <libubox/list.h> +#include "wifi_dataelements.h" + #ifdef __cplusplus extern "C" { #endif @@ -43,21 +45,12 @@ struct steer_config { uint8_t ch_utilization; }; -struct steer_target { - uint8_t opclass; - uint8_t channel; - uint8_t rcpi; - uint8_t rsni; - uint8_t bssid[6]; - struct list_head list; -}; - struct steer_sta { struct sta *s; struct list_head *nbrlist; - struct list_head *bcnlist; + struct list_head *meas_reportlist; steer_verdict_t verdict; - struct steer_target *best; + struct wifi_sta_meas_report *best; uint32_t reason; uint32_t mode; }; diff --git a/src/wifi_dataelements.h b/src/wifi_dataelements.h index a5e89e44..7516869e 100644 --- a/src/wifi_dataelements.h +++ b/src/wifi_dataelements.h @@ -84,8 +84,20 @@ struct ip_address { struct wifi_sta_meas_report { struct list_head list; - size_t len; - uint8_t *data; + + uint8_t opclass; + uint8_t channel; + uint64_t meas_start_time; + uint16_t meas_duration; + uint8_t rfi; /* Reported Frame Information */ + uint8_t rcpi; + uint8_t rsni; + uint8_t bssid[6]; + //uint8_t antena_id; + //uint32_t parent_tsf; + + uint32_t num_opt_subelem; + uint8_t optional[]; }; struct wifi_opclass_channels { @@ -198,6 +210,11 @@ struct wifi_opclass_disallowed_element { uint8_t *chanlist; }; +/* The maximum value that can be represented as an unsignedLong + * (i.e. 0xffffffffffffffff) indicates that no data is available + * for this parameter. + */ +#define STEER_STATS_NO_DATA UINT64_MAX struct wifi_steer_summary { uint64_t no_candidate_cnt; uint64_t blacklist_attempt_cnt; @@ -207,11 +224,15 @@ struct wifi_steer_summary { uint64_t btm_success_cnt; uint64_t btm_failure_cnt; uint64_t btm_query_resp_cnt; -}; -struct wifi_apsta_steer_summary { - struct wifi_steer_summary summary; - uint32_t time_since_steer; + /* Reperesents time Associated Device was last attempted to be + * Note: Calculate delta from now (secs) for reporting. + * Note: field not used for per Network statistics. + */ + struct timespec last_tsp; + + /* Private fields */ + int failed_steer_attempts; }; enum steer_trigger { @@ -230,20 +251,21 @@ enum steer_method { struct wifi_apsta_steer_history { struct list_head list; struct timespec time; - uint8_t origin_bssid[6]; + uint8_t src_bssid[6]; enum steer_trigger trigger; enum steer_method method; uint8_t dst_bssid[6]; + /* Failed attempt will leave this 0 */ uint32_t duration; /* seconds */ }; struct wifi_multiap_sta { time_t assoc_time; uint8_t anpi; /* avg noise to power indicator */ - struct wifi_apsta_steer_summary steer_summary; - + struct wifi_steer_summary stats; +#define MAX_STEER_HISTORY 10 uint8_t num_steer_hist; - struct list_head steer_history; /* list of wifi_apsta_steer_history */ + struct wifi_apsta_steer_history steer_history[MAX_STEER_HISTORY]; }; struct wifi_sta_element { @@ -277,7 +299,7 @@ struct wifi_sta_element { size_t reassoc_framelen; uint8_t *reassoc_frame; struct list_head tid_qsizelist; /* list of wifi_tid_queuesize */ - struct wifi_multiap_sta multi_apsta; + struct wifi_multiap_sta mapsta; }; struct wifi_multiap_steering { -- GitLab