diff --git a/src/wifi_ubus.c b/src/wifi_ubus.c index 74130cbb9f3113cc20943ad0f5bc5680246fa288..b2a6db9dd9d16fb7dfe93c5a823e47b87e44df70 100644 --- a/src/wifi_ubus.c +++ b/src/wifi_ubus.c @@ -1812,10 +1812,51 @@ struct get_stas_ctx { int status; }; +static int caps_bitmap_hex_to_byte_array(const char *bitmap, uint8_t *cbitmap) +{ + int hex_len = strlen(bitmap); + int byte_len = sizeof(cbitmap); + int i; + + if (hex_len / 2 != byte_len) + /* capabilities string has unexpected length */ + return -1; + + for (i = 0; i < byte_len; i++) { + int ret; + + ret = sscanf(bitmap + (2 * i), "%2hhx", &cbitmap[i]); + if (ret != 1) + return -1; + } + + return 0; +} + 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 ret = 0; + + /* 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; + + ret = caps_bitmap_hex_to_byte_array(blobmsg_get_string(caps_tb[0]), cbitmap); + if (ret < 0) + return -1; + + caps->valid |= WIFI_CAP_RM_VALID; return 0; } @@ -1963,7 +2004,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 +2211,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])