diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig index 101e2cce08640..a9c9518a1d5db 100644 --- a/lib/os/zvfs/Kconfig +++ b/lib/os/zvfs/Kconfig @@ -26,6 +26,7 @@ if ZVFS_EVENTFD config ZVFS_EVENTFD_MAX int "Maximum number of ZVFS eventfd's" + default 8 if WIFI_NM_WPA_SUPPLICANT default 1 range 1 4096 help diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 715cb4600ec70..7b1294cbb1ff4 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -13,11 +13,12 @@ config WIFI_NM_WPA_SUPPLICANT select XSI_SINGLE_PROCESS select NET_SOCKETS select NET_SOCKETS_PACKET - select NET_SOCKETPAIR select NET_L2_WIFI_MGMT select WIFI_NM select EXPERIMENTAL select COMMON_LIBC_MALLOC + select ZVFS + select ZVFS_EVENTFD help WPA supplicant as a network management backend for WIFI_NM. diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index ab20729448d37..4549ab3160d2c 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -11,6 +11,7 @@ LOG_MODULE_REGISTER(wifi_supplicant, CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL); #include <zephyr/kernel.h> #include <zephyr/init.h> #include <poll.h> +#include <zephyr/zvfs/eventfd.h> #if !defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE) && !defined(CONFIG_MBEDTLS_ENABLE_HEAP) #include <mbedtls/platform.h> @@ -44,6 +45,7 @@ static K_THREAD_STACK_DEFINE(iface_wq_stack, CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_ST #include "fst/fst.h" #include "includes.h" #include "wpa_cli_zephyr.h" +#include "ctrl_iface_zephyr.h" #ifdef CONFIG_WIFI_NM_HOSTAPD_AP #include "hostapd.h" #include "hapd_main.h" @@ -109,7 +111,8 @@ struct supplicant_context { struct net_mgmt_event_callback cb; struct net_if *iface; char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; - int event_socketpair[2]; + struct k_fifo fifo; + int sock; struct k_work iface_work; struct k_work_q iface_wq; int (*iface_handler)(struct supplicant_context *ctx, struct net_if *iface); @@ -139,39 +142,25 @@ struct k_work_q *get_workq(void) return &get_default_context()->iface_wq; } +/* found in hostap/wpa_supplicant/ctrl_iface_zephyr.c */ +extern int send_data(struct k_fifo *fifo, int sock, const char *buf, size_t len, int flags); + int zephyr_wifi_send_event(const struct wpa_supplicant_event_msg *msg) { struct supplicant_context *ctx; - struct pollfd fds[1]; int ret; /* TODO: Fix this to get the correct container */ ctx = get_default_context(); - if (ctx->event_socketpair[1] < 0) { + if (ctx->sock < 0) { ret = -ENOENT; goto out; } - fds[0].fd = ctx->event_socketpair[0]; - fds[0].events = POLLOUT; - fds[0].revents = 0; - - ret = zsock_poll(fds, 1, WRITE_TIMEOUT); - if (ret < 0) { - ret = -errno; - LOG_ERR("Cannot write event (%d)", ret); - goto out; - } - - ret = zsock_send(ctx->event_socketpair[1], msg, sizeof(*msg), 0); - if (ret < 0) { - ret = -errno; - LOG_WRN("Event send failed (%d)", ret); - goto out; - } - - if (ret != sizeof(*msg)) { + ret = send_data(&ctx->fifo, ctx->sock, + (const char *)msg, sizeof(*msg), 0); + if (ret != 0) { ret = -EMSGSIZE; LOG_WRN("Event partial send (%d)", ret); goto out; @@ -562,84 +551,105 @@ static int setup_interface_monitoring(struct supplicant_context *ctx, struct net static void event_socket_handler(int sock, void *eloop_ctx, void *user_data) { struct supplicant_context *ctx = user_data; - struct wpa_supplicant_event_msg msg; - int ret; + struct wpa_supplicant_event_msg event_msg; + struct zephyr_msg *msg; + zvfs_eventfd_t value; ARG_UNUSED(eloop_ctx); - ARG_UNUSED(ctx); - ret = zsock_recv(sock, &msg, sizeof(msg), 0); - if (ret < 0) { - LOG_ERR("Failed to recv the message (%d)", -errno); - return; - } + do { + zvfs_eventfd_read(sock, &value); - if (ret != sizeof(msg)) { - LOG_ERR("Received incomplete message: got: %d, expected:%d", - ret, sizeof(msg)); - return; - } + msg = k_fifo_get(&ctx->fifo, K_NO_WAIT); + if (msg == NULL) { + LOG_ERR("fifo(event): %s", "empty"); + return; + } - LOG_DBG("Passing message %d to wpa_supplicant", msg.event); + if (msg->data == NULL) { + LOG_ERR("fifo(event): %s", "no data"); + goto out; + } - if (msg.global) { - wpa_supplicant_event_global(msg.ctx, msg.event, msg.data); + if (msg->len != sizeof(event_msg)) { + LOG_ERR("Received incomplete message: got: %d, expected:%d", + msg->len, sizeof(event_msg)); + goto out; + } + + memcpy(&event_msg, msg->data, sizeof(event_msg)); + + LOG_DBG("Passing message %d to wpa_supplicant", event_msg.event); + + if (event_msg.global) { + wpa_supplicant_event_global(event_msg.ctx, event_msg.event, + event_msg.data); #ifdef CONFIG_WIFI_NM_HOSTAPD_AP - } else if (msg.hostapd) { - hostapd_event(msg.ctx, msg.event, msg.data); + } else if (event_msg.hostapd) { + hostapd_event(event_msg.ctx, event_msg.event, event_msg.data); #endif - } else { - wpa_supplicant_event(msg.ctx, msg.event, msg.data); - } - - if (msg.data) { - union wpa_event_data *data = msg.data; - - /* Free up deep copied data */ - if (msg.event == EVENT_AUTH) { - os_free((char *)data->auth.ies); - } else if (msg.event == EVENT_RX_MGMT) { - os_free((char *)data->rx_mgmt.frame); - } else if (msg.event == EVENT_TX_STATUS) { - os_free((char *)data->tx_status.data); - } else if (msg.event == EVENT_ASSOC) { - os_free((char *)data->assoc_info.addr); - os_free((char *)data->assoc_info.req_ies); - os_free((char *)data->assoc_info.resp_ies); - os_free((char *)data->assoc_info.resp_frame); - } else if (msg.event == EVENT_ASSOC_REJECT) { - os_free((char *)data->assoc_reject.bssid); - os_free((char *)data->assoc_reject.resp_ies); - } else if (msg.event == EVENT_DEAUTH) { - os_free((char *)data->deauth_info.addr); - os_free((char *)data->deauth_info.ie); - } else if (msg.event == EVENT_DISASSOC) { - os_free((char *)data->disassoc_info.addr); - os_free((char *)data->disassoc_info.ie); - } else if (msg.event == EVENT_UNPROT_DEAUTH) { - os_free((char *)data->unprot_deauth.sa); - os_free((char *)data->unprot_deauth.da); - } else if (msg.event == EVENT_UNPROT_DISASSOC) { - os_free((char *)data->unprot_disassoc.sa); - os_free((char *)data->unprot_disassoc.da); + } else { + wpa_supplicant_event(event_msg.ctx, event_msg.event, event_msg.data); } - os_free(msg.data); - } + if (event_msg.data) { + union wpa_event_data *data = event_msg.data; + + /* Free up deep copied data */ + if (event_msg.event == EVENT_AUTH) { + os_free((char *)data->auth.ies); + } else if (event_msg.event == EVENT_RX_MGMT) { + os_free((char *)data->rx_mgmt.frame); + } else if (event_msg.event == EVENT_TX_STATUS) { + os_free((char *)data->tx_status.data); + } else if (event_msg.event == EVENT_ASSOC) { + os_free((char *)data->assoc_info.addr); + os_free((char *)data->assoc_info.req_ies); + os_free((char *)data->assoc_info.resp_ies); + os_free((char *)data->assoc_info.resp_frame); + } else if (event_msg.event == EVENT_ASSOC_REJECT) { + os_free((char *)data->assoc_reject.bssid); + os_free((char *)data->assoc_reject.resp_ies); + } else if (event_msg.event == EVENT_DEAUTH) { + os_free((char *)data->deauth_info.addr); + os_free((char *)data->deauth_info.ie); + } else if (event_msg.event == EVENT_DISASSOC) { + os_free((char *)data->disassoc_info.addr); + os_free((char *)data->disassoc_info.ie); + } else if (event_msg.event == EVENT_UNPROT_DEAUTH) { + os_free((char *)data->unprot_deauth.sa); + os_free((char *)data->unprot_deauth.da); + } else if (event_msg.event == EVENT_UNPROT_DISASSOC) { + os_free((char *)data->unprot_disassoc.sa); + os_free((char *)data->unprot_disassoc.da); + } + + os_free(event_msg.data); + } + +out: + os_free(msg->data); + os_free(msg); + + } while (!k_fifo_is_empty(&ctx->fifo)); } static int register_supplicant_event_socket(struct supplicant_context *ctx) { int ret; - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, ctx->event_socketpair); + ret = zvfs_eventfd(0, ZVFS_EFD_NONBLOCK); if (ret < 0) { ret = -errno; LOG_ERR("Failed to initialize socket (%d)", ret); return ret; } - eloop_register_read_sock(ctx->event_socketpair[0], event_socket_handler, NULL, ctx); + ctx->sock = ret; + + k_fifo_init(&ctx->fifo); + + eloop_register_read_sock(ctx->sock, event_socket_handler, NULL, ctx); return 0; } @@ -707,7 +717,7 @@ static void handler(void) supplicant_generate_state_event(ctx->if_name, NET_EVENT_SUPPLICANT_CMD_NOT_READY, 0); - eloop_unregister_read_sock(ctx->event_socketpair[0]); + eloop_unregister_read_sock(ctx->sock); zephyr_global_wpa_ctrl_deinit(); @@ -716,8 +726,7 @@ static void handler(void) out: wpa_supplicant_deinit(ctx->supplicant); - zsock_close(ctx->event_socketpair[0]); - zsock_close(ctx->event_socketpair[1]); + close(ctx->sock); err: os_free(params.pid_file); diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 6662582aed88d..791fc464d38e1 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -350,7 +350,6 @@ if NET_SOCKETPAIR config NET_SOCKETPAIR_BUFFER_SIZE int "Size of the intermediate buffer, in bytes" - default 1024 if WIFI_NM_WPA_SUPPLICANT default 64 range 1 4096 help @@ -372,8 +371,6 @@ if NET_SOCKETPAIR_STATIC config NET_SOCKETPAIR_MAX int "How many socketpairs to pre-allocate" - default 6 if WIFI_NM_HOSTAPD_AP - default 4 if WIFI_NM_WPA_SUPPLICANT default 1 endif # NET_SOCKETPAIR_STATIC @@ -382,8 +379,6 @@ if NET_SOCKETPAIR_HEAP config HEAP_MEM_POOL_ADD_SIZE_SOCKETPAIR int - default 9136 if WIFI_NM_HOSTAPD_AP - default 6852 if WIFI_NM_WPA_SUPPLICANT default 296 endif # NET_SOCKETPAIR_HEAP diff --git a/west.yml b/west.yml index dba3ebbe9f3c2..5f7d6eef4e66c 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: cf270006050cf944af699301c7f4de2b427cd862 + revision: bc5d22f5838d017b889d1452a5854f9a32895414 - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3