diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20 index e65efeea4..c8a00e284 100644 --- a/wpa_supplicant/README-HS20 +++ b/wpa_supplicant/README-HS20 @@ -227,6 +227,12 @@ Credentials can be pre-configured for automatic network selection: # This optional field can be used to keep track of the SP that provisioned # the credential to find the PPS MO (./Wi-Fi/). # +# sp_priority: Credential priority within a provisioning SP +# This is the priority of the credential among all credentials +# provisionined by the same SP (i.e., for entries that have identical +# provisioning_sp value). The range of this priority is 0-255 with 0 +# being the highest and 255 the lower priority. +# # Minimum backhaul threshold (PPS//Policy/MinBackhauldThreshold/*) # These fields can be used to specify minimum download/upload backhaul # bandwidth that is preferred for the credential. This constraint is diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 3132a2c2b..9394a9c11 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2485,6 +2485,14 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, return 0; } + if (os_strcmp(var, "sp_priority") == 0) { + int prio = atoi(value); + if (prio < 0 || prio > 255) + return -1; + cred->sp_priority = prio; + return 0; + } + if (os_strcmp(var, "pcsc") == 0) { cred->pcsc = atoi(value); return 0; diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 55c5dc68f..a981ca942 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -252,6 +252,16 @@ struct wpa_cred { */ char *provisioning_sp; + /** + * sp_priority - Credential priority within a provisioning SP + * + * This is the priority of the credential among all credentials + * provisionined by the same SP (i.e., for entries that have identical + * provisioning_sp value). The range of this priority is 0-255 with 0 + * being the highest and 255 the lower priority. + */ + int sp_priority; + unsigned int min_dl_bandwidth_home; unsigned int min_ul_bandwidth_home; unsigned int min_dl_bandwidth_roaming; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 53631b91e..436204be4 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -809,6 +809,8 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) if (cred->provisioning_sp) fprintf(f, "\tprovisioning_sp=%s\n", cred->provisioning_sp); + if (cred->sp_priority) + fprintf(f, "\tsp_priority=%d\n", cred->sp_priority); if (cred->min_dl_bandwidth_home) fprintf(f, "\tmin_dl_bandwidth_home=%u\n", diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 2a9caff1a..345f11666 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -59,6 +59,13 @@ static int cred_prio_cmp(const struct wpa_cred *a, const struct wpa_cred *b) return 1; if (a->priority < b->priority) return -1; + if (a->provisioning_sp == NULL || b->provisioning_sp == NULL || + os_strcmp(a->provisioning_sp, b->provisioning_sp) != 0) + return 0; + if (a->sp_priority < b->sp_priority) + return 1; + if (a->sp_priority > b->sp_priority) + return -1; return 0; } @@ -1514,8 +1521,9 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_s, bss, 0, excl); if (cred_rc) { wpa_printf(MSG_DEBUG, "Interworking: Highest roaming " - "consortium matching credential priority %d", - cred_rc->priority); + "consortium matching credential priority %d " + "sp_priority %d", + cred_rc->priority, cred_rc->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -1523,8 +1531,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, cred = interworking_credentials_available_realm(wpa_s, bss, 0, excl); if (cred) { wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm list " - "matching credential priority %d", - cred->priority); + "matching credential priority %d sp_priority %d", + cred->priority, cred->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -1533,7 +1541,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, excl); if (cred_3gpp) { wpa_printf(MSG_DEBUG, "Interworking: Highest 3GPP matching " - "credential priority %d", cred_3gpp->priority); + "credential priority %d sp_priority %d", + cred_3gpp->priority, cred_3gpp->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -1545,8 +1554,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, if (cred_rc) { wpa_printf(MSG_DEBUG, "Interworking: Highest roaming " "consortium matching credential priority %d " - "(ignore BW)", - cred_rc->priority); + "sp_priority %d (ignore BW)", + cred_rc->priority, cred_rc->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -1556,7 +1565,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, if (cred) { wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm " "list matching credential priority %d " - "(ignore BW)", cred->priority); + "sp_priority %d (ignore BW)", + cred->priority, cred->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -1565,8 +1575,9 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, 1, excl); if (cred_3gpp) { wpa_printf(MSG_DEBUG, "Interworking: Highest 3GPP " - "matching credential priority %d (ignore BW)", - cred_3gpp->priority); + "matching credential priority %d " + "sp_priority %d (ignore BW)", + cred_3gpp->priority, cred_3gpp->sp_priority); if (allow_excluded && excl && !(*excl)) excl = NULL; } @@ -2245,13 +2256,13 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s) bh = cred_below_min_backhaul(wpa_s, cred, bss); bss_load = cred_over_max_bss_load(wpa_s, cred, bss); conn_capab = cred_conn_capab_missing(wpa_s, cred, bss); - wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d", + wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d", excluded ? INTERWORKING_BLACKLISTED : INTERWORKING_AP, MAC2STR(bss->bssid), type, bh ? " below_min_backhaul=1" : "", bss_load ? " over_max_bss_load=1" : "", conn_capab ? " conn_capab_missing=1" : "", - cred->id, cred->priority); + cred->id, cred->priority, cred->sp_priority); if (excluded) continue; if (wpa_s->auto_select ||