aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-08-28 13:14:13 (GMT)
committerJouni Malinen <j@w1.fi>2012-08-28 13:14:13 (GMT)
commit4d5bda5fca79c221f7714ffb85114d7b6bf4f9ff (patch)
tree4262aa0f3a07695bfedaf6b9fb42635b63914142
parentb1f122964e862bcb15d0237b4b852429957b7ebc (diff)
downloadhostap-4d5bda5fca79c221f7714ffb85114d7b6bf4f9ff.zip
hostap-4d5bda5fca79c221f7714ffb85114d7b6bf4f9ff.tar.gz
hostap-4d5bda5fca79c221f7714ffb85114d7b6bf4f9ff.tar.bz2
Interworking: Add optional use of network selection on normal scans
auto_interworking=1 configuration parameter can be used to request wpa_supplicant to use Interworking network selection automatically as a part of the normal (non-Interworking) network selection if the scan results do not match with enabled networks. This makes scanning work similarly to the "interworking_select auto" command. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
-rw-r--r--wpa_supplicant/README-HS2033
-rw-r--r--wpa_supplicant/config.c1
-rw-r--r--wpa_supplicant/config.h11
-rw-r--r--wpa_supplicant/config_file.c3
-rw-r--r--wpa_supplicant/events.c14
-rw-r--r--wpa_supplicant/interworking.c15
-rw-r--r--wpa_supplicant/interworking.h1
-rw-r--r--wpa_supplicant/scan.c3
-rw-r--r--wpa_supplicant/wpa_supplicant.conf8
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
10 files changed, 88 insertions, 2 deletions
diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20
index 0181e8b..feb9049 100644
--- a/wpa_supplicant/README-HS20
+++ b/wpa_supplicant/README-HS20
@@ -24,6 +24,31 @@ standardized in IEEE Std 802.11u-2011 which is now part of the IEEE Std
802.11-2012.
+wpa_supplicant network selection
+--------------------------------
+
+Interworking support added option for configuring credentials that can
+work with multiple networks as an alternative to configuration of
+network blocks (e.g., per-SSID parameters). When requested to perform
+network selection, wpa_supplicant picks the highest priority enabled
+network block or credential. If a credential is picked (based on ANQP
+information from APs), a temporary network block is created
+automatically for the matching network. This temporary network block is
+used similarly to the network blocks that can be configured by the user,
+but it is not stored into the configuration file and is meant to be used
+only for temporary period of time since a new one can be created
+whenever needed based on ANQP information and the credential.
+
+By default, wpa_supplicant is not using automatic network selection
+unless requested explicitly with the interworking_select command. This
+can be changed with the auto_interworking=1 parameter to perform network
+selection automatically whenever trying to find a network for connection
+and none of the enabled network blocks match with the scan results. This
+case works similarly to "interworking_select auto", i.e., wpa_supplicant
+will internally determine which network or credential is going to be
+used based on configured priorities, scan results, and ANQP information.
+
+
wpa_supplicant configuration
----------------------------
@@ -65,6 +90,14 @@ hs20=1
# This value controls the Access Network Type value in Probe Request frames.
#access_network_type=15
+# Automatic network selection behavior
+# 0 = do not automatically go through Interworking network selection
+# (i.e., require explicit interworking_select command for this; default)
+# 1 = perform Interworking network selection if one or more
+# credentials have been configured and scan did not find a
+# matching network block
+#auto_interworking=0
+
Credentials can be pre-configured for automatic network selection:
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index cecf648..c970745 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -3010,6 +3010,7 @@ static const struct global_parse_data global_fields[] = {
{ BIN(wps_nfc_dev_pw), 0 },
{ STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND },
{ INT(p2p_go_max_inactivity), 0 },
+ { INT_RANGE(auto_interworking, 0, 1), 0 },
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index c3c90e2..b889ab8 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -736,6 +736,17 @@ struct wpa_config {
int p2p_go_max_inactivity;
struct hostapd_wmm_ac_params wmm_ac_params[4];
+
+ /**
+ * auto_interworking - Whether to use network selection automatically
+ *
+ * 0 = do not automatically go through Interworking network selection
+ * (i.e., require explicit interworking_select command for this)
+ * 1 = perform Interworking network selection if one or more
+ * credentials have been configured and scan did not find a
+ * matching network block
+ */
+ int auto_interworking;
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index bd59a80..531957a 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -916,6 +916,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY)
fprintf(f, "p2p_go_max_inactivity=%d\n",
config->p2p_go_max_inactivity);
+ if (config->auto_interworking)
+ fprintf(f, "auto_interworking=%d\n",
+ config->auto_interworking);
}
#endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index cddcce7..517e11f 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -41,6 +41,7 @@
#include "bss.h"
#include "scan.h"
#include "offchannel.h"
+#include "interworking.h"
static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
@@ -1204,6 +1205,19 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
return 0;
}
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->auto_interworking &&
+ wpa_s->conf->interworking &&
+ wpa_s->conf->cred) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: "
+ "start ANQP fetch since no matching "
+ "networks found");
+ wpa_s->network_select = 1;
+ wpa_s->auto_network_select = 1;
+ interworking_start_fetch_anqp(wpa_s);
+ return 0;
+ }
+#endif /* CONFIG_INTERWORKING */
if (wpa_supplicant_req_sched_scan(wpa_s))
wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
timeout_usec);
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 11c57b4..7b5b20e 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1411,7 +1411,9 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
type = "unknown";
wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR " type=%s",
MAC2STR(bss->bssid), type);
- if (wpa_s->auto_select) {
+ if (wpa_s->auto_select ||
+ (wpa_s->conf->auto_interworking &&
+ wpa_s->auto_network_select)) {
if (selected == NULL ||
cred->priority > selected_prio) {
selected = bss;
@@ -1446,6 +1448,14 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
return;
}
+ if (wpa_s->auto_network_select) {
+ wpa_printf(MSG_DEBUG, "Interworking: Continue "
+ "scanning after ANQP fetch");
+ wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval,
+ 0);
+ return;
+ }
+
wpa_msg(wpa_s, MSG_INFO, INTERWORKING_NO_MATCH "No network "
"with matching credentials found");
}
@@ -1490,7 +1500,7 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s)
}
-static void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s)
+void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s)
{
struct wpa_bss *bss;
@@ -1748,6 +1758,7 @@ int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
{
interworking_stop_fetch_anqp(wpa_s);
wpa_s->network_select = 1;
+ wpa_s->auto_network_select = 0;
wpa_s->auto_select = !!auto_select;
wpa_printf(MSG_DEBUG, "Interworking: Start scan for network "
"selection");
diff --git a/wpa_supplicant/interworking.h b/wpa_supplicant/interworking.h
index 60566e5..cb8438e 100644
--- a/wpa_supplicant/interworking.h
+++ b/wpa_supplicant/interworking.h
@@ -24,5 +24,6 @@ int interworking_fetch_anqp(struct wpa_supplicant *wpa_s);
void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s);
int interworking_select(struct wpa_supplicant *wpa_s, int auto_select);
int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
+void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s);
#endif /* INTERWORKING_H */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 93d152e..71e7d8d 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -89,6 +89,9 @@ int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
count++;
ssid = ssid->next;
}
+ if (wpa_s->conf->cred && wpa_s->conf->interworking &&
+ wpa_s->conf->auto_interworking)
+ count++;
return count;
}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 4cf0ce1..2c07fd0 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -277,6 +277,14 @@ fast_reauth=1
# is enabled.
# hessid=00:11:22:33:44:55
+# Automatic network selection behavior
+# 0 = do not automatically go through Interworking network selection
+# (i.e., require explicit interworking_select command for this; default)
+# 1 = perform Interworking network selection if one or more
+# credentials have been configured and scan did not find a
+# matching network block
+#auto_interworking=0
+
# credential block
#
# Each credential used for automatic network selection is configured as a set
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4494bcc..01d67d9 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -570,6 +570,7 @@ struct wpa_supplicant {
unsigned int fetch_anqp_in_progress:1;
unsigned int network_select:1;
unsigned int auto_select:1;
+ unsigned int auto_network_select:1;
#endif /* CONFIG_INTERWORKING */
unsigned int drv_capa_known;