From c5d193d7b3cfeeafefa65c30b216aef04dd8dde3 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 15 Feb 2016 16:53:28 +0200 Subject: [PATCH] MBO: Add cellular capability to MBO IE Add cellular capability attribute to MBO IE and add MBO IE with cellular capabilities to Probe Request frames. By default, cellular capability value is set to Not Cellular capable (3). Signed-off-by: David Spinadel --- wpa_supplicant/config.c | 6 ++++++ wpa_supplicant/config.h | 6 ++++++ wpa_supplicant/config_file.c | 2 ++ wpa_supplicant/mbo.c | 24 ++++++++++++++++++++++-- wpa_supplicant/scan.c | 6 ++++++ wpa_supplicant/wpa_supplicant.conf | 6 ++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 3319ed18f..eff104382 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3561,6 +3561,10 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->cert_in_cb = DEFAULT_CERT_IN_CB; config->wpa_rsc_relaxation = DEFAULT_WPA_RSC_RELAXATION; +#ifdef CONFIG_MBO + config->mbo_cell_capa = DEFAULT_MBO_CELL_CAPA; +#endif /* CONFIG_MBO */ + if (ctrl_interface) config->ctrl_interface = os_strdup(ctrl_interface); if (driver_param) @@ -4270,6 +4274,8 @@ static const struct global_parse_data global_fields[] = { { STR(sched_scan_plans), CFG_CHANGED_SCHED_SCAN_PLANS }, #ifdef CONFIG_MBO { STR(non_pref_chan), 0 }, + { INT_RANGE(mbo_cell_capa, MBO_CELL_CAPA_AVAILABLE, + MBO_CELL_CAPA_NOT_SUPPORTED), 0 }, #endif /*CONFIG_MBO */ }; diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 27e9b9839..9a13f5ff7 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -40,6 +40,7 @@ #define DEFAULT_CERT_IN_CB 1 #define DEFAULT_P2P_GO_CTWINDOW 0 #define DEFAULT_WPA_RSC_RELAXATION 1 +#define DEFAULT_MBO_CELL_CAPA MBO_CELL_CAPA_NOT_SUPPORTED #include "config_ssid.h" #include "wps/wps.h" @@ -1284,6 +1285,11 @@ struct wpa_config { * Detail is optional. */ char *non_pref_chan; + + /** + * mbo_cell_capa - Cellular capabilities for MBO + */ + enum mbo_cellular_capa mbo_cell_capa; #endif /* CONFIG_MBO */ }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 07822ef41..38061f1c1 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1331,6 +1331,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) #ifdef CONFIG_MBO if (config->non_pref_chan) fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan); + if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA) + fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa); #endif /* CONFIG_MBO */ } diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c index f35a1de5c..d6f2e769a 100644 --- a/wpa_supplicant/mbo.c +++ b/wpa_supplicant/mbo.c @@ -136,8 +136,7 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len) struct wpabuf *mbo; int res; - if (!wpa_s->non_pref_chan || !wpa_s->non_pref_chan_num || - len < MBO_IE_HEADER + 7) + if (len < MBO_IE_HEADER + 3 + 7) return 0; /* Leave room for the MBO IE header */ @@ -148,6 +147,14 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len) /* Add non-preferred channels attribute */ wpas_mbo_non_pref_chan_attrs(wpa_s, mbo, 0); + /* + * Send cellular capabilities attribute even if AP does not advertise + * cellular capabilities. + */ + wpabuf_put_u8(mbo, MBO_ATTR_ID_CELL_DATA_CAPA); + wpabuf_put_u8(mbo, 1); + wpabuf_put_u8(mbo, wpa_s->conf->mbo_cell_capa); + res = mbo_add_ie(buf, len, wpabuf_head_u8(mbo), wpabuf_len(mbo)); if (!res) wpa_printf(MSG_ERROR, "Failed to add MBO IE"); @@ -330,3 +337,16 @@ fail: os_free(cmd); return -1; } + + +void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie) +{ + wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC); + wpabuf_put_u8(ie, 7); + wpabuf_put_be24(ie, OUI_WFA); + wpabuf_put_u8(ie, MBO_OUI_TYPE); + + wpabuf_put_u8(ie, MBO_ATTR_ID_CELL_DATA_CAPA); + wpabuf_put_u8(ie, 1); + wpabuf_put_u8(ie, wpa_s->conf->mbo_cell_capa); +} diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 30bec2cae..c333e5748 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -490,6 +490,12 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) wpabuf_put_buf(extra_ie, wpa_s->fst_ies); #endif /* CONFIG_FST */ +#ifdef CONFIG_MBO + /* Send cellular capabilities for potential MBO STAs */ + if (wpabuf_resize(&extra_ie, 9) == 0) + wpas_mbo_scan_ie(wpa_s, extra_ie); +#endif /* CONFIG_MBO */ + return extra_ie; } diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index a6e7bb9e4..e55b380fe 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -649,6 +649,12 @@ fast_reauth=1 # Example: # non_pref_chan="81:5:10:2:0 81:1:0:2:0 81:9:0:2" +# MBO Cellular Data Capabilities +# 1 = Cellular data connection available +# 2 = Cellular data connection not available +# 3 = Not cellular capable (default) +#mbo_cell_capa=3 + # network block # # Each network (usually AP's sharing the same SSID) is configured as a separate diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 22efb27cd..d53bc961e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1146,6 +1146,7 @@ void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s, int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len); int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s, const char *non_pref_chan); +void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie); /** * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response