Cumulative patch from commit 905828fea4b95a6d48ce86e1b5272c25a618b3d8
905828f hostapd: Fix vht_capab 'Maximum A-MPDU Length Exponent' handling
89de64c ACS: Fix VHT80 segment picking
1f37483 DFS: Print error in case CAC fails
354c903 AP/GO interface teardown optimization
8bc4372 Use P2P_IE_VENDOR_TYPE more consistently
8714caa WPS: Parse Registrar Configuration Methods
6b9f7af nl80211: Extend the new vendor command for testing nl80211
3a94adb P2P: Do not start scan for P2P Device interfaces at driver init
aa10983 P2P: Do not initialize bgscan on P2P interfaces
819f096 nl80211: Fix RTM event handling for dynamic interfaces
54ac5aa config: Add bgscan option when saving global configuration
268043d bgscan: Do not initialize bgscan if disabled by user
adef894 nl80211: Add vendor command support
d0595b2 nl80211: Fix tearing down WDS STA interfaces
Change-Id: I6d49f445692b71a4cd324f517eba651518ee14bb
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index f150679..af27303 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -669,6 +669,9 @@
wpa_s->ap_iface->bss[0]->p2p_group = NULL;
wpas_p2p_group_deinit(wpa_s);
#endif /* CONFIG_P2P */
+ wpa_s->ap_iface->driver_ap_teardown =
+ !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
+
hostapd_interface_deinit(wpa_s->ap_iface);
hostapd_interface_free(wpa_s->ap_iface);
wpa_s->ap_iface = NULL;
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 850a6cf..4f58130 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1118,6 +1118,9 @@
if (config->tdls_external_control)
fprintf(f, "tdls_external_control=%d\n",
config->tdls_external_control);
+
+ if (config->bgscan)
+ fprintf(f, "bgscan=\"%s\"\n", config->bgscan);
}
#endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 793faec..2935ce7 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5460,6 +5460,63 @@
#endif /* ANDROID */
+static int wpa_supplicant_vendor_cmd(struct wpa_supplicant *wpa_s, char *cmd,
+ char *buf, size_t buflen)
+{
+ int ret;
+ char *pos;
+ u8 *data = NULL;
+ unsigned int vendor_id, subcmd;
+ struct wpabuf *reply;
+ size_t data_len = 0;
+
+ /* cmd: <vendor id> <subcommand id> [<hex formatted data>] */
+ vendor_id = strtoul(cmd, &pos, 16);
+ if (!isblank(*pos))
+ return -EINVAL;
+
+ subcmd = strtoul(pos, &pos, 10);
+
+ if (*pos != '\0') {
+ if (!isblank(*pos++))
+ return -EINVAL;
+ data_len = os_strlen(pos);
+ }
+
+ if (data_len) {
+ data_len /= 2;
+ data = os_malloc(data_len);
+ if (!data)
+ return -ENOBUFS;
+
+ if (hexstr2bin(pos, data, data_len)) {
+ wpa_printf(MSG_DEBUG,
+ "Vendor command: wrong parameter format");
+ os_free(data);
+ return -EINVAL;
+ }
+ }
+
+ reply = wpabuf_alloc((buflen - 1) / 2);
+ if (!reply) {
+ os_free(data);
+ return -ENOBUFS;
+ }
+
+ ret = wpa_drv_vendor_cmd(wpa_s, vendor_id, subcmd, data, data_len,
+ reply);
+
+ if (ret == 0)
+ ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(reply),
+ wpabuf_len(reply));
+
+ wpabuf_free(reply);
+ os_free(data);
+
+ return ret;
+}
+
+
static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
{
wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state");
@@ -6345,6 +6402,9 @@
reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
reply_size);
#endif /* ANDROID */
+ } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
+ reply_len = wpa_supplicant_vendor_cmd(wpa_s, buf + 7, reply,
+ reply_size);
} else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
pmksa_cache_clear_current(wpa_s->wpa);
eapol_sm_request_reauth(wpa_s->eapol);
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 0691b6c..b336afb 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -604,4 +604,14 @@
qos_map_set_len);
}
+static inline int wpa_drv_vendor_cmd(struct wpa_supplicant *wpa_s,
+ int vendor_id, int subcmd, const u8 *data,
+ size_t data_len, struct wpabuf *buf)
+{
+ if (!wpa_s->driver->vendor_cmd)
+ return -1;
+ return wpa_s->driver->vendor_cmd(wpa_s->drv_priv, vendor_id, subcmd,
+ data, data_len, buf);
+}
+
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 0691183..63ea1df 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2426,6 +2426,12 @@
#endif /* ANDROID */
+static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+ return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
+}
+
+
static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
return wpa_ctrl_command(ctrl, "FLUSH");
@@ -2912,6 +2918,9 @@
#endif /* ANDROID */
{ "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
"= radio_work <show/add/done>" },
+ { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
+ "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
+ },
{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
};
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index ad1a03e..46195b1 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -573,12 +573,16 @@
name = wpa_s->current_ssid->bgscan;
else
name = wpa_s->conf->bgscan;
- if (name == NULL)
+ if (name == NULL || name[0] == '\0')
return;
if (wpas_driver_bss_selection(wpa_s))
return;
if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
return;
+#ifdef CONFIG_P2P
+ if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
+ return;
+#endif /* CONFIG_P2P */
bgscan_deinit(wpa_s);
if (wpa_s->current_ssid) {
@@ -2669,7 +2673,8 @@
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
interface_count = 0;
}
- if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
+ if (!wpa_s->p2p_mgmt &&
+ wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
100000))
wpa_supplicant_req_scan(wpa_s, interface_count,
100000);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 442b44c..03c6f5f 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -603,6 +603,8 @@
# bgscan="learn:<short bgscan interval in seconds>:<signal strength threshold>:
# <long interval>[:<database file name>]"
# bgscan="learn:30:-45:300:/etc/wpa_supplicant/network1.bgscan"
+# Explicitly disable bgscan by setting
+# bgscan=""
#
# This option can also be set outside of all network blocks for the bgscan
# parameter to apply for all the networks that have no specific bgscan