usteer: track RRM and BSS-TM support per connection

BSS transition management as well as RRM capabilities have to be
considered not for the STA but per STA connection.

Most prominently, a STA might not support BSS-TM when connected without
PMF.

Signed-off-by: David Bauer <mail@david-bauer.net>
This commit is contained in:
David Bauer
2022-02-19 01:07:47 +01:00
parent 6ec60fc370
commit 98247d1eda
4 changed files with 17 additions and 26 deletions

View File

@@ -344,7 +344,7 @@ usteer_local_node_assoc_update(struct sta_info *si, struct blob_attr *data)
} }
static void static void
usteer_local_node_update_sta_rrm_wnm(const uint8_t *addr, struct blob_attr *client_attr) usteer_local_node_update_sta_rrm_wnm(struct sta_info *si, struct blob_attr *client_attr)
{ {
static const struct blobmsg_policy rrm_policy = { static const struct blobmsg_policy rrm_policy = {
.name = "rrm", .name = "rrm",
@@ -355,24 +355,15 @@ usteer_local_node_update_sta_rrm_wnm(const uint8_t *addr, struct blob_attr *clie
.type = BLOBMSG_TYPE_ARRAY, .type = BLOBMSG_TYPE_ARRAY,
}; };
struct blob_attr *rrm_blob = NULL, *wnm_blob = NULL, *cur; struct blob_attr *rrm_blob = NULL, *wnm_blob = NULL, *cur;
struct sta *sta;
int rem; int rem;
int i = 0; int i = 0;
if (!addr)
return;
/* Don't create the STA */
sta = usteer_sta_get(addr, false);
if (!sta)
return;
/* RRM */ /* RRM */
blobmsg_parse(&rrm_policy, 1, &rrm_blob, blobmsg_data(client_attr), blobmsg_data_len(client_attr)); blobmsg_parse(&rrm_policy, 1, &rrm_blob, blobmsg_data(client_attr), blobmsg_data_len(client_attr));
if (!rrm_blob) if (!rrm_blob)
return; return;
sta->rrm = blobmsg_get_u32(blobmsg_data(rrm_blob)); si->rrm = blobmsg_get_u32(blobmsg_data(rrm_blob));
/* Extended Capabilities / WNM */ /* Extended Capabilities / WNM */
blobmsg_parse(&ext_capa_policy, 1, &wnm_blob, blobmsg_data(client_attr), blobmsg_data_len(client_attr)); blobmsg_parse(&ext_capa_policy, 1, &wnm_blob, blobmsg_data(client_attr), blobmsg_data_len(client_attr));
@@ -385,7 +376,7 @@ usteer_local_node_update_sta_rrm_wnm(const uint8_t *addr, struct blob_attr *clie
if (i == 2) { if (i == 2) {
if (blobmsg_get_u32(cur) & (1 << 3)) if (blobmsg_get_u32(cur) & (1 << 3))
sta->bss_transition = true; si->bss_transition = true;
} }
i++; i++;
@@ -432,7 +423,7 @@ usteer_local_node_set_assoc(struct usteer_local_node *ln, struct blob_attr *cl)
} }
/* Read RRM information */ /* Read RRM information */
usteer_local_node_update_sta_rrm_wnm(addr, cur); usteer_local_node_update_sta_rrm_wnm(si, cur);
} }
node->n_assoc = n_assoc; node->n_assoc = n_assoc;

8
sta.c
View File

