Enable WMM support in the test MLME code
[wpasupplicant] / wpa_supplicant / mlme.c
index ec63f51..82d7897 100644 (file)
@@ -116,8 +116,6 @@ static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s,
 }
 
 
-
-#if 0 /* FIX */
 static int ecw2cw(int ecw)
 {
        int cw = 1;
@@ -127,7 +125,6 @@ static int ecw2cw(int ecw)
        }
        return cw - 1;
 }
-#endif
 
 
 static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
@@ -136,6 +133,7 @@ static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
        size_t left;
        int count;
        u8 *pos;
+       u8 wmm_acm;
 
        if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
                return;
@@ -147,54 +145,42 @@ static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
        pos = wmm_param + 8;
        left = wmm_param_len - 8;
 
-#if 0 /* FIX */
        wmm_acm = 0;
        for (; left >= 4; left -= 4, pos += 4) {
                int aci = (pos[0] >> 5) & 0x03;
                int acm = (pos[0] >> 4) & 0x01;
-               int queue;
+               int aifs, cw_max, cw_min, burst_time;
 
                switch (aci) {
-               case 1:
-                       queue = IEEE80211_TX_QUEUE_DATA3;
+               case 1: /* AC_BK */
                        if (acm)
-                               wmm_acm |= BIT(1) | BIT(2);
+                               wmm_acm |= BIT(1) | BIT(2); /* BK/- */
                        break;
-               case 2:
-                       queue = IEEE80211_TX_QUEUE_DATA1;
+               case 2: /* AC_VI */
                        if (acm)
-                               wmm_acm |= BIT(4) | BIT(5);
+                               wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
                        break;
-               case 3:
-                       queue = IEEE80211_TX_QUEUE_DATA0;
+               case 3: /* AC_VO */
                        if (acm)
-                               wmm_acm |= BIT(6) | BIT(7);
+                               wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
                        break;
-               case 0:
+               case 0: /* AC_BE */
                default:
-                       queue = IEEE80211_TX_QUEUE_DATA2;
                        if (acm)
-                               wpa_s->mlme.wmm_acm |= BIT(0) | BIT(3);
+                               wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
                        break;
                }
 
-               params.aifs = pos[0] & 0x0f;
-               params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
-               params.cw_min = ecw2cw(pos[1] & 0x0f);
+               aifs = pos[0] & 0x0f;
+               cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
+               cw_min = ecw2cw(pos[1] & 0x0f);
                /* TXOP is in units of 32 usec; burst_time in 0.1 ms */
-               params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100;
-               wpa_printf(MSG_DEBUG, "MLME: WMM queue=%d aci=%d acm=%d "
-                          "aifs=%d cWmin=%d cWmax=%d burst=%d",
-                          queue, aci, acm, params.aifs, params.cw_min,
-                          params.cw_max, params.burst_time);
-               /* TODO: handle ACM (block TX, fallback to next lowest allowed
-                * AC for now) */
-               if (local->hw->conf_tx(local->mdev, queue, &params)) {
-                       wpa_printf(MSG_DEBUG, "MLME: failed to set TX queue "
-                                  "parameters for queue %d", queue);
-               }
+               burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100;
+               wpa_printf(MSG_DEBUG, "MLME: WMM aci=%d acm=%d aifs=%d "
+                          "cWmin=%d cWmax=%d burst=%d",
+                          aci, acm, aifs, cw_min, cw_max, burst_time);
+               /* TODO: driver configuration */
        }
-#endif
 }
 
 
@@ -459,9 +445,9 @@ static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s)
                *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
                *pos++ = 0x50;
                *pos++ = 0xf2;
-               *pos++ = 2; /* WME */
-               *pos++ = 0; /* WME info */
-               *pos++ = 1; /* WME ver */
+               *pos++ = 2; /* WMM */
+               *pos++ = 0; /* WMM info */
+               *pos++ = 1; /* WMM ver */
                *pos++ = 0;
        }
 
