diff --git a/src/cntlr.c b/src/cntlr.c index 618d3cf5778850df0ebc5a1bc77322ab589766f9..94f5fe9a641a639d6afc40983d2ee4eedeb3fee2 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 7f20da9bb22052c0d3f41b43fe999ef9c9401c22..e177d8511dbdd05f9fb14ecd27396e928f3a8260 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 c4becee6e00bbee503f87849f4b72c32c7b17ef8..31a89004b6b7891a77b069431c4f37f48d6bc611 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 01b24f14f8376a73b0c928b3baf38c4ec6b6f164..823ff46ce728b00cf5646829d80be21c3d3d38d6 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 1c35d47a4ea2c0233a22793e008f7549409504ba..1bdb264aeb753703a51d85bdc96e320257911d67 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 2f99fa656ef0348a624918cc2ef75c81d00999e1..52af628e68b4632eea5d9ba3cd6ec1a8b7d7e256 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 a5e89e441e1fe2b8bbefb03d272a3455c4d90f5d..7516869ee6404884bbff8c99132af162b166a1ef 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 {