From 0bd7f104c16af43fb1f5a678ddefe5a46ed49463 Mon Sep 17 00:00:00 2001 From: Bhagavathi Perumal S Date: Fri, 3 Nov 2017 10:44:15 +0530 Subject: [PATCH] hostapd: Add supported rate information into STATUS and STA These allow external programs to determine supported legacy, HT, and VHT rates of an interface or a STA. Signed-off-by: Bhagavathi Perumal S --- src/ap/ctrl_iface_ap.c | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index bb3efa60b..74d3a2577 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -26,6 +26,30 @@ #include "taxonomy.h" +static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, + size_t curr_len, const u8 *mcs_set) +{ + int ret; + size_t len = curr_len; + + ret = os_snprintf(buf + len, buflen - len, + "ht_mcs_bitmask="); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + + /* 77 first bits (+ 3 reserved bits) */ + len += wpa_snprintf_hex(buf + len, buflen - len, mcs_set, 10); + + ret = os_snprintf(buf + len, buflen - len, "\n"); + if (os_snprintf_error(buflen - len, ret)) + return curr_len; + len += ret; + + return len; +} + + static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd, struct sta_info *sta, char *buf, size_t buflen) @@ -111,6 +135,24 @@ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd, if (!os_snprintf_error(buflen - len, ret)) len += ret; + if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) { + ret = os_snprintf(buf + len, buflen - len, + "rx_vht_mcs_map=%04x\n" + "tx_vht_mcs_map=%04x\n", + le_to_host16(sta->vht_capabilities-> + vht_supported_mcs_set.rx_map), + le_to_host16(sta->vht_capabilities-> + vht_supported_mcs_set.tx_map)); + if (!os_snprintf_error(buflen - len, ret)) + len += ret; + } + + if ((sta->flags & WLAN_STA_HT) && sta->ht_capabilities) { + len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, + sta->ht_capabilities-> + supported_mcs_set); + } + return len; } @@ -676,6 +718,19 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, len += ret; } + if (iface->conf->ieee80211ac && !hapd->conf->disable_11ac && mode) { + u16 rxmap = WPA_GET_LE16(&mode->vht_mcs_set[0]); + u16 txmap = WPA_GET_LE16(&mode->vht_mcs_set[4]); + + ret = os_snprintf(buf + len, buflen - len, + "rx_vht_mcs_map=%04x\n" + "tx_vht_mcs_map=%04x\n", + rxmap, txmap); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + } + if (iface->conf->ieee80211n && !hapd->conf->disable_11n) { ret = os_snprintf(buf + len, buflen - len, "ht_caps_info=%04x\n", @@ -685,6 +740,31 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, len += ret; } + if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) { + len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, + mode->mcs_set); + } + + if (iface->current_rates && iface->num_rates) { + ret = os_snprintf(buf + len, buflen - len, "supported_rates="); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + + for (j = 0; j < iface->num_rates; j++) { + ret = os_snprintf(buf + len, buflen - len, "%s%02x", + j > 0 ? " " : "", + iface->current_rates[j].rate / 5); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + } + ret = os_snprintf(buf + len, buflen - len, "\n"); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + } + for (j = 0; mode && j < mode->num_channels; j++) { if (mode->channels[j].freq == iface->freq) { ret = os_snprintf(buf + len, buflen - len,