static void nl80211_register_eloop_read(struct nl_handle **handle,
eloop_sock_handler handler,
- void *eloop_data)
+ void *eloop_data, int persist)
{
#ifdef CONFIG_LIBNL20
/*
nl_socket_set_nonblocking(*handle);
eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
eloop_data, *handle);
- *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
+ if (!persist)
+ *handle = (void *) (((intptr_t) *handle) ^
+ ELOOP_SOCKET_INVALID);
}
-static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
+static void nl80211_destroy_eloop_handle(struct nl_handle **handle, int persist)
{
- *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
+ if (!persist)
+ *handle = (void *) (((intptr_t) *handle) ^
+ ELOOP_SOCKET_INVALID);
eloop_unregister_read_sock(nl_socket_get_fd(*handle));
nl_destroy_handles(handle);
}
}
nl80211_register_eloop_read(&w->nl_beacons,
- nl80211_recv_beacons, w);
+ nl80211_recv_beacons, w, 0);
}
dl_list_add(&nl80211_wiphys, &w->list);
return;
if (w->nl_beacons)
- nl80211_destroy_eloop_handle(&w->nl_beacons);
+ nl80211_destroy_eloop_handle(&w->nl_beacons, 0);
nl_cb_put(w->nl_cb);
dl_list_del(&w->list);
nl80211_register_eloop_read(&global->nl_event,
wpa_driver_nl80211_event_receive,
- global->nl_cb);
+ global->nl_cb, 0);
return 0;
{
nl80211_register_eloop_read(&bss->nl_mgmt,
wpa_driver_nl80211_event_receive,
- bss->nl_cb);
+ bss->nl_cb, 0);
}
}
+static int nl80211_init_connect_handle(struct i802_bss *bss)
+{
+ if (bss->nl_connect) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Connect handle already created (nl_connect=%p)",
+ bss->nl_connect);
+ return -1;
+ }
+
+ bss->nl_connect = nl_create_handle(bss->nl_cb, "connect");
+ if (!bss->nl_connect)
+ return -1;
+ nl80211_register_eloop_read(&bss->nl_connect,
+ wpa_driver_nl80211_event_receive,
+ bss->nl_cb, 1);
+ return 0;
+}
+
+
static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
return;
wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
"(%s)", bss->nl_mgmt, reason);
- nl80211_destroy_eloop_handle(&bss->nl_mgmt);
+ nl80211_destroy_eloop_handle(&bss->nl_mgmt, 0);
nl80211_put_wiphy_data_ap(bss);
}
if (drv->vendor_cmd_test_avail)
qca_vendor_test(drv);
+ nl80211_init_connect_handle(bss);
+
return 0;
}
nl80211_del_p2pdev(bss);
}
+ if (bss->nl_connect)
+ nl80211_destroy_eloop_handle(&bss->nl_connect, 1);
+
nl80211_destroy_bss(drv->first_bss);
os_free(drv->filter_ssids);
static int wpa_driver_nl80211_try_connect(
struct wpa_driver_nl80211_data *drv,
- struct wpa_driver_associate_params *params)
+ struct wpa_driver_associate_params *params,
+ struct nl_handle *nl_connect)
{
struct nl_msg *msg;
enum nl80211_auth_type type;
if (ret)
goto fail;
- ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ if (nl_connect)
+ ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL);
+ else
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+
msg = NULL;
if (ret) {
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
static int wpa_driver_nl80211_connect(
struct wpa_driver_nl80211_data *drv,
- struct wpa_driver_associate_params *params)
+ struct wpa_driver_associate_params *params,
+ struct nl_handle *nl_connect)
{
int ret;
else
os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
- ret = wpa_driver_nl80211_try_connect(drv, params);
+ ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
if (ret == -EALREADY) {
/*
* cfg80211 does not currently accept new connections if
if (wpa_driver_nl80211_disconnect(
drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
return -1;
- ret = wpa_driver_nl80211_try_connect(drv, params);
+ ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
}
return ret;
}
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
enum nl80211_iftype nlmode = params->p2p ?
NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
+ struct nl_handle *nl_connect = NULL;
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
return -1;
- return wpa_driver_nl80211_connect(drv, params);
+ if (params->auth_alg & WPA_AUTH_ALG_SAE)
+ nl_connect = bss->nl_connect;
+ return wpa_driver_nl80211_connect(drv, params, nl_connect);
}
nl80211_mark_disconnected(drv);
} else if (bss->nl_preq) {
wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
"reporting nl_preq=%p", bss->nl_preq);
- nl80211_destroy_eloop_handle(&bss->nl_preq);
+ nl80211_destroy_eloop_handle(&bss->nl_preq, 0);
}
return 0;
}
nl80211_register_eloop_read(&bss->nl_preq,
wpa_driver_nl80211_event_receive,
- bss->nl_cb);
+ bss->nl_cb, 0);
return 0;
nl_destroy_handles(&global->nl);
if (global->nl_event)
- nl80211_destroy_eloop_handle(&global->nl_event);
+ nl80211_destroy_eloop_handle(&global->nl_event, 0);
nl_cb_put(global->nl_cb);