Accumulative patch from commit f5f37d3a4fc2df2a24676b4f95afca15ed793cba
Author: Jouni Malinen <j@w1.fi>
Date: Sun Nov 25 22:05:32 2012 +0200
Fix REAUTHENTICATE command after PMKSA caching
The current PMKSA cache entry needs to be clear to allow EAPOL
reauthentication to be started in case this association used PMKSA
caching.
- Remove old WPS_OOB NCF
- WPS: Add preliminary NFC connection handover support for Enrollee
- WPS: Reenable the networks disabled during wpa_wpas_reassoc
- P2P: Avoid multi-channel scans when they are not needed
- P2P: Allow discoverable interval for p2p_find to be configured
- P2P: Allow all channels with multi-channel concurrency
- Bonjour changes
- Remove disassociate
- HS 2.0 changes
- Add preliminary support for using SQLite for eap_user database
- Add SAE support
- Add disallow_aps parameter to disallow BSSIDs/SSIDs
Change-Id: I85358a05b39d46b8db49acdad667e771c580b05c
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 0f6433b..048e6d0 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -66,7 +66,8 @@
}
#ifdef CONFIG_P2P
- if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) {
+ 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;
@@ -439,11 +440,78 @@
}
+#ifdef CONFIG_P2P
+
+/*
+ * Check whether there are any enabled networks or credentials that could be
+ * used for a non-P2P connection.
+ */
+static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_ssid *ssid;
+
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if (wpas_network_disabled(wpa_s, ssid))
+ continue;
+ if (!ssid->p2p_group)
+ return 1;
+ }
+
+ if (wpa_s->conf->cred && wpa_s->conf->interworking &&
+ wpa_s->conf->auto_interworking)
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ * Find the operating frequency of any other virtual interface that is using
+ * the same radio concurrently.
+ */
+static int shared_vif_oper_freq(struct wpa_supplicant *wpa_s)
+{
+ const char *rn, *rn2;
+ struct wpa_supplicant *ifs;
+ u8 bssid[ETH_ALEN];
+
+ if (!wpa_s->driver->get_radio_name)
+ return -1;
+
+ rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
+ if (rn == NULL || rn[0] == '\0')
+ return -1;
+
+ for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+ if (ifs == wpa_s || !ifs->driver->get_radio_name)
+ continue;
+
+ rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
+ if (!rn2 || os_strcmp(rn, rn2) != 0)
+ continue;
+
+ if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
+ continue;
+
+ if (ifs->current_ssid->mode == WPAS_MODE_AP ||
+ ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
+ return ifs->current_ssid->frequency;
+ if (wpa_drv_get_bssid(ifs, bssid) == 0)
+ return ifs->assoc_freq;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_P2P */
+
+
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_ssid *ssid;
- int scan_req = 0, ret;
+ enum scan_req_type scan_req = NORMAL_SCAN_REQ;
+ int ret;
struct wpabuf *extra_ie = NULL;
struct wpa_driver_scan_params params;
struct wpa_driver_scan_params *scan_params;
@@ -455,7 +523,7 @@
return;
}
- if (wpa_s->disconnected && !wpa_s->scan_req) {
+ if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
return;
@@ -468,7 +536,7 @@
}
#endif
if (!wpa_supplicant_enabled_networks(wpa_s) &&
- !wpa_s->scan_req) {
+ wpa_s->scan_req == NORMAL_SCAN_REQ) {
wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
#ifdef CONFIG_P2P
@@ -516,7 +584,7 @@
}
scan_req = wpa_s->scan_req;
- wpa_s->scan_req = 0;
+ wpa_s->scan_req = NORMAL_SCAN_REQ;
os_memset(¶ms, 0, sizeof(params));
@@ -533,7 +601,7 @@
goto scan;
}
- if (scan_req != 2 && wpa_s->connect_without_scan) {
+ if (scan_req != MANUAL_SCAN_REQ && wpa_s->connect_without_scan) {
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
if (ssid == wpa_s->connect_without_scan)
break;
@@ -571,7 +639,7 @@
}
}
- if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
+ if (scan_req != MANUAL_SCAN_REQ && wpa_s->conf->ap_scan == 2) {
wpa_s->connect_without_scan = NULL;
wpa_s->prev_scan_wildcard = 0;
wpa_supplicant_assoc_try(wpa_s, ssid);
@@ -698,6 +766,35 @@
scan_params = ¶ms;
scan:
+#ifdef CONFIG_P2P
+ /*
+ * If the driver does not support multi-channel concurrency and a
+ * virtual interface that shares the same radio with the wpa_s interface
+ * is operating there may not be need to scan other channels apart from
+ * the current operating channel on the other virtual interface. Filter
+ * out other channels in case we are trying to find a connection for a
+ * station interface when we are not configured to prefer station
+ * connection and a concurrent operation is already in process.
+ */
+ if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ &&
+ !scan_params->freqs && !params.freqs &&
+ wpas_is_p2p_prioritized(wpa_s) &&
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
+ wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
+ non_p2p_network_enabled(wpa_s)) {
+ int freq = shared_vif_oper_freq(wpa_s);
+ if (freq > 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only the current "
+ "operating channel (%d MHz) since driver does "
+ "not support multi-channel concurrency", freq);
+ params.freqs = os_zalloc(sizeof(int) * 2);
+ if (params.freqs)
+ params.freqs[0] = freq;
+ scan_params->freqs = params.freqs;
+ }
+ }
+#endif /* CONFIG_P2P */
+
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
wpabuf_free(extra_ie);
@@ -706,15 +803,13 @@
if (ret) {
wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
-#ifdef ANDROID_P2P
- /* Restore back the wpa_s->scan_req if we failed the scan because of any reason */
- wpa_msg(wpa_s, MSG_DEBUG, "Restoring back the wpa_s->scan_req "
- "to the original value %d", scan_req);
- wpa_s->scan_req = scan_req;
-#endif
if (prev_state != wpa_s->wpa_state)
wpa_supplicant_set_state(wpa_s, prev_state);
+ /* Restore scan_req since we will try to scan again */
+ wpa_s->scan_req = scan_req;
wpa_supplicant_req_scan(wpa_s, 1, 0);
+ } else {
+ wpa_s->scan_for_connection = 0;
}
}