From 790709060dd6d31fe4ae951f9cc7eb7fca2299b4 Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Mon, 1 Sep 2014 00:23:39 -0400 Subject: [PATCH] mesh: Add scan result for mesh network Android 4.4 uses "BSS" command instead of "SCAN_RESULT" command. So this patch add the mesh scan result for BSS command. Signed-off-by: Masashi Honma --- src/common/wpa_ctrl.h | 1 + wpa_supplicant/ctrl_iface.c | 11 +++++ wpa_supplicant/mesh.c | 94 +++++++++++++++++++++++++++++++++++++ wpa_supplicant/mesh.h | 2 + 4 files changed, 108 insertions(+) diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index a91cc38fd..65e6ff1fc 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -248,6 +248,7 @@ extern "C" { #define WPA_BSS_MASK_INTERNETW BIT(15) #define WPA_BSS_MASK_WIFI_DISPLAY BIT(16) #define WPA_BSS_MASK_DELIM BIT(17) +#define WPA_BSS_MASK_MESH_SCAN BIT(18) /* VENDOR_ELEM_* frame id values */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index b7eeb14cb..1e4196238 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -47,6 +47,7 @@ #include "wnm_sta.h" #include "offchannel.h" #include "drivers/driver.h" +#include "mesh.h" static int wpa_supplicant_global_iface_list(struct wpa_global *global, char *buf, int len); @@ -3868,6 +3869,16 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } #endif /* CONFIG_INTERWORKING */ +#ifdef CONFIG_MESH + if (mask & WPA_BSS_MASK_MESH_SCAN) { + ie = (const u8 *) (bss + 1); + ret = wpas_mesh_scan_result_text(ie, bss->ie_len, pos, end); + if (ret < 0 || ret >= end - pos) + return 0; + pos += ret; + } +#endif /* CONFIG_MESH */ + if (mask & WPA_BSS_MASK_DELIM) { ret = os_snprintf(pos, end - pos, "====\n"); if (ret < 0 || ret >= end - pos) diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index 1ff8dac34..23108ba07 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -375,3 +375,97 @@ int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s) return ret; } + + +static int mesh_attr_text(const u8 *ies, size_t ies_len, char *buf, char *end) +{ + struct ieee802_11_elems elems; + char *mesh_id, *pos = buf; + u8 *bss_basic_rate_set; + int bss_basic_rate_set_len, ret, i; + + if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) + return -1; + + if (elems.mesh_id_len < 1) + return 0; + + mesh_id = os_malloc(elems.mesh_id_len + 1); + if (mesh_id == NULL) + return -1; + + os_memcpy(mesh_id, elems.mesh_id, elems.mesh_id_len); + mesh_id[elems.mesh_id_len] = '\0'; + ret = os_snprintf(pos, end - pos, "mesh_id=%s\n", mesh_id); + os_free(mesh_id); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + + if (elems.mesh_config_len > 6) { + ret = os_snprintf(pos, end - pos, + "active_path_selection_protocol_id=0x%02x\n" + "active_path_selection_metric_id=0x%02x\n" + "congestion_control_mode_id=0x%02x\n" + "synchronization_method_id=0x%02x\n" + "authentication_protocol_id=0x%02x\n" + "mesh_formation_info=0x%02x\n" + "mesh_capability=0x%02x\n", + elems.mesh_config[0], elems.mesh_config[1], + elems.mesh_config[2], elems.mesh_config[3], + elems.mesh_config[4], elems.mesh_config[5], + elems.mesh_config[6]); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + } + + bss_basic_rate_set = os_malloc(elems.supp_rates_len + + elems.ext_supp_rates_len); + if (bss_basic_rate_set == NULL) + return -1; + + bss_basic_rate_set_len = 0; + for (i = 0; i < elems.supp_rates_len; i++) { + if (elems.supp_rates[i] & 0x80) { + bss_basic_rate_set[bss_basic_rate_set_len++] = + (elems.supp_rates[i] & 0x7f) * 5; + } + } + for (i = 0; i < elems.ext_supp_rates_len; i++) { + if (elems.ext_supp_rates[i] & 0x80) { + bss_basic_rate_set[bss_basic_rate_set_len++] = + (elems.ext_supp_rates[i] & 0x7f) * 5; + } + } + if (bss_basic_rate_set_len > 0) { + ret = os_snprintf(pos, end - pos, "bss_basic_rate_set=%d", + bss_basic_rate_set[0]); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + + for (i = 1; i < bss_basic_rate_set_len; i++) { + ret = os_snprintf(pos, end - pos, " %d", + bss_basic_rate_set[i]); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + } + + ret = os_snprintf(pos, end - pos, "\n"); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + } + os_free(bss_basic_rate_set); + + return pos - buf; +} + + +int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf, + char *end) +{ + return mesh_attr_text(ies, ies_len, buf, end); +} diff --git a/wpa_supplicant/mesh.h b/wpa_supplicant/mesh.h index 44188a917..3c3ea1f88 100644 --- a/wpa_supplicant/mesh.h +++ b/wpa_supplicant/mesh.h @@ -14,6 +14,8 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s); void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh); +int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf, + char *end); #ifdef CONFIG_MESH