From: Ilan Peer <ilan.peer@xxxxxxxxx> Integrate the NAN module with the wpa_supplicant. - Introduce a new NAN device interface that can be used for NAN management flows. Support creating this interface dynamically. - Support setting NAN configuration, and support starting/stopping NAN Device operation. Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx> --- wpa_supplicant/Android.mk | 6 ++ wpa_supplicant/Makefile | 6 ++ wpa_supplicant/ctrl_iface.c | 3 + wpa_supplicant/defconfig | 3 + wpa_supplicant/driver_i.h | 19 +++++ wpa_supplicant/events.c | 9 ++- wpa_supplicant/nan_supplicant.c | 111 ++++++++++++++++++++++++++++++ wpa_supplicant/nan_supplicant.h | 45 ++++++++++++ wpa_supplicant/wpa_cli.c | 18 +++++ wpa_supplicant/wpa_supplicant.c | 19 +++-- wpa_supplicant/wpa_supplicant_i.h | 11 +++ 11 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 wpa_supplicant/nan_supplicant.c create mode 100644 wpa_supplicant/nan_supplicant.h diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index cb07e73643..3b755459d4 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -283,6 +283,12 @@ L_CFLAGS += -DCONFIG_DPP3 endif endif +ifdef CONFIG_NAN +OBJS += nan_supplicant.o +OBJS += src/nan/nan.o +CFLAGS += -DCONFIG_NAN +endif + ifdef CONFIG_NAN_USD OBJS += src/common/nan_de.c OBJS += nan_usd.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index fd7d7a0bd0..4e753f4ed6 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -317,6 +317,12 @@ CFLAGS += -DCONFIG_DPP3 endif endif +ifdef CONFIG_NAN +OBJS += nan_supplicant.o +OBJS += ../src/nan/nan.o +CFLAGS += -DCONFIG_NAN +endif + ifdef CONFIG_NAN_USD OBJS += ../src/common/nan_de.o OBJS += nan_usd.o diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 229595d36c..72510f0f9a 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -14137,6 +14137,9 @@ static int wpa_supplicant_global_iface_add(struct wpa_global *global, type = WPA_IF_STATION; } else if (os_strcmp(pos, "ap") == 0) { type = WPA_IF_AP_BSS; + } else if (os_strcmp(pos, "nan") == 0) { + type = WPA_IF_NAN; + iface.nan_mgmt = 1; } else { wpa_printf(MSG_DEBUG, "INTERFACE_ADD unsupported interface type: '%s'", diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index 52befd8f15..6bbd8c4b65 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -686,3 +686,6 @@ CONFIG_DPP2=y # Wi-Fi Aware unsynchronized service discovery (NAN USD) #CONFIG_NAN_USD=y + +# Wi-Fi Aware (NAN) support +#CONFIG_NAN=y diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index ccebd2cbed..4b253e7c9b 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -1267,4 +1267,23 @@ wpas_drv_nan_cancel_subscribe(struct wpa_supplicant *wpa_s, int subscribe_id) subscribe_id); } +#ifdef CONFIG_NAN + +static inline int wpa_drv_nan_start(struct wpa_supplicant *wpa_s, + struct nan_cluster_config *conf) +{ + if (!wpa_s->driver->nan_start) + return -1; + return wpa_s->driver->nan_start(wpa_s->drv_priv, conf); +} + +static inline void wpa_drv_nan_stop(struct wpa_supplicant *wpa_s) +{ + if (!wpa_s->driver->nan_stop) + return; + wpa_s->driver->nan_stop(wpa_s->drv_priv); +} + +#endif /* CONFIG_NAN */ + #endif /* DRIVER_I_H */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index d388f31ff5..d31b3d53bc 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -53,6 +53,7 @@ #include "wmm_ac.h" #include "nan_usd.h" #include "dpp_supplicant.h" +#include "nan_supplicant.h" #define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5 @@ -6917,7 +6918,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, else wpa_sm_pmksa_cache_reconfig(wpa_s->wpa); wpa_supplicant_set_default_scan_ies(wpa_s); - if (wpa_s->p2p_mgmt) { + if (wpa_s->p2p_mgmt || wpa_s->nan_mgmt) { wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); break; @@ -6940,6 +6941,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; case EVENT_INTERFACE_DISABLED: wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled"); + if (wpa_s->nan_mgmt) { + wpas_nan_flush(wpa_s); + wpa_supplicant_set_state(wpa_s, + WPA_INTERFACE_DISABLED); + break; + } #ifdef CONFIG_P2P if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO || (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group && diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c new file mode 100644 index 0000000000..612f387adf --- /dev/null +++ b/wpa_supplicant/nan_supplicant.c @@ -0,0 +1,111 @@ +/* + * wpa_supplicant - NAN + * Copyright (C) 2025 Intel Corporation + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "nan/nan.h" +#include "config.h" + +#define DEFAULT_NAN_MASTER_PREF 2 +#define DEFAULT_NAN_DUAL_BAND 0 + + +static int wpas_nan_start_cb(void *ctx, struct nan_cluster_config *config) +{ + struct wpa_supplicant *wpa_s = ctx; + + return wpa_drv_nan_start(wpa_s, config); +} + + +static void wpas_nan_stop_cb(void *ctx) +{ + struct wpa_supplicant *wpa_s = ctx; + + wpa_drv_nan_stop(wpa_s); +} + + +int wpas_nan_init(struct wpa_supplicant *wpa_s) +{ + struct nan_config nan; + + if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SUPPORT_NAN)) { + wpa_printf(MSG_DEBUG, "NAN: NAN is not supported"); + return -1; + } + + os_memset(&nan, 0, sizeof(nan)); + nan.cb_ctx = wpa_s; + + nan.start = wpas_nan_start_cb; + nan.stop = wpas_nan_stop_cb; + + wpa_s->nan = nan_init(&nan); + if (!wpa_s->nan) { + wpa_printf(MSG_DEBUG, "NAN: Failed to init"); + return -1; + } + + return 0; +} + + +void wpas_nan_deinit(struct wpa_supplicant *wpa_s) +{ + if (!wpa_s || !wpa_s->nan) + return; + + nan_deinit(wpa_s->nan); + wpa_s->nan = NULL; +} + + +static int wpas_nan_ready(struct wpa_supplicant *wpa_s) +{ + return wpa_s->nan_mgmt && wpa_s->nan && + wpa_s->wpa_state != WPA_INTERFACE_DISABLED; +} + + +/* Join a cluster using current configuration */ +int wpas_nan_start(struct wpa_supplicant *wpa_s) +{ + struct nan_cluster_config cluster_config; + + if (!wpas_nan_ready(wpa_s)) + return -1; + + cluster_config.master_pref = DEFAULT_NAN_MASTER_PREF; + cluster_config.dual_band = DEFAULT_NAN_DUAL_BAND; + + return nan_start(wpa_s->nan, &cluster_config); +} + + +int wpas_nan_stop(struct wpa_supplicant *wpa_s) +{ + if (!wpas_nan_ready(wpa_s)) + return -1; + + nan_stop(wpa_s->nan); + + return 0; +} + + +void wpas_nan_flush(struct wpa_supplicant *wpa_s) +{ + if (!wpas_nan_ready(wpa_s)) + return; + + nan_flush(wpa_s->nan); +} diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h new file mode 100644 index 0000000000..615c6f64aa --- /dev/null +++ b/wpa_supplicant/nan_supplicant.h @@ -0,0 +1,45 @@ +/* + * wpa_supplicant - NAN + * Copyright (C) 2025 Intel Corporation + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef NAN_SUPPLICANT_H +#define NAN_SUPPLICANT_H + +#ifdef CONFIG_NAN + +int wpas_nan_init(struct wpa_supplicant *wpa_s); +void wpas_nan_deinit(struct wpa_supplicant *wpa_s); +int wpas_nan_start(struct wpa_supplicant *wpa_s); +int wpas_nan_stop(struct wpa_supplicant *wpa_s); +void wpas_nan_flush(struct wpa_supplicant *wpa_s); + +#else /* CONFIG_NAN */ + +static inline int wpas_nan_init(struct wpa_supplicant *wpa_s) +{ + return -1; +} + +static inline void wpas_nan_deinit(struct wpa_supplicant *wpa_s) +{} + +static inline int wpas_nan_start(struct wpa_supplicant *wpa_s) +{ + return -1; +} + +static inline int wpas_nan_stop(struct wpa_supplicant *wpa_s) +{ + return -1; +} + +static inline void wpas_nan_flush(struct wpa_supplicant *wpa_s) +{} + +#endif /* CONFIG_NAN */ + +#endif /* NAN_SUPPLICANT_H */ diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index b13bf49924..031460ae89 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -3364,6 +3364,24 @@ static int wpa_cli_cmd_nan_flush(struct wpa_ctrl *ctrl, int argc, #endif /* CONFIG_NAN_USD */ +#ifdef CONFIG_NAN + +static int wpa_cli_cmd_nan_start(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "NAN_START", 0, argc, argv); +} + + +static int wpa_cli_cmd_nan_stop(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "NAN_STOP", 0, argc, argv); +} + +#endif /* CONFIG_NAN */ + + enum wpa_cli_cmd_flags { cli_cmd_flag_none = 0x00, cli_cmd_flag_sensitive = 0x01 diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 0586c371ae..d3b7361f37 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -66,6 +66,7 @@ #include "mesh.h" #include "dpp_supplicant.h" #include "nan_usd.h" +#include "nan_supplicant.h" #ifdef CONFIG_MESH #include "ap/ap_config.h" #include "ap/hostapd.h" @@ -6174,7 +6175,8 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) if ((!wpa_s->p2p_mgmt || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) && - !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) { + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) && + !wpa_s->nan_mgmt) { l2_packet_deinit(wpa_s->l2); wpa_s->l2 = l2_packet_init(wpa_s->ifname, wpa_drv_get_mac_addr(wpa_s), @@ -7860,6 +7862,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) wpa_s->p2p_mgmt = iface->p2p_mgmt; + wpa_s->nan_mgmt = iface->nan_mgmt; + if (wpa_s->num_multichan_concurrent == 0) wpa_s->num_multichan_concurrent = 1; @@ -7867,7 +7871,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, return -1; #ifdef CONFIG_TDLS - if (!iface->p2p_mgmt && wpa_tdls_init(wpa_s->wpa)) + if (!iface->p2p_mgmt && !iface->nan_mgmt && wpa_tdls_init(wpa_s->wpa)) return -1; #endif /* CONFIG_TDLS */ @@ -8014,6 +8018,11 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, wpa_supplicant_set_default_scan_ies(wpa_s); + if (wpa_s->nan_mgmt && wpas_nan_init(wpa_s) < 0) { + wpa_msg(wpa_s, MSG_ERROR, "Failed to init NAN"); + return -1; + } + return 0; } @@ -8065,6 +8074,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, wpa_supplicant_cleanup(wpa_s); wpas_p2p_deinit_iface(wpa_s); + wpas_nan_deinit(wpa_s); + wpas_ctrl_radio_work_flush(wpa_s); radio_remove_interface(wpa_s); @@ -8232,7 +8243,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, return NULL; } - if (iface->p2p_mgmt == 0) { + if (iface->p2p_mgmt == 0 && iface->nan_mgmt == 0) { /* Notify the control interfaces about new iface */ if (wpas_notify_iface_added(wpa_s)) { wpa_supplicant_deinit_iface(wpa_s, 1, 0); @@ -8250,7 +8261,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); #ifdef CONFIG_P2P - if (wpa_s->global->p2p == NULL && + if (!wpa_s->global->p2p && !iface->nan_mgmt && !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) && wpas_p2p_add_p2pdev_interface( diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 2f77413d57..a53bda9431 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -135,6 +135,11 @@ struct wpa_interface { WPA_IFACE_MATCHED } matched; #endif /* CONFIG_MATCH_IFACE */ + + /** + * nan_mgmt - Interface used for NAN management (NAN Device operations) + */ + bool nan_mgmt; }; /** @@ -1631,6 +1636,12 @@ struct wpa_supplicant { unsigned int next_beacon_check; bool scs_reconfigure; + + bool nan_mgmt; + +#ifdef CONFIG_NAN + struct nan_data *nan; +#endif }; -- 2.49.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap