nl80211: Parse WMM parameters on association
authorEliad Peller <eliad@wizery.com>
Wed, 22 Oct 2014 12:03:53 +0000 (08:03 -0400)
committerJouni Malinen <j@w1.fi>
Sun, 16 Nov 2014 18:19:04 +0000 (20:19 +0200)
Set the relevant WMM parameters in the assoc_data event.

Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
src/drivers/driver_nl80211_event.c

index 4523366..ef80eb9 100644 (file)
@@ -178,8 +178,39 @@ static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static int nl80211_parse_wmm_params(struct nlattr *wmm_attr,
+                                   struct wmm_params *wmm_params)
+{
+       struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
+       static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
+               [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
+       };
+
+       if (!wmm_attr) {
+               wpa_printf(MSG_DEBUG, "nl80211: WMM data missing");
+               return -1;
+       }
+
+       if (nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
+                            wme_policy)) {
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: Failed to parse nested attributes");
+               return -1;
+       }
+
+       if (!wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
+               return -1;
+
+       wmm_params->uapsd_queues =
+               nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
+       wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
+
+       return 0;
+}
+
+
 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
-                           const u8 *frame, size_t len)
+                           const u8 *frame, size_t len, struct nlattr *wmm)
 {
        const struct ieee80211_mgmt *mgmt;
        union wpa_event_data event;
@@ -233,6 +264,8 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
 
        event.assoc_info.freq = drv->assoc_freq;
 
+       nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
+
        wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
 }
 
@@ -691,7 +724,8 @@ static void mlme_event(struct i802_bss *bss,
                       enum nl80211_commands cmd, struct nlattr *frame,
                       struct nlattr *addr, struct nlattr *timed_out,
                       struct nlattr *freq, struct nlattr *ack,
-                      struct nlattr *cookie, struct nlattr *sig)
+                      struct nlattr *cookie, struct nlattr *sig,
+                      struct nlattr *wmm)
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
        const u8 *data;
@@ -738,7 +772,7 @@ static void mlme_event(struct i802_bss *bss,
                mlme_event_auth(drv, nla_data(frame), nla_len(frame));
                break;
        case NL80211_CMD_ASSOCIATE:
-               mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
+               mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm);
                break;
        case NL80211_CMD_DEAUTHENTICATE:
                mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
@@ -1683,7 +1717,8 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
                           tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
                           tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
                           tb[NL80211_ATTR_COOKIE],
-                          tb[NL80211_ATTR_RX_SIGNAL_DBM]);
+                          tb[NL80211_ATTR_RX_SIGNAL_DBM],
+                          tb[NL80211_ATTR_STA_WME]);
                break;
        case NL80211_CMD_CONNECT:
        case NL80211_CMD_ROAM:
@@ -1875,7 +1910,8 @@ int process_bss_event(struct nl_msg *msg, void *arg)
                           tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
                           tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
                           tb[NL80211_ATTR_COOKIE],
-                          tb[NL80211_ATTR_RX_SIGNAL_DBM]);
+                          tb[NL80211_ATTR_RX_SIGNAL_DBM],
+                          tb[NL80211_ATTR_STA_WME]);
                break;
        case NL80211_CMD_UNEXPECTED_FRAME:
                nl80211_spurious_frame(bss, tb, 0);