@@ -1087,9 +1073,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
                           status_code);
 #ifdef CONFIG_IEEE80211W
                if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
-                   elems.assoc_comeback && elems.assoc_comeback_len == 4) {
+                   elems.timeout_int && elems.timeout_int_len == 5 &&
+                   elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
                        u32 tu, ms;
-                       tu = WPA_GET_LE32(elems.assoc_comeback);
+                       tu = WPA_GET_LE32(elems.timeout_int + 1);
                        ms = tu * 1024 / 1000;
                        wpa_printf(MSG_DEBUG, "MLME: AP rejected association "
                                   "temporarily; comeback duration %u TU "
@@ -1171,14 +1158,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
                           "netstack");
        }
 
-#if 0 /* FIX? */
-       sta->assoc_ap = 1;
-
-       if (elems.wme && wpa_s->mlme.wmm_enabled) {
-               sta->flags |= WLAN_STA_WME;
-               ieee80211_sta_wmm_params(wpa_s, elems.wme, elems.wme_len);
-       }
-#endif
+       if (elems.wmm && wpa_s->mlme.wmm_enabled)
+               ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len);
 
        ieee80211_associated(wpa_s);
 }
@@ -1487,18 +1468,18 @@ static void ieee80211_bss_info(struct wpa_supplicant *wpa_s,
                bss->rsn_ie_len = 0;
        }
 
-       if (elems.wme &&
-           (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wme_len ||
-            os_memcmp(bss->wmm_ie, elems.wme, elems.wme_len))) {
+       if (elems.wmm &&
+           (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_len ||
+            os_memcmp(bss->wmm_ie, elems.wmm, elems.wmm_len))) {
                os_free(bss->wmm_ie);
-               bss->wmm_ie = os_malloc(elems.wme_len + 2);
+               bss->wmm_ie = os_malloc(elems.wmm_len + 2);
                if (bss->wmm_ie) {
-                       os_memcpy(bss->wmm_ie, elems.wme - 2,
-                                 elems.wme_len + 2);
-                       bss->wmm_ie_len = elems.wme_len + 2;
+                       os_memcpy(bss->wmm_ie, elems.wmm - 2,
+                                 elems.wmm_len + 2);
+                       bss->wmm_ie_len = elems.wmm_len + 2;
                } else
                        bss->wmm_ie_len = 0;
-       } else if (!elems.wme && bss->wmm_ie) {
+       } else if (!elems.wmm && bss->wmm_ie) {
                os_free(bss->wmm_ie);
                bss->wmm_ie = NULL;
                bss->wmm_ie_len = 0;
@@ -1594,9 +1575,9 @@ static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s,
                wpa_s->mlme.cts_protect_erp_frames = use_protection;
        }
 
-       if (elems.wme && wpa_s->mlme.wmm_enabled) {
-               ieee80211_sta_wmm_params(wpa_s, elems.wme,
-                                        elems.wme_len);
+       if (elems.wmm && wpa_s->mlme.wmm_enabled) {
+               ieee80211_sta_wmm_params(wpa_s, elems.wmm,
+                                        elems.wmm_len);
        }
 }
 
@@ -1738,9 +1719,9 @@ static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s,
 
 #ifdef CONFIG_IEEE80211W
 
-/* MLME-PING.response */
-static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
-                                       const u8 *addr, const u8 *trans_id)
+/* MLME-SAQuery.response */
+static int ieee80211_sta_send_sa_query_resp(struct wpa_supplicant *wpa_s,
+                                           const u8 *addr, const u8 *trans_id)
 {
        struct ieee80211_mgmt *mgmt;
        int res;
@@ -1749,7 +1730,7 @@ static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
        mgmt = os_zalloc(sizeof(*mgmt));
        if (mgmt == NULL) {
                wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
-                          "ping action frame");
+                          "SA Query action frame");
                return -1;
        }
 
