aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvamsi krishna <vamsin@qti.qualcomm.com>2016-07-19 12:41:15 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-24 21:49:53 -0700
commit2b23da8a23446f9c8deb8c8650528f1b09d8701d (patch)
tree395eb6d58f9a8c3267a73cdff43c00ec3ea87b41
parent5000e881341727fa0ba747c8b91e680135613396 (diff)
downloadandroid_external_wpa_supplicant_8-2b23da8a23446f9c8deb8c8650528f1b09d8701d.tar.gz
android_external_wpa_supplicant_8-2b23da8a23446f9c8deb8c8650528f1b09d8701d.tar.bz2
android_external_wpa_supplicant_8-2b23da8a23446f9c8deb8c8650528f1b09d8701d.zip
Set default scan IEs to the driver (QCA vendor extension)
This makes wpa_supplicant set default scan IEs to the driver (if the vendor command is supported). The driver can use these IEs in the scan requests initiated by the driver itself. Also the driver can merge these IEs into further scan requests that it receives, in case if the scan request doesn't carry any of the IEs sent in this command. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Git-commit: cc9985d1b1a844fddbc042abe8c4f5036c0d410b Git-repo: git://w1.fi/srv/git/hostap.git Change-Id: I21e8e31c50bb14903a14a2419a6eb5f4ae8841ef CRs-Fixed: 1049832
-rw-r--r--src/drivers/driver.h17
-rw-r--r--src/drivers/driver_nl80211.c1
-rw-r--r--src/drivers/driver_nl80211.h2
-rw-r--r--src/drivers/driver_nl80211_capa.c3
-rw-r--r--src/drivers/driver_nl80211_scan.c50
-rw-r--r--wpa_supplicant/driver_i.h9
-rw-r--r--wpa_supplicant/mbo.c2
-rw-r--r--wpa_supplicant/scan.c33
-rw-r--r--wpa_supplicant/scan.h1
-rw-r--r--wpa_supplicant/wpa_supplicant.c2
10 files changed, 120 insertions, 0 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index c33db9fe..a102d9bc 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3578,6 +3578,23 @@ struct wpa_driver_ops {
* Returns: 0 on success or -1 on failure
*/
int (*p2p_lo_stop)(void *priv);
+
+ /**
+ * set_default_scan_ies - Set default scan IEs
+ * @priv: Private driver interface data
+ * @ies: Scan default IEs buffer
+ * @ies_len: Length of IEs in bytes
+ * Returns: 0 on success or -1 on failure
+ *
+ * The driver can use these by default when there are no scan IEs coming
+ * in the subsequent scan requests. Also in case of one or more of IEs
+ * given in set_default_scan_ies() are missing in the subsequent scan
+ * request, the driver should merge the missing scan IEs in the scan
+ * request from the IEs set by set_default_scan_ies() in the Probe
+ * Request frames sent.
+ */
+ int (*set_default_scan_ies)(void *priv, const u8 *ies, size_t ies_len);
+
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0ca6ccdc..fd9cd01c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9289,6 +9289,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.set_prob_oper_freq = nl80211_set_prob_oper_freq,
.p2p_lo_start = nl80211_p2p_lo_start,
.p2p_lo_stop = nl80211_p2p_lo_stop,
+ .set_default_scan_ies = nl80211_set_default_scan_ies,
#endif /* CONFIG_DRIVER_NL80211_QCA */
.get_ext_capab = nl80211_get_ext_capab,
};
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 283dfd99..d0ec48c9 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -159,6 +159,7 @@ struct wpa_driver_nl80211_data {
unsigned int set_prob_oper_freq:1;
unsigned int scan_vendor_cmd_avail:1;
unsigned int connect_reassoc:1;
+ unsigned int set_wifi_conf_vendor_cmd_avail:1;
u64 vendor_scan_cookie;
u64 remain_on_chan_cookie;
@@ -301,5 +302,6 @@ void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv);
int wpa_driver_nl80211_abort_scan(void *priv);
int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
struct wpa_driver_scan_params *params);
+int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len);
#endif /* DRIVER_NL80211_H */
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index a5515fff..56647449 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -702,6 +702,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
drv->scan_vendor_cmd_avail = 1;
break;
+ case QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION:
+ drv->set_wifi_conf_vendor_cmd_avail = 1;
+ break;
#endif /* CONFIG_DRIVER_NL80211_QCA */
}
}
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index c0898914..c115b6b3 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -1070,4 +1070,54 @@ fail:
return ret;
}
+
+/**
+ * nl80211_set_default_scan_ies - Set the scan default IEs to the driver
+ * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
+ * @ies: Pointer to IEs buffer
+ * @ies_len: Length of IEs in bytes
+ * Returns: 0 on success, -1 on failure
+ */
+int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg = NULL;
+ struct nlattr *attr;
+ int ret = -1;
+
+ if (!drv->set_wifi_conf_vendor_cmd_avail)
+ return -1;
+
+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION))
+ goto fail;
+
+ attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (attr == NULL)
+ goto fail;
+
+ wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan default IEs", ies, ies_len);
+ if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES,
+ ies_len, ies))
+ goto fail;
+
+ nla_nest_end(msg, attr);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ msg = NULL;
+ if (ret) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: Set scan default IEs failed: ret=%d (%s)",
+ ret, strerror(-ret));
+ goto fail;
+ }
+
+fail:
+ nlmsg_free(msg);
+ return ret;
+}
+
#endif /* CONFIG_DRIVER_NL80211_QCA */
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 82e9a5a3..869b705f 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -950,4 +950,13 @@ static inline int wpa_drv_p2p_lo_stop(struct wpa_supplicant *wpa_s)
return -1;
return wpa_s->driver->p2p_lo_stop(wpa_s->drv_priv);
}
+
+static inline int wpa_drv_set_default_scan_ies(struct wpa_supplicant *wpa_s,
+ const u8 *ies, size_t len)
+{
+ if (!wpa_s->driver->set_default_scan_ies)
+ return -1;
+ return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
+}
+
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 3292e67c..1154ab6d 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -18,6 +18,7 @@
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "bss.h"
+#include "scan.h"
/* type + length + oui + oui type */
#define MBO_IE_HEADER 6
@@ -768,4 +769,5 @@ void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa)
cell_capa[6] = mbo_cell_capa;
wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
+ wpa_supplicant_set_default_scan_ies(wpa_s);
}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 466ff5fc..09c7bd89 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -428,6 +428,39 @@ static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_INTERWORKING */
+void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
+{
+ struct wpabuf *default_ies = NULL;
+ u8 ext_capab[18];
+ int ext_capab_len;
+ enum wpa_driver_if_type type = WPA_IF_STATION;
+
+#ifdef CONFIG_P2P
+ if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
+ type = WPA_IF_P2P_CLIENT;
+#endif /* CONFIG_P2P */
+
+ wpa_drv_get_ext_capa(wpa_s, type);
+
+ ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
+ sizeof(ext_capab));
+ if (ext_capab_len > 0 &&
+ wpabuf_resize(&default_ies, ext_capab_len) == 0)
+ wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
+
+#ifdef CONFIG_MBO
+ /* Send cellular capabilities for potential MBO STAs */
+ if (wpabuf_resize(&default_ies, 9) == 0)
+ wpas_mbo_scan_ie(wpa_s, default_ies);
+#endif /* CONFIG_MBO */
+
+ if (default_ies)
+ wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
+ wpabuf_len(default_ies));
+ wpabuf_free(default_ies);
+}
+
+
static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
{
struct wpabuf *extra_ie = NULL;
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 917ec552..a734148a 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -59,5 +59,6 @@ void filter_scan_res(struct wpa_supplicant *wpa_s,
void scan_snr(struct wpa_scan_res *res);
void scan_est_throughput(struct wpa_supplicant *wpa_s,
struct wpa_scan_res *res);
+void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s);
#endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 6a978667..a158501a 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4841,6 +4841,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
#endif /* CONFIG_MBO */
+ wpa_supplicant_set_default_scan_ies(wpa_s);
+
return 0;
}