diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 772aac1105c604..d19eff6148bd4e 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -123,6 +123,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_NEIGHBOR_REP_COMPLETE, /** Specific scan */ NET_REQUEST_WIFI_CMD_CANDIDATE_SCAN, + /** AP WPS config */ + NET_REQUEST_WIFI_CMD_AP_WPS_CONFIG, /** @cond INTERNAL_HIDDEN */ NET_REQUEST_WIFI_CMD_MAX /** @endcond */ diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index 56298b5bcd152a..d15546276da8da 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -224,8 +224,8 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_AP CONFIG_NO_ACCOUNTING NEED_AP_MLME CONFIG_IEEE80211AC - CONFIG_EAP_SERVER - CONFIG_EAP_SERVER_IDENTITY + EAP_SERVER + EAP_SERVER_IDENTITY ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX @@ -365,6 +365,14 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS EAP_WSC ) +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_HOSTAPD_WPS + ${HOSTAP_SRC_BASE}/eap_server/eap_server_wsc.c +) + +zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_HOSTAPD_WPS + EAP_SERVER_WSC +) + zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE ${HOSTAP_SRC_BASE}/eap_common/eap_common.c ) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 4f0fccecbd6d51..fb961f93d1ca1f 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -243,6 +243,11 @@ config WIFI_NM_WPA_SUPPLICANT_WPS bool "WPS support" depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE +config WIFI_NM_HOSTAPD_WPS + bool "WPS hostapd support" + depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE + depends on WIFI_NM_HOSTAPD_AP + config WIFI_NM_WPA_SUPPLICANT_P2P bool "P2P mode support" select WIFI_NM_WPA_SUPPLICANT_AP diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index e8209b8cd089ea..52c51345b8f106 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -2086,6 +2086,106 @@ int supplicant_ap_status(const struct device *dev, struct wifi_iface_status *sta } #endif /* CONFIG_WIFI_NM_HOSTAPD_AP */ +#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS +int supplicant_ap_wps_pbc(const struct device *dev) +{ + struct hostapd_iface *iface; + int ret = -1; + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + ret = -1; + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + goto out; + } + + if (iface->state != HAPD_IFACE_ENABLED) { + ret = -EBUSY; + wpa_printf(MSG_ERROR, "Interface %s is not in enable state", dev->name); + goto out; + } + + if (!hostapd_cli_cmd_v("wps_pbc")) { + goto out; + } + + wpas_api_ctrl.dev = dev; + wpas_api_ctrl.requested_op = WPS_PBC; + + ret = 0; + +out: + k_mutex_unlock(&wpa_supplicant_mutex); + + return ret; +} + +int supplicant_ap_wps_pin(const struct device *dev, struct wifi_wps_config_params *params) +{ + struct hostapd_iface *iface; + char *get_pin_cmd = "WPS_AP_PIN random"; + int ret = 0; + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + ret = -1; + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + goto out; + } + + if (iface->state != HAPD_IFACE_ENABLED) { + ret = -EBUSY; + wpa_printf(MSG_ERROR, "Interface %s is not in enable state", dev->name); + goto out; + } + + if (params->oper == WIFI_WPS_PIN_GET) { + if (zephyr_hostapd_cli_cmd_resp(get_pin_cmd, params->pin)) { + goto out; + } + } else if (params->oper == WIFI_WPS_PIN_SET) { + if (!hostapd_cli_cmd_v("wps_check_pin %s", params->pin)) { + goto out; + } + + if (!hostapd_cli_cmd_v("wps_pin any %s", params->pin)) { + goto out; + } + + wpas_api_ctrl.dev = dev; + wpas_api_ctrl.requested_op = WPS_PIN; + } else { + wpa_printf(MSG_ERROR, "Error wps pin operation : %d", params->oper); + goto out; + } + + ret = 0; + +out: + k_mutex_unlock(&wpa_supplicant_mutex); + + return ret; +} + + +int supplicant_ap_wps_config(const struct device *dev, struct wifi_wps_config_params *params) +{ + int ret = 0; + + if (params->oper == WIFI_WPS_PBC) { + ret = supplicant_ap_wps_pbc(dev); + } else if (params->oper == WIFI_WPS_PIN_GET || params->oper == WIFI_WPS_PIN_SET) { + ret = supplicant_ap_wps_pin(dev, params); + } + + return ret; +} +#endif + int supplicant_ap_enable(const struct device *dev, struct wifi_connect_req_params *params) { diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index 46a1381a28dd4b..b9ea808be0ae51 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -287,6 +287,17 @@ static inline int hapd_state(const struct device *dev, int *state) } #endif +#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS +/** Start AP WPS PBC/PIN + * + * @param dev Pointer to the device structure for the driver instance + * @param params wps operarion parameters + * + * @return 0 if ok, < 0 if error + */ +int supplicant_ap_wps_config(const struct device *dev, struct wifi_wps_config_params *params); +#endif + /** * @brief Get Wi-Fi SAP status * diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 7840525c3b9158..0e21f5aa81b9cf 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -104,6 +104,9 @@ static const struct wifi_mgmt_ops mgmt_ap_ops = { .ap_disable = supplicant_ap_disable, .ap_sta_disconnect = supplicant_ap_sta_disconnect, .iface_status = supplicant_ap_status, +#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS + .wps_config = supplicant_ap_wps_config, +#endif #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP .dpp_dispatch = hapd_dpp_dispatch, #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ diff --git a/samples/net/wifi/boards/frdm_rw612.conf b/samples/net/wifi/boards/frdm_rw612.conf index 87de6bc8dbdeee..06f43c23f4413a 100644 --- a/samples/net/wifi/boards/frdm_rw612.conf +++ b/samples/net/wifi/boards/frdm_rw612.conf @@ -90,6 +90,7 @@ CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES=2 CONFIG_SAE_PWE_EARLY_EXIT=y CONFIG_WIFI_NM_HOSTAPD_AP=y CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS=y +CONFIG_WIFI_NM_HOSTAPD_WPS=y CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING=y CONFIG_WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING=y diff --git a/samples/net/wifi/boards/rd_rw612_bga.conf b/samples/net/wifi/boards/rd_rw612_bga.conf index 633137e3fb02d3..54070b24a8ec83 100644 --- a/samples/net/wifi/boards/rd_rw612_bga.conf +++ b/samples/net/wifi/boards/rd_rw612_bga.conf @@ -89,6 +89,7 @@ CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES=2 CONFIG_SAE_PWE_EARLY_EXIT=y CONFIG_WIFI_NM_HOSTAPD_AP=y CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS=y +CONFIG_WIFI_NM_HOSTAPD_WPS=y CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING=y CONFIG_WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING=y diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 77b2debe3550e4..380bacfbe83469 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1975,7 +1975,7 @@ static int cmd_wifi_btm_query(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_wps_pbc(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_first_wifi(); + struct net_if *iface = net_if_get_wifi_sta(); struct wifi_wps_config_params params = {0}; context.sh = sh; @@ -1997,7 +1997,7 @@ static int cmd_wifi_wps_pbc(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_wps_pin(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_first_wifi(); + struct net_if *iface = net_if_get_wifi_sta(); struct wifi_wps_config_params params = {0}; context.sh = sh; @@ -2024,6 +2024,57 @@ static int cmd_wifi_wps_pin(const struct shell *sh, size_t argc, char *argv[]) return 0; } +static int cmd_wifi_ap_wps_pbc(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_wifi_sap(); + struct wifi_wps_config_params params = {0}; + + context.sh = sh; + + if (argc == 1) { + params.oper = WIFI_WPS_PBC; + } else { + shell_help(sh); + return -ENOEXEC; + } + + if (net_mgmt(NET_REQUEST_WIFI_WPS_CONFIG, iface, ¶ms, sizeof(params))) { + PR_WARNING("Start AP WPS PBC failed\n"); + return -ENOEXEC; + } + + return 0; +} + +static int cmd_wifi_ap_wps_pin(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_wifi_sap(); + struct wifi_wps_config_params params = {0}; + + context.sh = sh; + + if (argc == 1) { + params.oper = WIFI_WPS_PIN_GET; + } else if (argc == 2) { + params.oper = WIFI_WPS_PIN_SET; + strncpy(params.pin, argv[1], WIFI_WPS_PIN_MAX_LEN); + } else { + shell_help(sh); + return -ENOEXEC; + } + + if (net_mgmt(NET_REQUEST_WIFI_WPS_CONFIG, iface, ¶ms, sizeof(params))) { + PR_WARNING("Start AP WPS PIN failed\n"); + return -ENOEXEC; + } + + if (params.oper == WIFI_WPS_PIN_GET) { + PR("WPS PIN is: %s\n", params.pin); + } + + return 0; +} + static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); @@ -3055,6 +3106,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE( "-s --max_num_sta=\n" "-h --help (prints help)", cmd_wifi_ap_config_params, 2, 5), + SHELL_CMD_ARG(wps_pbc, NULL, + "Start AP WPS PBC session.\n", + cmd_wifi_ap_wps_pbc, 1, 0), + SHELL_CMD_ARG(wps_pin, NULL, + "Get or Set AP WPS PIN.\n" + "[pin] Only applicable for set.\n", + cmd_wifi_ap_wps_pin, 1, 1), SHELL_CMD_ARG(status, NULL, "Status of Wi-Fi SAP\n", cmd_wifi_ap_status, 1, 0), SHELL_SUBCMD_SET_END);