[PATCH] mesh: Add scan result for mesh network

Masashi Honma masashi.honma at gmail.com
Wed Aug 20 02:53:34 EDT 2014


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 <masashi.honma at gmail.com>
---
 src/common/wpa_ctrl.h       |  1 +
 wpa_supplicant/ctrl_iface.c | 11 ++++++
 wpa_supplicant/mesh.c       | 93 +++++++++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/mesh.h       |  2 +
 4 files changed, 107 insertions(+)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 521b97b..e0ee1dc 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -243,6 +243,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 130449a..d782c7e 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -41,6 +41,7 @@
 #include "autoscan.h"
 #include "wnm_sta.h"
 #include "offchannel.h"
+#include "mesh.h"
 
 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
 					    char *buf, int len);
@@ -3816,6 +3817,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 07f1ff8..e0b4e2e 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -333,3 +333,96 @@ 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 9b14ecf..e82ec79 100644
--- a/wpa_supplicant/mesh.h
+++ b/wpa_supplicant/mesh.h
@@ -35,4 +35,6 @@ void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
 				     struct wpabuf **extra_ie);
 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);
 #endif /* MESH_H */
-- 
1.9.1



More information about the HostAP mailing list