aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/config.c2
-rw-r--r--wpa_supplicant/config.h10
-rw-r--r--wpa_supplicant/config_file.c6
-rw-r--r--wpa_supplicant/ctrl_iface.c25
-rw-r--r--wpa_supplicant/events.c27
-rw-r--r--wpa_supplicant/p2p_supplicant.c23
-rw-r--r--wpa_supplicant/p2p_supplicant.h1
-rw-r--r--wpa_supplicant/scan.c11
-rw-r--r--wpa_supplicant/wpa_supplicant.c12
-rw-r--r--wpa_supplicant/wpa_supplicant_template.conf4
10 files changed, 96 insertions, 25 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 69eb7d0..9d93161 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2968,6 +2968,7 @@ static const struct global_parse_data global_fields[] = {
{ INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
{ INT(p2p_group_idle), 0 },
{ FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
+ { INT(p2p_disabled), 0 },
#endif /* CONFIG_P2P */
#ifdef ANDROID_P2P
{ STR_RANGE(prioritize, 0, 32), CFG_CHANGED_IFACE_PRIORITY },
@@ -3000,6 +3001,7 @@ static const struct global_parse_data global_fields[] = {
MAX_NUM_SCHED_SCAN_SHORT_INTERVALS), 0 },
{ INT_RANGE(sched_scan_short_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 },
{ INT_RANGE(sched_scan_long_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 },
+ { INT_RANGE(concurrent_sched_scan, 0, 1), 0 },
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index eb7dbf0..8273f14 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -743,6 +743,16 @@ struct wpa_config {
*/
int p2p_conc_mode;
#endif
+ /*
+ * p2p_disabled - Whether P2P operations are disabled for this interface
+ */
+ int p2p_disabled;
+
+ /*
+ * concurrent_sched_scan - sched scan can run concurrently with normal
+ * scan and no need to stop one to do the other.
+ */
+ int concurrent_sched_scan;
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index cbece8e..cba8604 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -852,6 +852,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
}
fprintf(f, "\n");
}
+
+ if (config->p2p_disabled)
+ fprintf(f, "p2p_disabled=%u\n", config->p2p_disabled);
#endif /* CONFIG_P2P */
if (config->country[0] && config->country[1]) {
fprintf(f, "country=%c%c\n",
@@ -916,6 +919,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (config->p2p_conc_mode)
fprintf(f, "p2p_conc_mode=%u\n", config->p2p_conc_mode);
#endif
+ if (config->concurrent_sched_scan)
+ fprintf(f, "concurrent_sched_scan=%u\n",
+ config->concurrent_sched_scan);
}
#endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 63da94c..81cd363 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4200,6 +4200,7 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
ret = pno_stop(wpa_s);
else if (os_strncasecmp(cmd, "SETBAND ", 8) == 0) {
int val = atoi(cmd + 8);
+ uint setband = 0;
/*
* Use driver_cmd for drivers that support it, but ignore the
* return value since scan requests from wpa_supplicant will
@@ -4210,20 +4211,29 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
ret = 0;
if (val == 0)
- wpa_s->setband = WPA_SETBAND_AUTO;
+ setband = WPA_SETBAND_AUTO;
else if (val == 1)
- wpa_s->setband = WPA_SETBAND_5G;
+ setband = WPA_SETBAND_5G;
else if (val == 2)
- wpa_s->setband = WPA_SETBAND_2G;
- else
+ setband = WPA_SETBAND_2G;
+ else {
ret = -1;
+ goto out;
+ }
+
+ if (wpa_s->setband == setband) {
+ wpa_printf(MSG_DEBUG, "Same setband as before");
+ goto out;
+ }
+ wpa_s->setband = setband;
if (wpa_s->current_bss && !wpa_bss_in_current_band(wpa_s, wpa_s->current_bss))
wpa_supplicant_disable_network(wpa_s, wpa_s->current_ssid);
wpa_supplicant_select_network(wpa_s, NULL);
} else
ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
+out:
if (ret == 0)
ret = sprintf(buf, "%s\n", "OK");
return ret;
@@ -4584,13 +4594,16 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
reply_len = -1;
else {
- if (!wpa_s->sched_scanning && !wpa_s->scanning &&
+ if ((wpa_s->conf->concurrent_sched_scan ||
+ !wpa_s->sched_scanning) &&
+ !wpa_s->scanning &&
((wpa_s->wpa_state <= WPA_SCANNING) ||
(wpa_s->wpa_state == WPA_COMPLETED))) {
wpa_s->normal_scans = 0;
wpa_s->scan_req = 2;
wpa_supplicant_req_scan(wpa_s, 0, 0);
- } else if (wpa_s->sched_scanning) {
+ } else if (wpa_s->sched_scanning &&
+ !wpa_s->conf->concurrent_sched_scan) {
wpa_printf(MSG_DEBUG, "Stop ongoing "
"sched_scan to allow requested "
"full scan to proceed");
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c3e9ed6..e97939e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -473,7 +473,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
return 0;
}
- if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
+ if (!wpa_key_mgmt_wpa(ssid->key_mgmt) && !rsn_ie && !wpa_ie) {
wpa_dbg(wpa_s, MSG_DEBUG, " allow in non-WPA/WPA2");
return 1;
}
@@ -1219,7 +1219,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (wpas_p2p_scan_no_go_seen(wpa_s) == 1)
return 0;
- if (wpa_s->p2p_in_provisioning) {
+ if (wpa_s->p2p_in_provisioning ||
+ wpa_s->show_group_started) {
/*
* Use shorter wait during P2P Provisioning
* state to speed up group formation.
@@ -1231,9 +1232,20 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
return 0;
}
#endif /* CONFIG_P2P */
- if ((data && data->scan_info.is_sched_scan_res) ||
- !wpa_s->sched_scanning)
+ /*
+ * If sched scan results were received but we didn't
+ * connect then there's an AP with a matching SSID
+ * which may have mismatching security. Don't restart
+ * another sched scan immediately and wait for the next
+ * normal scan in scan_interval to trigger it in order
+ * to avoid a sched scan results storm.
+ * In any case if it's not started kick start it.
+ */
+ if (!wpa_s->sched_scanning)
wpa_supplicant_req_sched_scan(wpa_s);
+ else if (data && data->scan_info.is_sched_scan_res)
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+
wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
timeout_usec);
}
@@ -2835,6 +2847,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#ifdef CONFIG_P2P
wpas_p2p_update_channel_list(wpa_s);
#endif /* CONFIG_P2P */
+
+ /* Restart the sched scan with updated channel list */
+ if (wpa_s->sched_scanning) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Channel list changed restart"
+ " sched scan.");
+ wpa_supplicant_req_sched_scan(wpa_s);
+ }
break;
case EVENT_INTERFACE_UNAVAILABLE:
#ifdef CONFIG_P2P
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b0eb594..42c062f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4137,6 +4137,22 @@ void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
if (wpa_s->global->p2p == NULL)
return;
+ /*
+ * Discard an Rx duplication created by mac80211 rx path
+ * when receiving public action frames with mismatched BSSID
+ * In case of separate GO interface such public action frames (prov disc
+ * dev disc, invites) these should be handled by the P2P dev interface
+ */
+ if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO &&
+ category == WLAN_ACTION_PUBLIC &&
+ wpa_s->p2p_group &&
+ os_memcmp(bssid, p2p_group_get_interface_addr(wpa_s->p2p_group),
+ ETH_ALEN)) {
+ wpa_printf(MSG_DEBUG, "Discard duplicate RX action event on"
+ " P2P GO interface");
+ return;
+ }
+
p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
freq);
}
@@ -4973,13 +4989,6 @@ int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
return p2p_in_progress(wpa_s->global->p2p);
}
-int wpas_p2p_non_idle(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return 0;
-
- return p2p_non_idle(wpa_s->global->p2p);
-}
void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index f24fb28..8d3bff1 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -137,7 +137,6 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s);
void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail);
int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
-int wpas_p2p_non_idle(struct wpa_supplicant *wpa_s);
void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 6b43968..887c747 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -66,7 +66,8 @@ static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
}
#ifdef CONFIG_P2P
- if (wpas_p2p_non_idle(wpa_s)) {
+ if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
+ !wpa_s->conf->p2p_disabled) {
wpa_s->wps->dev.p2p = 1;
if (!wps) {
wps = 1;
@@ -798,6 +799,9 @@ int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
if (!wpa_s->sched_scan_supported)
return -1;
+ eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
+ wpa_s, NULL);
+
eloop_register_timeout(sec, usec,
wpa_supplicant_delayed_sched_scan_timeout,
wpa_s, NULL);
@@ -887,6 +891,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
need_ssids++;
if (wpa_s->normal_scans < 3 &&
+ wpa_s->max_scan_ssids > 1 &&
(need_ssids <= wpa_s->max_scan_ssids ||
wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
/*
@@ -895,6 +900,10 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
* user space sleep more. We do this only if the normal scan
* has functionality that is suitable for this or if the
* sched_scan does not have better support for multiple SSIDs.
+ * max_scan_ssids=1 is a special case where we'd like to avoid
+ * using normal scan as wpa_supplicant_scan handles this case
+ * differently and doesn't add a wildcard SSID so broadcast scan
+ * results would be delayed.
*/
wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
"sched_scan for initial scans (normal_scans=%d)",
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 73ffde8..39630ad 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2375,11 +2375,8 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
wpa_s->prev_scan_wildcard = 0;
if (wpa_supplicant_enabled_networks(wpa_s)) {
-#ifdef ANDROID
- wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0);
-#else
- wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
-#endif
+ wpa_supplicant_delayed_sched_scan(wpa_s,
+ interface_count, 100000);
interface_count++;
} else
wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
@@ -2849,6 +2846,11 @@ next_driver:
#ifdef CONFIG_P2P
#ifdef ANDROID
+ if (os_strncmp(iface->ifname, "wlan0", 4) == 0) {
+ wpa_printf(MSG_DEBUG, "Disable P2P on wlan0");
+ wpa_s->conf->p2p_disabled = 1;
+ }
+
if (os_strncmp(iface->ifname, "p2p0", 4) == 0)
#endif /* ANDROID */
if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf
index 901209a..e99525d 100644
--- a/wpa_supplicant/wpa_supplicant_template.conf
+++ b/wpa_supplicant/wpa_supplicant_template.conf
@@ -5,7 +5,9 @@ eapol_version=1
ap_scan=1
fast_reauth=1
p2p_conc_mode=2
-p2p_go_max_inactivity=30
+driver_param=use_p2p_group_interface=1
+p2p_go_max_inactivity=60
p2p_go_ht40=1
p2p_multi_chan=1
disassoc_low_ack=1
+concurrent_sched_scan=1