diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 9b7dff218..a1e3bc96c 100644 --- a/doc/dbus.doxygen +++ b/doc/dbus.doxygen @@ -644,8 +644,8 @@ scan results.

Frequency of the BSS in MHz.

  • -

    MaxRate - q - (read)

    -

    Maximal data rate of the BSS in bits per second.

    +

    Rates - au - (read)

    +

    Descending ordered array of rates supported by the BSS in bits per second.

  • Signal - n - (read)

    diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index a125ca182..bd8d06195 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -434,3 +434,27 @@ int wpa_bss_get_max_rate(const struct wpa_bss *bss) return rate; } + + +int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates) +{ + const u8 *ie, *ie2; + int i, j, len; + + ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES); + ie2 = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); + + len = (ie ? ie[1] : 0) + (ie2 ? ie2[1] : 0); + + *rates = os_malloc(len); + if (!rates) + return -1; + + for (i = 0; ie && i < ie[1]; i++) + (*rates)[i] = ie[i + 2] & 0x7f; + + for (j = 0; ie2 && j < ie2[1]; j++) + (*rates)[i + j] = ie2[j + 2] & 0x7f; + + return len; +} diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index d6e061350..2fa4863a2 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -40,7 +40,7 @@ struct wpa_scan_res; * @noise: noise level * @level: signal level * @tsf: Timestamp of last Beacon/Probe Response frame - * @last_update: Time of the last update (i.e., Beacon or Probe Response RX) + * @last_update: Time of the last update (i.e., Beacon or Probe Response RX) * @ie_len: length of the following IE field in octets * * This structure is used to store information about neighboring BSSes in @@ -85,5 +85,6 @@ const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type); struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss, u32 vendor_type); int wpa_bss_get_max_rate(const struct wpa_bss *bss); +int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates); #endif /* BSS_H */ diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index ce6332560..41f9743f0 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -1072,8 +1072,8 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { NULL, R }, - { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate, + { "Rates", WPAS_DBUS_NEW_IFACE_BSSID, "au", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates, NULL, R }, diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index f118e26e3..cbcd8fa72 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -2505,29 +2505,58 @@ DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, } +static int cmp_u8s_desc(const void *a, const void *b) +{ + return (*(u8 *) b - *(u8 *) a); +} + + /** - * wpas_dbus_getter_bss_max_rate - Return the maximal rate of a BSS + * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS * @message: Pointer to incoming dbus message * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the maximal data rate of requested bss + * Returns: a dbus message containing sorted array of bit rates * - * Getter for "MaxRate" property. + * Getter for "Rates" property. */ -DBusMessage * wpas_dbus_getter_bss_max_rate(DBusMessage *message, +DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, struct bss_handler_args *bss) { + DBusMessage *reply; struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); - int max_rate; + u8 *ie_rates = NULL; + u32 *real_rates; + int rates_num, i; if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_max_rate[dbus]: " + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: " "no bss with id %d found", bss->id); return NULL; } - max_rate = wpa_bss_get_max_rate(res); - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16, - &max_rate); + rates_num = wpa_bss_get_bit_rates(res, &ie_rates); + if (rates_num < 0) + return NULL; + + qsort(ie_rates, rates_num, 1, cmp_u8s_desc); + + real_rates = os_malloc(sizeof(u32) * rates_num); + if (!real_rates) { + os_free(ie_rates); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + for (i = 0; i < rates_num; i++) + real_rates[i] = ie_rates[i] * 500000; + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_UINT32, + real_rates, rates_num); + + os_free(ie_rates); + os_free(real_rates); + return reply; } diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index af63a7f87..a05c1ad9c 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -151,8 +151,8 @@ DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, struct bss_handler_args *bss); -DBusMessage * wpas_dbus_getter_bss_max_rate(DBusMessage *message, - struct bss_handler_args *bss); +DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, + struct bss_handler_args *bss); DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message, struct bss_handler_args *bss); diff --git a/wpa_supplicant/examples/wpas-dbus-new.py b/wpa_supplicant/examples/wpas-dbus-new.py index b9714bd97..11d6e494f 100755 --- a/wpa_supplicant/examples/wpas-dbus-new.py +++ b/wpa_supplicant/examples/wpas-dbus-new.py @@ -66,9 +66,12 @@ def showBss(bss): dbus_interface=dbus.PROPERTIES_IFACE) signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal', dbus_interface=dbus.PROPERTIES_IFACE) - val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'MaxRate', + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates', dbus_interface=dbus.PROPERTIES_IFACE) - maxrate = val / 1000000 + if len(val) > 0: + maxrate = val[0] / 1000000 + else: + maxrate = 0 print " %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq)