P2P: Add mechanism for configuring UAPSD parameters for group
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 28 Jul 2010 17:18:52 +0000 (10:18 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 9 Sep 2010 14:17:21 +0000 (07:17 -0700)
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

src/drivers/driver.h
wpa_supplicant/ap.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 27e8831..7f1f526 100644 (file)
@@ -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;
 };
 
 /**
index 8d173ff..dd41c20 100644 (file)
@@ -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;
index 739b9e9..4357ada 100644 (file)
@@ -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);
 
index 23ffe80..985c900 100644 (file)
@@ -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");
index 8536b45..bbfa291 100644 (file)
@@ -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
index fb1b955..ca3a273 100644 (file)
@@ -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];