@@ -210,15 +210,15 @@ usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr,
} }
bool bool
usteer_sta_supports_beacon_measurement_mode(struct sta *sta, enum usteer_beacon_measurement_mode mode) usteer_sta_supports_beacon_measurement_mode(struct sta_info *si, enum usteer_beacon_measurement_mode mode)
{ {
switch (mode) { switch (mode) {
case BEACON_MEASUREMENT_PASSIVE: case BEACON_MEASUREMENT_PASSIVE:
return sta->rrm & (1 << 4); return si->rrm & (1 << 4);
case BEACON_MEASUREMENT_ACTIVE: case BEACON_MEASUREMENT_ACTIVE:
return sta->rrm & (1 << 5); return si->rrm & (1 << 5);
case BEACON_MEASUREMENT_TABLE: case BEACON_MEASUREMENT_TABLE:
return sta->rrm & (1 << 6); return si->rrm & (1 << 6);
} }
return false; return false;

10
ubus.c
View File

@@ -423,16 +423,16 @@ usteer_ubus_get_connected_clients(struct ubus_context *ctx, struct ubus_object *
/* Beacon measurement modes */ /* Beacon measurement modes */
a = blobmsg_open_array(&b, "beacon-measurement-modes"); a = blobmsg_open_array(&b, "beacon-measurement-modes");
if (usteer_sta_supports_beacon_measurement_mode(si->sta, BEACON_MEASUREMENT_PASSIVE)) if (usteer_sta_supports_beacon_measurement_mode(si, BEACON_MEASUREMENT_PASSIVE))
blobmsg_add_string(&b, "", "PASSIVE"); blobmsg_add_string(&b, "", "PASSIVE");
if (usteer_sta_supports_beacon_measurement_mode(si->sta, BEACON_MEASUREMENT_ACTIVE)) if (usteer_sta_supports_beacon_measurement_mode(si, BEACON_MEASUREMENT_ACTIVE))
blobmsg_add_string(&b, "", "ACTIVE"); blobmsg_add_string(&b, "", "ACTIVE");
if (usteer_sta_supports_beacon_measurement_mode(si->sta, BEACON_MEASUREMENT_TABLE)) if (usteer_sta_supports_beacon_measurement_mode(si, BEACON_MEASUREMENT_TABLE))
blobmsg_add_string(&b, "", "TABLE"); blobmsg_add_string(&b, "", "TABLE");
blobmsg_close_array(&b, a); blobmsg_close_array(&b, a);
/* BSS-Transition support */ /* BSS-Transition support */
blobmsg_add_u8(&b, "bss-transition-management", si->sta->bss_transition); blobmsg_add_u8(&b, "bss-transition-management", si->bss_transition);
/* Measurements */ /* Measurements */
a = blobmsg_open_array(&b, "measurements"); a = blobmsg_open_array(&b, "measurements");
@@ -664,7 +664,7 @@ int usteer_ubus_trigger_client_scan(struct sta_info *si)
{ {
struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node); struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node);
if (!usteer_sta_supports_beacon_measurement_mode(si->sta, BEACON_MEASUREMENT_ACTIVE)) { if (!usteer_sta_supports_beacon_measurement_mode(si, BEACON_MEASUREMENT_ACTIVE)) {
MSG(DEBUG, "STA does not support beacon measurement sta=" MAC_ADDR_FMT "\n", MAC_ADDR_DATA(si->sta->addr)); MSG(DEBUG, "STA does not support beacon measurement sta=" MAC_ADDR_FMT "\n", MAC_ADDR_DATA(si->sta->addr));
return 0; return 0;
} }

View File

@@ -238,6 +238,9 @@ struct sta_info {
uint64_t last_connected; uint64_t last_connected;
int signal; int signal;
uint8_t rrm;
bool bss_transition;
enum roam_trigger_state roam_state; enum roam_trigger_state roam_state;
uint8_t roam_tries; uint8_t roam_tries;
uint64_t roam_event; uint64_t roam_event;
@@ -267,9 +270,6 @@ struct sta {
uint8_t seen_5ghz : 1; uint8_t seen_5ghz : 1;
uint8_t addr[6]; uint8_t addr[6];
uint8_t rrm;
bool bss_transition;
}; };
struct usteer_beacon_report { struct usteer_beacon_report {
@@ -327,7 +327,7 @@ int usteer_ubus_bss_transition_request(struct sta_info *si,
struct sta *usteer_sta_get(const uint8_t *addr, bool create); struct sta *usteer_sta_get(const uint8_t *addr, bool create);
struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create); struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create);
bool usteer_sta_supports_beacon_measurement_mode(struct sta *sta, enum usteer_beacon_measurement_mode mode); bool usteer_sta_supports_beacon_measurement_mode(struct sta_info *si, enum usteer_beacon_measurement_mode mode);
void usteer_sta_disconnected(struct sta_info *si); void usteer_sta_disconnected(struct sta_info *si);
void usteer_sta_info_update_timeout(struct sta_info *si, int timeout); void usteer_sta_info_update_timeout(struct sta_info *si, int timeout);