From a45b2dc5dc809e18e47be7762d22a5b4258b62d5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 6 Aug 2013 16:14:25 +0300 Subject: [PATCH] HS 2.0R2: Add support for Policy/MaximumBSSLoadValue The new credential parameter max_bss_load can be used to specify restrictions on BSS Load in the home network. Signed-hostap: Jouni Malinen --- wpa_supplicant/README-HS20 | 7 ++++++ wpa_supplicant/config.c | 5 +++++ wpa_supplicant/config.h | 9 ++++++++ wpa_supplicant/config_file.c | 4 ++++ wpa_supplicant/interworking.c | 36 ++++++++++++++++++++++++++++-- wpa_supplicant/wpa_supplicant.conf | 7 ++++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20 index 57abdbf75..c79b05ef2 100644 --- a/wpa_supplicant/README-HS20 +++ b/wpa_supplicant/README-HS20 @@ -237,6 +237,13 @@ Credentials can be pre-configured for automatic network selection: # min_dl_bandwidth_roaming # min_ul_bandwidth_roaming # +# max_bss_load: Maximum BSS Load Channel Utilization (1..255) +# (PPS//Policy/MaximumBSSLoadValue) +# This value is used as the maximum channel utilization for network +# selection purposes for home networks. If the AP does not advertise +# BSS Load or if the limit would prevent any connection, this constraint +# will be ignored. +# # for example: # #cred={ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index ab7a68071..f4a81aa05 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2473,6 +2473,11 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, return 0; } + if (os_strcmp(var, "max_bss_load") == 0) { + cred->max_bss_load = atoi(value); + return 0; + } + val = wpa_config_parse_string(value, &len); if (val == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string " diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index b37a97495..f2da234d4 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -256,6 +256,15 @@ struct wpa_cred { unsigned int min_ul_bandwidth_home; unsigned int min_dl_bandwidth_roaming; unsigned int min_ul_bandwidth_roaming; + + /** + * max_bss_load - Maximum BSS Load Channel Utilization (1..255) + * This value is used as the maximum channel utilization for network + * selection purposes for home networks. If the AP does not advertise + * BSS Load or if the limit would prevent any connection, this + * constraint will be ignored. + */ + unsigned int max_bss_load; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index e50c86abc..53631b91e 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -822,6 +822,10 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) if (cred->min_ul_bandwidth_roaming) fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n", cred->min_ul_bandwidth_roaming); + + if (cred->max_bss_load) + fprintf(f, "\tmax_bss_load=%u\n", + cred->max_bss_load); } diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 7f42e7717..860cddca5 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -1131,6 +1131,28 @@ static int cred_below_min_backhaul(struct wpa_supplicant *wpa_s, } +static int cred_over_max_bss_load(struct wpa_supplicant *wpa_s, + struct wpa_cred *cred, struct wpa_bss *bss) +{ + const u8 *ie; + int res; + + if (!cred->max_bss_load) + return 0; /* No BSS Load constraint specified */ + + ie = wpa_bss_get_ie(bss, WLAN_EID_BSS_LOAD); + if (ie == NULL || ie[1] < 3) + return 0; /* No BSS Load advertised */ + + res = interworking_home_sp_cred(wpa_s, cred, bss->anqp ? + bss->anqp->domain_name : NULL); + if (res <= 0) + return 0; /* Not a home network */ + + return ie[4] > cred->max_bss_load; +} + + static struct wpa_cred * interworking_credentials_available_roaming_consortium( struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw) { @@ -1164,6 +1186,8 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium( continue; if (!ignore_bw && cred_below_min_backhaul(wpa_s, cred, bss)) continue; + if (!ignore_bw && cred_over_max_bss_load(wpa_s, cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) @@ -1656,6 +1680,9 @@ static struct wpa_cred * interworking_credentials_available_3gpp( if (!ignore_bw && cred_below_min_backhaul(wpa_s, cred, bss)) continue; + if (!ignore_bw && + cred_over_max_bss_load(wpa_s, cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) selected = cred; @@ -1703,6 +1730,9 @@ static struct wpa_cred * interworking_credentials_available_realm( if (!ignore_bw && cred_below_min_backhaul(wpa_s, cred, bss)) continue; + if (!ignore_bw && + cred_over_max_bss_load(wpa_s, cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) selected = cred; @@ -1994,10 +2024,12 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s) type = "roaming"; else type = "unknown"; - wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR " type=%s%s", + wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR " type=%s%s%s", MAC2STR(bss->bssid), type, cred_below_min_backhaul(wpa_s, cred, bss) ? - " below_min_backhaul=1" : ""); + " below_min_backhaul=1" : "", + cred_over_max_bss_load(wpa_s, cred, bss) ? + " over_max_bss_load=1" : ""); if (wpa_s->auto_select || (wpa_s->conf->auto_interworking && wpa_s->auto_network_select)) { diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 42954e6ab..3b0ea717f 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -456,6 +456,13 @@ fast_reauth=1 # min_dl_bandwidth_roaming # min_ul_bandwidth_roaming # +# max_bss_load: Maximum BSS Load Channel Utilization (1..255) +# (PPS//Policy/MaximumBSSLoadValue) +# This value is used as the maximum channel utilization for network +# selection purposes for home networks. If the AP does not advertise +# BSS Load or if the limit would prevent any connection, this constraint +# will be ignored. +# # for example: # #cred={