Parcourir la source

P2P: Add mechanism for configuring UAPSD parameters for group

This is needed to be able to change parameters for dynamically
created interfaces between the creation of the interface and
association/start AP commands.

Following ctrl_interface commands can now be used:

P2P_SET client_apsd disable
- disable configuration (i.e., use driver default) in client mode

P2P_SET client_apsd <BE>,<BK>,<VI>,<VO>;<max SP Length>
- enable UASPD with specific trigger configuration (0/1) per AC
  (max SP Length is currently ignored)

P2P_SET go_apsd disable
- disable configuration (i.e., use driver default) in AP mode

P2P_SET go_apsd <0/1>
- disable/enable APSD in AP mode
Jouni Malinen il y a 14 ans
Parent
commit
eea2fd9eff

+ 8 - 0
src/drivers/driver.h

@@ -481,6 +481,14 @@ struct wpa_driver_associate_params {
 	 * p2p - Whether this connection is a P2P group
 	 */
 	int p2p;
+
+	/**
+	 * uapsd - UAPSD parameters for the network
+	 * -1 = do not change defaults
+	 * AP mode: 1 = enabled, 0 = disabled
+	 * STA mode: bits 0..3 UAPSD enabled for VO,VI,BK,BE
+	 */
+	int uapsd;
 };
 
 /**

+ 5 - 0
wpa_supplicant/ap.c

@@ -296,6 +296,11 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
 		params.p2p = 1;
 #endif /* CONFIG_P2P */
 
+	if (wpa_s->parent->set_ap_uapsd)
+		params.uapsd = wpa_s->parent->ap_uapsd;
+	else
+		params.uapsd = -1;
+
 	if (wpa_drv_associate(wpa_s, &params) < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
 		return -1;

+ 49 - 0
wpa_supplicant/ctrl_iface.c

@@ -2479,6 +2479,55 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 	if (os_strcmp(cmd, "cross_connect") == 0)
 		return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
 
+	if (os_strcmp(cmd, "go_apsd") == 0) {
+		if (os_strcmp(param, "disable") == 0)
+			wpa_s->set_ap_uapsd = 0;
+		else {
+			wpa_s->set_ap_uapsd = 1;
+			wpa_s->ap_uapsd = atoi(param);
+		}
+		return 0;
+	}
+
+	if (os_strcmp(cmd, "client_apsd") == 0) {
+		if (os_strcmp(param, "disable") == 0)
+			wpa_s->set_sta_uapsd = 0;
+		else {
+			int be, bk, vi, vo;
+			char *pos;
+			/* format: BE,BK,VI,VO;max SP Length */
+			be = atoi(param);
+			pos = os_strchr(param, ',');
+			if (pos == NULL)
+				return -1;
+			pos++;
+			bk = atoi(pos);
+			pos = os_strchr(pos, ',');
+			if (pos == NULL)
+				return -1;
+			pos++;
+			vi = atoi(pos);
+			pos = os_strchr(pos, ',');
+			if (pos == NULL)
+				return -1;
+			pos++;
+			vo = atoi(pos);
+			/* ignore max SP Length for now */
+
+			wpa_s->set_sta_uapsd = 1;
+			wpa_s->sta_uapsd = 0;
+			if (be)
+				wpa_s->sta_uapsd |= BIT(0);
+			if (bk)
+				wpa_s->sta_uapsd |= BIT(1);
+			if (vi)
+				wpa_s->sta_uapsd |= BIT(2);
+			if (vo)
+				wpa_s->sta_uapsd |= BIT(3);
+		}
+		return 0;
+	}
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
 		   cmd);
 

+ 5 - 0
wpa_supplicant/sme.c

@@ -386,6 +386,11 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
 	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
 		params.p2p = 1;
 
+	if (wpa_s->parent->set_sta_uapsd)
+		params.uapsd = wpa_s->parent->sta_uapsd;
+	else
+		params.uapsd = -1;
+
 	if (wpa_drv_associate(wpa_s, &params) < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
 			"failed");

+ 5 - 0
wpa_supplicant/wpa_supplicant.c

@@ -1283,6 +1283,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 		params.p2p = 1;
 #endif /* CONFIG_P2P */
 
+	if (wpa_s->parent->set_sta_uapsd)
+		params.uapsd = wpa_s->parent->sta_uapsd;
+	else
+		params.uapsd = -1;
+
 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
 		ret = ieee80211_sta_associate(wpa_s, &params);
 	else

+ 5 - 0
wpa_supplicant/wpa_supplicant_i.h

@@ -424,6 +424,11 @@ struct wpa_supplicant {
 
 	struct ibss_rsn *ibss_rsn;
 
+	int set_sta_uapsd;
+	int sta_uapsd;
+	int set_ap_uapsd;
+	int ap_uapsd;
+
 #ifdef CONFIG_SME
 	struct {
 		u8 ssid[32];