@@ -1759,11 +1740,11 @@ static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
        os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
        mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                           WLAN_FC_STYPE_ACTION);
-       mgmt->u.action.category = WLAN_ACTION_PING;
-       mgmt->u.action.u.ping_resp.action = WLAN_PING_RESPONSE;
-       os_memcpy(mgmt->u.action.u.ping_resp.trans_id, trans_id,
-                 WLAN_PING_TRANS_ID_LEN);
-       len += 1 + sizeof(mgmt->u.action.u.ping_resp);
+       mgmt->u.action.category = WLAN_ACTION_SA_QUERY;
+       mgmt->u.action.u.sa_query_resp.action = WLAN_SA_QUERY_RESPONSE;
+       os_memcpy(mgmt->u.action.u.sa_query_resp.trans_id, trans_id,
+                 WLAN_SA_QUERY_TR_ID_LEN);
+       len += 1 + sizeof(mgmt->u.action.u.sa_query_resp);
 
        res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len);
        os_free(mgmt);
@@ -1772,36 +1753,36 @@ static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
 }
 
 
-static void ieee80211_rx_mgmt_ping_action(
+static void ieee80211_rx_mgmt_sa_query_action(
        struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
        struct ieee80211_rx_status *rx_status)
 {
-       if (len < 24 + 1 + sizeof(mgmt->u.action.u.ping_req)) {
-               wpa_printf(MSG_DEBUG, "MLME: Too short Ping Action frame");
+       if (len < 24 + 1 + sizeof(mgmt->u.action.u.sa_query_req)) {
+               wpa_printf(MSG_DEBUG, "MLME: Too short SA Query Action frame");
                return;
        }
 
-       if (mgmt->u.action.u.ping_req.action != WLAN_PING_REQUEST) {
-               wpa_printf(MSG_DEBUG, "MLME: Unexpected Ping Action %d",
-                          mgmt->u.action.u.ping_req.action);
+       if (mgmt->u.action.u.sa_query_req.action != WLAN_SA_QUERY_REQUEST) {
+               wpa_printf(MSG_DEBUG, "MLME: Unexpected SA Query Action %d",
+                          mgmt->u.action.u.sa_query_req.action);
                return;
        }
 
        if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
-               wpa_printf(MSG_DEBUG, "MLME: Ignore ping from unknown source "
-                          MACSTR, MAC2STR(mgmt->sa));
+               wpa_printf(MSG_DEBUG, "MLME: Ignore SA Query from unknown "
+                          "source " MACSTR, MAC2STR(mgmt->sa));
                return;
        }
 
        if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) {
-               wpa_printf(MSG_DEBUG, "MLME: Ignore ping request during "
+               wpa_printf(MSG_DEBUG, "MLME: Ignore SA query request during "
                           "association process");
                return;
        }
 
-       wpa_printf(MSG_DEBUG, "MLME: Replying to ping request");
-       ieee80211_sta_send_ping_resp(wpa_s, mgmt->sa,
-                                    mgmt->u.action.u.ping_req.trans_id);
+       wpa_printf(MSG_DEBUG, "MLME: Replying to SA Query request");
+       ieee80211_sta_send_sa_query_resp(wpa_s, mgmt->sa, mgmt->u.action.u.
+                                        sa_query_req.trans_id);
 }
 
 #endif /* CONFIG_IEEE80211W */
@@ -1824,8 +1805,8 @@ static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
                break;
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_IEEE80211W
-       case WLAN_ACTION_PING:
-               ieee80211_rx_mgmt_ping_action(wpa_s, mgmt, len, rx_status);
+       case WLAN_ACTION_SA_QUERY:
+               ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status);
                break;
 #endif /* CONFIG_IEEE80211W */
        default:
@@ -2865,6 +2846,8 @@ int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
        wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211B;
        wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211G;
 
+       wpa_s->mlme.wmm_enabled = 1;
+
        return 0;
 }