Browse Source

Interworking: Add sp_priority cred parameter

This new priority parameter can be used to specify priorities between
credentials provisioned by the same SP. cred->priority is checked first
and if it is same and the provisioning_sp parameter matches, the new
sp_priority is used to order the credentials. It should be noted that
the order of priorities is different (higher 'priority' value indicates
higher priority of the credential, while higher 'sp_priority' indicates
lower priority of the credential).

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 11 years ago
parent
commit
74794891c7

+ 6 - 0
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
 #	This optional field can be used to keep track of the SP that provisioned
 #	the credential to find the PPS MO (./Wi-Fi/<provisioning_sp>).
 #	the credential to find the PPS MO (./Wi-Fi/<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.
+#
 # Minimum backhaul threshold (PPS/<X+>/Policy/MinBackhauldThreshold/*)
 # Minimum backhaul threshold (PPS/<X+>/Policy/MinBackhauldThreshold/*)
 #	These fields can be used to specify minimum download/upload backhaul
 #	These fields can be used to specify minimum download/upload backhaul
 #	bandwidth that is preferred for the credential. This constraint is
 #	bandwidth that is preferred for the credential. This constraint is

+ 8 - 0
wpa_supplicant/config.c

@@ -2485,6 +2485,14 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
 		return 0;
 		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) {
 	if (os_strcmp(var, "pcsc") == 0) {
 		cred->pcsc = atoi(value);
 		cred->pcsc = atoi(value);
 		return 0;
 		return 0;

+ 10 - 0
wpa_supplicant/config.h

@@ -252,6 +252,16 @@ struct wpa_cred {
 	 */
 	 */
 	char *provisioning_sp;
 	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_dl_bandwidth_home;
 	unsigned int min_ul_bandwidth_home;
 	unsigned int min_ul_bandwidth_home;
 	unsigned int min_dl_bandwidth_roaming;
 	unsigned int min_dl_bandwidth_roaming;

+ 2 - 0
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)
 	if (cred->provisioning_sp)
 		fprintf(f, "\tprovisioning_sp=%s\n", 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)
 	if (cred->min_dl_bandwidth_home)
 		fprintf(f, "\tmin_dl_bandwidth_home=%u\n",
 		fprintf(f, "\tmin_dl_bandwidth_home=%u\n",

+ 23 - 12
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;
 		return 1;
 	if (a->priority < b->priority)
 	if (a->priority < b->priority)
 		return -1;
 		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;
 	return 0;
 }
 }
 
 
@@ -1514,8 +1521,9 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s,
 		wpa_s, bss, 0, excl);
 		wpa_s, bss, 0, excl);
 	if (cred_rc) {
 	if (cred_rc) {
 		wpa_printf(MSG_DEBUG, "Interworking: Highest roaming "
 		wpa_printf(MSG_DEBUG, "Interworking: Highest roaming "
-			   "consortium matching credential priority %d",
+			   "consortium matching credential priority %d "
-			   cred_rc->priority);
+			   "sp_priority %d",
+			   cred_rc->priority, cred_rc->sp_priority);
 		if (allow_excluded && excl && !(*excl))
 		if (allow_excluded && excl && !(*excl))
 			excl = NULL;
 			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);
 	cred = interworking_credentials_available_realm(wpa_s, bss, 0, excl);
 	if (cred) {
 	if (cred) {
 		wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm list "
 		wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm list "
-			   "matching credential priority %d",
+			   "matching credential priority %d sp_priority %d",
-			   cred->priority);
+			   cred->priority, cred->sp_priority);
 		if (allow_excluded && excl && !(*excl))
 		if (allow_excluded && excl && !(*excl))
 			excl = NULL;
 			excl = NULL;
 	}
 	}
@@ -1533,7 +1541,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s,
 							    excl);
 							    excl);
 	if (cred_3gpp) {
 	if (cred_3gpp) {
 		wpa_printf(MSG_DEBUG, "Interworking: Highest 3GPP matching "
 		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))
 		if (allow_excluded && excl && !(*excl))
 			excl = NULL;
 			excl = NULL;
 	}
 	}
@@ -1545,8 +1554,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s,
 		if (cred_rc) {
 		if (cred_rc) {
 			wpa_printf(MSG_DEBUG, "Interworking: Highest roaming "
 			wpa_printf(MSG_DEBUG, "Interworking: Highest roaming "
 				   "consortium matching credential priority %d "
 				   "consortium matching credential priority %d "
-				   "(ignore BW)",
+				   "sp_priority %d (ignore BW)",
-				   cred_rc->priority);
+				   cred_rc->priority, cred_rc->sp_priority);
 			if (allow_excluded && excl && !(*excl))
 			if (allow_excluded && excl && !(*excl))
 				excl = NULL;
 				excl = NULL;
 		}
 		}
@@ -1556,7 +1565,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s,
 		if (cred) {
 		if (cred) {
 			wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm "
 			wpa_printf(MSG_DEBUG, "Interworking: Highest NAI Realm "
 				   "list matching credential priority %d "
 				   "list matching credential priority %d "
-				   "(ignore BW)", cred->priority);
+				   "sp_priority %d (ignore BW)",
+				   cred->priority, cred->sp_priority);
 			if (allow_excluded && excl && !(*excl))
 			if (allow_excluded && excl && !(*excl))
 				excl = NULL;
 				excl = NULL;
 		}
 		}
@@ -1565,8 +1575,9 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s,
 								    1, excl);
 								    1, excl);
 		if (cred_3gpp) {
 		if (cred_3gpp) {
 			wpa_printf(MSG_DEBUG, "Interworking: Highest 3GPP "
 			wpa_printf(MSG_DEBUG, "Interworking: Highest 3GPP "
-				   "matching credential priority %d (ignore BW)",
+				   "matching credential priority %d "
-				   cred_3gpp->priority);
+				   "sp_priority %d (ignore BW)",
+				   cred_3gpp->priority, cred_3gpp->sp_priority);
 			if (allow_excluded && excl && !(*excl))
 			if (allow_excluded && excl && !(*excl))
 				excl = NULL;
 				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);
 		bh = cred_below_min_backhaul(wpa_s, cred, bss);
 		bss_load = cred_over_max_bss_load(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);
 		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,
 			excluded ? INTERWORKING_BLACKLISTED : INTERWORKING_AP,
 			MAC2STR(bss->bssid), type,
 			MAC2STR(bss->bssid), type,
 			bh ? " below_min_backhaul=1" : "",
 			bh ? " below_min_backhaul=1" : "",
 			bss_load ? " over_max_bss_load=1" : "",
 			bss_load ? " over_max_bss_load=1" : "",
 			conn_capab ? " conn_capab_missing=1" : "",
 			conn_capab ? " conn_capab_missing=1" : "",
-			cred->id, cred->priority);
+			cred->id, cred->priority, cred->sp_priority);
 		if (excluded)
 		if (excluded)
 			continue;
 			continue;
 		if (wpa_s->auto_select ||
 		if (wpa_s->auto_select ||