[PATCH 07/25] MBO: Add MBO wnm notification request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: David Spinadel <david.spinadel@xxxxxxxxx>

Add WNM notification request in case of a change in np_chan list
during connection.

Signed-off-by: David Spinadel <david.spinadel@xxxxxxxxx>
---
 wpa_supplicant/mbo.c              | 77 ++++++++++++++++++++++++++++++++++++---
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 2 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index f545034..1cfea44 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -95,15 +95,42 @@ static void wpas_mbo_np_chan_attr(struct wpa_supplicant *wpa_s,
 }
 
 
-static void wpas_mbo_np_chan_attrs(struct wpa_supplicant *wpa_s,
-				   struct wpabuf *mbo)
+static void wpas_mbo_np_chan_subelem_hdr(struct wpabuf *mbo, u8 len)
+{
+	wpabuf_put_u8(mbo, WLAN_EID_VENDOR_SPECIFIC);
+	wpabuf_put_u8(mbo, len); /* Length */
+	wpabuf_put_be24(mbo, OUI_WFA);
+	wpabuf_put_u8(mbo, MBO_ATTR_ID_NP_CHAN_REPORT);
+}
+
+
+static void wpas_mbo_np_chan_subelement(struct wpa_supplicant *wpa_s,
+					struct wpabuf *mbo, u8 start, u8 end)
+{
+	size_t size = end - start + 8;
+
+	if (start == end)
+		return;
+
+	if (size + 2 > wpabuf_tailroom(mbo))
+		return;
+
+	wpas_mbo_np_chan_subelem_hdr(mbo, size);
+	wpas_mbo_np_chan_attr_body(wpa_s, mbo, start, end);
+}
+
 
+static void wpas_mbo_np_chan_attrs(struct wpa_supplicant *wpa_s,
+				   struct wpabuf *mbo, int subelement)
 {
 	u8 oper_class = 0, reason = 0, reason_detail = 0, preference = 0;
 	u8 i, start = 0;
 
-	if (!wpa_s->np_chan || !wpa_s->np_chan_num)
+	if (!wpa_s->np_chan || !wpa_s->np_chan_num) {
+		if (subelement)
+			wpas_mbo_np_chan_subelem_hdr(mbo, 4);
 		return;
+	}
 
 	for (i = 0; i <= wpa_s->np_chan_num; i++) {
 		if (i == wpa_s->np_chan_num ||
@@ -111,7 +138,11 @@ static void wpas_mbo_np_chan_attrs(struct wpa_supplicant *wpa_s,
 		    wpa_s->np_chan[i].reason != reason ||
 		    wpa_s->np_chan[i].reason_detail != reason_detail ||
 		    wpa_s->np_chan[i].preference != preference) {
-			wpas_mbo_np_chan_attr(wpa_s, mbo, start, i);
+			if (subelement)
+				wpas_mbo_np_chan_subelement(wpa_s, mbo, start,
+							    i);
+			else
+				wpas_mbo_np_chan_attr(wpa_s, mbo, start, i);
 
 			if (i == wpa_s->np_chan_num)
 				return;
@@ -143,7 +174,7 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len)
 		return 0;
 
 	/* Add Non-preferred channels attribute */
-	wpas_mbo_np_chan_attrs(wpa_s, mbo);
+	wpas_mbo_np_chan_attrs(wpa_s, mbo, 0);
 
 	res = mbo_add_ie(buf, len, wpabuf_head_u8(mbo), wpabuf_len(mbo));
 	if (!res)
@@ -154,6 +185,41 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len)
 }
 
 
+static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s)
+{
+	struct wpabuf *buf;
+	int res;
+
+	/* Sending WNM request only in case of a change in non preferred channel
+	 * during connection, if the AP supports MBO.
+	 */
+	if (wpa_s->wpa_state != WPA_COMPLETED ||
+	    !wpa_bss_get_vendor_ie_subtype(wpa_s->current_bss, OUI_WFA,
+					   MBO_OUI_TYPE))
+		return;
+
+	buf = wpabuf_alloc(512);
+	if (!buf)
+		return;
+
+	wpabuf_put_u8(buf, WLAN_ACTION_WNM);
+	wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
+	wpabuf_put_u8(buf, ++wpa_s->mbo_wnm_token);
+	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); /* Type */
+
+	wpas_mbo_np_chan_attrs(wpa_s, buf, 1);
+
+	res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				  wpa_s->own_addr, wpa_s->bssid,
+				  wpabuf_head(buf), wpabuf_len(buf), 0);
+	if (res < 0)
+		wpa_printf(MSG_DEBUG,
+			   "Failed to send WNM req with non preferred channel list");
+
+	wpabuf_free(buf);
+}
+
+
 static int wpa_np_chan_is_eq(struct wpa_mbo_np_channel *a,
 			     struct wpa_mbo_np_channel *b)
 {
@@ -263,6 +329,7 @@ update:
 	os_free(wpa_s->np_chan);
 	wpa_s->np_chan = chans;
 	wpa_s->np_chan_num = num;
+	wpas_mbo_send_wnm_notification(wpa_s);
 
 	return 0;
 
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 9519fb6..e03b619 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1027,6 +1027,7 @@ struct wpa_supplicant {
 		u8 preference;
 	} *np_chan;
 	size_t np_chan_num;
+	u8 mbo_wnm_token;
 #endif /* CONFIG_MBO */
 };
 
-- 
1.9.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux