Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / ap / wmm.c
index 3668130..314e244 100644 (file)
@@ -4,14 +4,8 @@
  * Copyright 2005-2006, Devicescape Software, Inc.
  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "utils/includes.h"
@@ -23,6 +17,7 @@
 #include "ieee802_11.h"
 #include "sta_info.h"
 #include "ap_config.h"
+#include "ap_drv_ops.h"
 #include "wmm.h"
 
 
@@ -71,9 +66,12 @@ u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid)
        wmm->version = WMM_VERSION;
        wmm->qos_info = hapd->parameter_set_count & 0xf;
 
-       if (hapd->conf->wmm_uapsd)
+       if (hapd->conf->wmm_uapsd &&
+           (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
                wmm->qos_info |= 0x80;
 
+       wmm->reserved = 0;
+
        /* fill in a parameter set record for each AC */
        for (e = 0; e < 4; e++) {
                struct wmm_ac_parameter *ac = &wmm->ac[e];
@@ -94,9 +92,11 @@ u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid)
 }
 
 
-/* This function is called when a station sends an association request with
- * WMM info element. The function returns zero on success or non-zero on any
- * error in WMM element. eid does not include Element ID and Length octets. */
+/*
+ * This function is called when a station sends an association request with
+ * WMM info element. The function returns 1 on success or 0 on any error in WMM
+ * element. eid does not include Element ID and Length octets.
+ */
 int hostapd_eid_wmm_valid(struct hostapd_data *hapd, const u8 *eid, size_t len)
 {
        struct wmm_information_element *wmm;
@@ -106,7 +106,7 @@ int hostapd_eid_wmm_valid(struct hostapd_data *hapd, const u8 *eid, size_t len)
        if (len < sizeof(struct wmm_information_element)) {
                wpa_printf(MSG_DEBUG, "Too short WMM IE (len=%lu)",
                           (unsigned long) len);
-               return -1;
+               return 0;
        }
 
        wmm = (struct wmm_information_element *) eid;
@@ -117,10 +117,10 @@ int hostapd_eid_wmm_valid(struct hostapd_data *hapd, const u8 *eid, size_t len)
        if (wmm->oui_subtype != WMM_OUI_SUBTYPE_INFORMATION_ELEMENT ||
            wmm->version != WMM_VERSION) {
                wpa_printf(MSG_DEBUG, "Unsupported WMM IE Subtype/Version");
-               return -1;
+               return 0;
        }
 
-       return 0;
+       return 1;
 }
 
 
@@ -150,8 +150,8 @@ static void wmm_send_action(struct hostapd_data *hapd, const u8 *addr,
        os_memcpy(t, tspec, sizeof(struct wmm_tspec_element));
        len = ((u8 *) (t + 1)) - buf;
 
-       if (hapd->drv.send_mgmt_frame(hapd, m, len) < 0)
-               perror("wmm_send_action: send");
+       if (hostapd_drv_send_mlme(hapd, m, len, 0) < 0)
+               wpa_printf(MSG_INFO, "wmm_send_action: send failed");
 }
 
 
@@ -274,6 +274,9 @@ void hostapd_wmm_action(struct hostapd_data *hapd,
                return;
        }
 
+       if (left < 0)
+               return; /* not a valid WMM Action frame */
+
        /* extract the tspec info element */
        if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
                hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,