From 016082e9e6479e27f3b09f37d803fc5ea0847732 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Mon, 15 Feb 2016 16:54:02 +0200 Subject: [PATCH] MBO: Send WNM-Notification when cellular capabilities change Send a WNM-Notification to the associated AP to indicate changes in cellular data capabilities. Signed-off-by: Avraham Stern --- wpa_supplicant/ctrl_iface.c | 2 ++ wpa_supplicant/mbo.c | 47 +++++++++++++++++++++++++++++++++++---- wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 2ce6127..f585b92 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -493,6 +493,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, #ifdef CONFIG_MBO } else if (os_strcasecmp(cmd, "non_pref_chan") == 0) { ret = wpas_mbo_update_non_pref_chan(wpa_s, value); + } else if (os_strcasecmp(cmd, "mbo_cell_capa") == 0) { + wpas_mbo_update_cell_capa(wpa_s, atoi(value)); #endif /* CONFIG_MBO */ } else { value[-1] = '='; diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c index 0fac6b7..3292e67 100644 --- a/wpa_supplicant/mbo.c +++ b/wpa_supplicant/mbo.c @@ -182,7 +182,8 @@ 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) +static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s, + const u8 *data, size_t len) { struct wpabuf *buf; int res; @@ -196,7 +197,7 @@ static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s) !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE)) return; - buf = wpabuf_alloc(512); + buf = wpabuf_alloc(4 + len); if (!buf) return; @@ -208,7 +209,7 @@ static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s) wpabuf_put_u8(buf, wpa_s->mbo_wnm_token); wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); /* Type */ - wpas_mbo_non_pref_chan_attrs(wpa_s, buf, 1); + wpabuf_put_data(buf, data, len); res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid, @@ -221,6 +222,21 @@ static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s) } +static void wpas_mbo_non_pref_chan_changed(struct wpa_supplicant *wpa_s) +{ + struct wpabuf *buf; + + buf = wpabuf_alloc(512); + if (!buf) + return; + + wpas_mbo_non_pref_chan_attrs(wpa_s, buf, 1); + wpas_mbo_send_wnm_notification(wpa_s, wpabuf_head_u8(buf), + wpabuf_len(buf)); + wpabuf_free(buf); +} + + static int wpa_non_pref_chan_is_eq(struct wpa_mbo_non_pref_channel *a, struct wpa_mbo_non_pref_channel *b) { @@ -346,7 +362,7 @@ update: os_free(wpa_s->non_pref_chan); wpa_s->non_pref_chan = chans; wpa_s->non_pref_chan_num = num; - wpas_mbo_send_wnm_notification(wpa_s); + wpas_mbo_non_pref_chan_changed(wpa_s); return 0; @@ -730,3 +746,26 @@ size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos, return mbo_add_ie(pos, len, reject_attr, sizeof(reject_attr)); } + + +void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa) +{ + u8 cell_capa[7]; + + if (wpa_s->conf->mbo_cell_capa == mbo_cell_capa) { + wpa_printf(MSG_DEBUG, + "MBO: Cellular capability already set to %u", + mbo_cell_capa); + return; + } + + wpa_s->conf->mbo_cell_capa = mbo_cell_capa; + + cell_capa[0] = WLAN_EID_VENDOR_SPECIFIC; + cell_capa[1] = 5; /* Length */ + WPA_PUT_BE24(cell_capa + 2, OUI_WFA); + cell_capa[5] = MBO_ATTR_ID_CELL_DATA_CAPA; + cell_capa[6] = mbo_cell_capa; + + wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7); +} diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 9504f14..0e3e42a 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1167,6 +1167,7 @@ void wpas_mbo_ie_trans_req(struct wpa_supplicant *wpa_s, const u8 *ie, size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos, size_t len, enum mbo_transition_reject_reason reason); +void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa); /** * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response -- 2.1.4