diff --git a/src/agent.c b/src/agent.c index 1ec43cceca7a396015e56c966a8e04edada0f64f..10e0506ddb6a4437d218792b821a0ec9969e4134 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1287,8 +1287,24 @@ static int update_sta_entry(struct agent *a, struct netif_ap *ap, struct wifi_st s->rx_fail_pkts = e->stats.rx_fail_pkts; s->rtx_pkts = e->stats.tx_retry_pkts; - memcpy(s->bssid, e->bssid, 6); + + if (!!(e->caps.valid & WIFI_CAP_RM_VALID)) { + if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_ACTIVE)) { + s->rrm_mode |= NBR_PARAM_BCN_ACTIVE; + s->supports_bcnreport = true; + } + + if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_PASSIVE)) { + s->rrm_mode |= NBR_PARAM_BCN_PASSIVE; + s->supports_bcnreport = true; + } + + if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_TABLE)) { + s->rrm_mode |= NBR_PARAM_BCN_TABLE; + s->supports_bcnreport = true; + } + } #ifdef UBUS_STA_INFO wifiagent_log_stainfo(ap->agent, s); #endif @@ -1301,7 +1317,8 @@ static int update_sta_entry(struct agent *a, struct netif_ap *ap, struct wifi_st static int agent_req_beacon_metrics(struct agent *a, struct netif_ap *ap, uint8_t *sta_addr, uint8_t opclass, - uint8_t channel, uint8_t *bssid, uint8_t reporting_detail, + uint8_t channel, uint8_t *bssid, + uint8_t rrm_mode, uint8_t reporting_detail, uint8_t ssid_len, char *ssid, uint8_t num_report, uint8_t *report, uint8_t num_element, uint8_t *element) { @@ -1322,6 +1339,7 @@ static int agent_req_beacon_metrics(struct agent *a, param.report = report; param.num_element = num_element; param.element = element; + param.rrm_mode = rrm_mode; return wifi_req_neighbor(ap->ifname, sta_addr, ¶m); } @@ -1346,6 +1364,7 @@ static void wifi_sta_bcn_req(atimer_t *t) agent_req_beacon_metrics(a, breq->ap, s->macaddr, breq->opclass, breq->channel, breq->bssid, + s->rrm_mode, breq->reporting_detail, breq->ssid_len, breq->ssid, 0, NULL, breq->num_element, breq->element); diff --git a/src/agent.h b/src/agent.h index 48f944f4789f6bbab99eb41d5cd8860a1c5db299..b8814114646c6179b644405e02c7f228a58d7f4b 100644 --- a/src/agent.h +++ b/src/agent.h @@ -494,6 +494,7 @@ struct sta { int inform_leaving; /** flag indicating leaving BSS */ bool wait_for_cntlr_nbr; /** awaiting pref nbr from cntlr */ bool supports_bcnreport; /** supports 11K beacon reporting */ + uint8_t rrm_mode; /** bitmap for ACTIVE/PASSIVE/TABLE */ atimer_t sta_timer; /** periodic run */ atimer_t sta_bcn_req_timer; /** enqueue bcn requests */ struct list_head sta_nbrlist; /** neighbor BSSs as seen by this STA */ diff --git a/src/wifi.h b/src/wifi.h index 66575bf94236d8e3175f7ae4cae779f1a31f4691..ed926e4fa5a2480d68d2fa0b7b062bf602de05d0 100644 --- a/src/wifi.h +++ b/src/wifi.h @@ -49,10 +49,17 @@ struct wifi_radio_status { uint32_t bandwidth; }; +enum nbr_param_bcn_mode { + NBR_PARAM_BCN_ACTIVE = 1 << 0, + NBR_PARAM_BCN_PASSIVE = 1 << 1, + NBR_PARAM_BCN_TABLE = 1 << 2, +}; + struct wifi_request_neighbor_param { uint8_t opclass; uint8_t channel; uint8_t *bssid; + uint8_t rrm_mode; uint8_t reporting_detail; uint8_t ssid_len; char *ssid; diff --git a/src/wifi_ubus.c b/src/wifi_ubus.c index 74130cbb9f3113cc20943ad0f5bc5680246fa288..47f6e6fd7de61f60282e8d75d427899e8ca810bd 100644 --- a/src/wifi_ubus.c +++ b/src/wifi_ubus.c @@ -1718,10 +1718,16 @@ int wifi_ubus_req_neighbor(struct ubus_context *ubus_ctx, const char *ifname, blobmsg_add_string(&bb, "bssid", bssid_macstr); } - /* TODO: revisit */ - /* Set mode to PASSIVE/100ms explicitly */ + /* Start with passive mode by default */ blobmsg_add_string(&bb, "mode", "passive"); blobmsg_add_u32(&bb, "duration", 100); + if (!(param->rrm_mode & NBR_PARAM_BCN_PASSIVE)) { + /* passive not supported, check for active but keep passive otherwise */ + if (param->rrm_mode & NBR_PARAM_BCN_ACTIVE) { + blobmsg_add_string(&bb, "mode", "active"); + blobmsg_add_u32(&bb, "duration", 20); + } + } if (param->reporting_detail) blobmsg_add_u32(&bb, "reporting_detail", param->reporting_detail); @@ -1813,9 +1819,29 @@ struct get_stas_ctx { }; static int wifi_ubus_get_sta_caps(struct blob_attr *msg, - struct wifi_caps *caps) + struct wifi_caps *caps, uint8_t *cbitmap) { - /* TODO fill caps */ + static const struct blobmsg_policy caps_policy[] = { + [0] = { .name = "bitmap", .type = BLOBMSG_TYPE_STRING }, + }; + struct blob_attr *caps_tb[ARRAY_SIZE(caps_policy)]; + int len; + + /* TODO: only updating cbitmap here, update caps (may be redundant) */ + + blobmsg_parse(caps_policy, ARRAY_SIZE(caps_policy), caps_tb, + blobmsg_data(msg), blobmsg_data_len(msg)); + + caps->valid &= ~WIFI_CAP_RM_VALID; + + if (!caps_tb[0]) + return -1; + + len = strlen(blobmsg_get_string(caps_tb[0])); + if (!strtob(blobmsg_get_string(caps_tb[0]), len / 2, cbitmap)) + return -1; + + caps->valid |= WIFI_CAP_RM_VALID; return 0; } @@ -1963,7 +1989,7 @@ static int wifi_ubus_parse_sta(struct blob_attr *cur, sta->est_tx_thput = blobmsg_get_u32(sta_tb[14]); wifi_ubus_get_sta_rssi(sta_tb[12], sta->rssi, sizeof(sta->rssi)); - wifi_ubus_get_sta_caps(sta_tb[10], &sta->caps); + wifi_ubus_get_sta_caps(sta_tb[10], &sta->caps, sta->cbitmap); wifi_ubus_get_sta_stats(sta_tb[4], sta, &sta->stats); if (sta_tb[16]) wifi_ubus_get_sta_rate(sta_tb[16], &sta->tx_rate); @@ -2170,7 +2196,7 @@ static void wifi_sta_parse_mlo_links(struct ubus_request *req, sta->est_tx_thput = blobmsg_get_u32(sta_tb[15]); wifi_ubus_get_sta_rssi(sta_tb[13], sta->rssi, sizeof(sta->rssi)); - wifi_ubus_get_sta_caps(sta_tb[11], &sta->caps); + wifi_ubus_get_sta_caps(sta_tb[11], &sta->caps, sta->cbitmap); if (sta_tb[16]) wifi_ubus_get_sta_rate(sta_tb[16], &sta->tx_rate); if (sta_tb[17])