Updated to hostap_2_6
[mech_eap.git] / libeap / src / ap / wnm_ap.c
index 4c8bc10..41d50ce 100644 (file)
@@ -17,6 +17,7 @@
 #include "ap/ap_config.h"
 #include "ap/ap_drv_ops.h"
 #include "ap/wpa_auth.h"
+#include "mbo_ap.h"
 #include "wnm_ap.h"
 
 #define MAX_TFS_IE_LEN  1024
@@ -94,6 +95,7 @@ static int ieee802_11_send_wnmsleep_resp(struct hostapd_data *hapd,
        if (mgmt == NULL) {
                wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
                           "WNM-Sleep Response action frame");
+               os_free(wnmtfs_ie);
                return -1;
        }
        os_memcpy(mgmt->da, addr, ETH_ALEN);
@@ -376,6 +378,29 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
 }
 
 
+static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
+                                              const u8 *addr, const u8 *buf,
+                                              size_t len)
+{
+       u8 dialog_token, type;
+
+       if (len < 2)
+               return;
+       dialog_token = *buf++;
+       type = *buf++;
+       len -= 2;
+
+       wpa_printf(MSG_DEBUG,
+                  "WNM: Received WNM Notification Request frame from "
+                  MACSTR " (dialog_token=%u type=%u)",
+                  MAC2STR(addr), dialog_token, type);
+       wpa_hexdump(MSG_MSGDUMP, "WNM: Notification Request subelements",
+                   buf, len);
+       if (type == WLAN_EID_VENDOR_SPECIFIC)
+               mbo_ap_wnm_notification_req(hapd, addr, buf, len);
+}
+
+
 int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
                                const struct ieee80211_mgmt *mgmt, size_t len)
 {
@@ -402,6 +427,10 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
        case WNM_SLEEP_MODE_REQ:
                ieee802_11_rx_wnmsleep_req(hapd, mgmt->sa, payload, plen);
                return 0;
+       case WNM_NOTIFICATION_REQ:
+               ieee802_11_rx_wnm_notification_req(hapd, mgmt->sa, payload,
+                                                  plen);
+               return 0;
        }
 
        wpa_printf(MSG_DEBUG, "WNM: Unsupported WNM Action %u from " MACSTR,
@@ -527,7 +556,8 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
 int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
                        u8 req_mode, int disassoc_timer, u8 valid_int,
                        const u8 *bss_term_dur, const char *url,
-                       const u8 *nei_rep, size_t nei_rep_len)
+                       const u8 *nei_rep, size_t nei_rep_len,
+                       const u8 *mbo_attrs, size_t mbo_len)
 {
        u8 *buf, *pos;
        struct ieee80211_mgmt *mgmt;
@@ -536,7 +566,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
        wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
                   MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x",
                   MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int);
-       buf = os_zalloc(1000 + nei_rep_len);
+       buf = os_zalloc(1000 + nei_rep_len + mbo_len);
        if (buf == NULL)
                return -1;
        mgmt = (struct ieee80211_mgmt *) buf;
@@ -579,6 +609,11 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
                pos += nei_rep_len;
        }
 
+       if (mbo_len > 0) {
+               pos += mbo_add_ie(pos, buf + sizeof(buf) - pos, mbo_attrs,
+                                 mbo_len);
+       }
+
        if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
                wpa_printf(MSG_DEBUG,
                           "Failed to send BSS Transition Management Request frame");