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>
This commit is contained in:
parent
b1f122964e
commit
4d5bda5fca
10 changed files with 88 additions and 2 deletions
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue