}
+static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
+{
+ if (nl80211_alloc_mgmt_handle(bss))
+ return -1;
+ wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
+ "handle %p (device SME)", bss->nl_mgmt);
+
+ if (nl80211_register_frame(bss, bss->nl_mgmt,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_ACTION << 4),
+ NULL, 0) < 0)
+ goto out_err;
+
+ return 0;
+
+out_err:
+ eloop_unregister_read_sock(nl_socket_get_fd(bss->nl_mgmt));
+ nl_destroy_handles(&bss->nl_mgmt);
+ return -1;
+}
+
+
static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
{
if (bss->nl_mgmt == NULL)
if (nl80211_mgmt_subscribe_ap(bss))
return -1;
+ if (drv->device_ap_sme && !drv->use_monitor)
+ if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
+ return -1;
+
if (!drv->device_ap_sme && drv->use_monitor &&
nl80211_create_monitor_interface(drv) &&
!drv->device_ap_sme)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
- if (drv->device_ap_sme)
+ if (drv->device_ap_sme) {
wpa_driver_nl80211_probe_req_report(bss, 0);
- else if (drv->use_monitor)
+ if (!drv->use_monitor)
+ nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
+ } else if (drv->use_monitor)
nl80211_remove_monitor_interface(drv);
else
nl80211_mgmt_unsubscribe(bss, "AP teardown");