diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 8f54750c4984a..704c8976092b3 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -735,6 +735,12 @@ enum wifi_ap_config_param { WIFI_AP_CONFIG_PARAM_VHT_CAPAB = BIT(4), }; +/** @brief Wi-Fi STA mode configuration parameter */ +enum wifi_config_param { + /** Used for STA mode configuration parameter OKC */ + WIFI_CONFIG_PARAM_OKC = BIT(0), +}; + /** Helper function to get user-friendly status name for the status code. */ const char *wifi_conn_status_txt(enum wifi_conn_status status); diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 40dd023839a7d..1e590a2ec79e2 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -109,6 +109,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_RTS_THRESHOLD, /** Configure AP parameter */ NET_REQUEST_WIFI_CMD_AP_CONFIG_PARAM, + /** Configure STA parameter */ + NET_REQUEST_WIFI_CMD_CONFIG_PARAM, /** DPP actions */ NET_REQUEST_WIFI_CMD_DPP, /** BSS transition management query */ @@ -267,6 +269,12 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM); +/** Request a Wi-Fi STA parameters configuration */ +#define NET_REQUEST_WIFI_CONFIG_PARAM \ + (NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_CONFIG_PARAM) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CONFIG_PARAM); + #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP /** Request a Wi-Fi DPP operation */ #define NET_REQUEST_WIFI_DPP \ @@ -1054,6 +1062,14 @@ struct wifi_ap_config_params { #endif }; +/** @brief Wi-Fi STA configuration parameter */ +struct wifi_config_params { + /** Parameter used to identify the different STA parameters */ + enum wifi_config_param type; + /** Parameter used for opportunistic key caching */ + int okc; +}; + #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP /** @brief Wi-Fi DPP configuration parameter */ /** Wi-Fi DPP QR-CODE in string max len for SHA512 */ @@ -1538,7 +1554,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*ap_config_params)(const struct device *dev, struct wifi_ap_config_params *params); - + /** Configure STA parameter + * + * @param dev Pointer to the device structure for the driver instance. + * @param params STA mode parameter configuration parameter info + * + * @return 0 if ok, < 0 if error + */ + int (*config_params)(const struct device *dev, struct wifi_config_params *params); #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP /** Dispatch DPP operations by action enum, with or without arguments in string format * diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index d39986b571cd0..8a57dceb425fd 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -2336,3 +2336,31 @@ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *pa return 0; } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ + +int supplicant_config_params(const struct device *dev, struct wifi_config_params *params) +{ + struct wpa_supplicant *wpa_s; + int ret = 0; + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + + wpa_s = get_wpa_s_handle(dev); + if (!wpa_s) { + ret = -ENOENT; + wpa_printf(MSG_ERROR, "Device %s not found", dev->name); + goto out; + } + + if (params->type & WIFI_CONFIG_PARAM_OKC) { + if (!wpa_cli_cmd_v("set okc %d", params->okc)) { + ret = -EINVAL; + wpa_printf(MSG_ERROR, "Failed to set OKC"); + goto out; + } + wpa_printf(MSG_INFO, "Set OKC: %d", params->okc); + } + +out: + k_mutex_unlock(&wpa_supplicant_mutex); + return ret; +} diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index ddd3c3d66988b..e602072e2f89f 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -350,4 +350,13 @@ int dpp_params_to_cmd(struct wifi_dpp_params *params, char *cmd, size_t max_len) */ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *params); #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ + +/** + * @brief Wi-Fi STA configuration parameter. + * + * @param dev Wi-Fi interface handle to use + * @param params STA parameters + * @return 0 for OK; -1 for ERROR + */ +int supplicant_config_params(const struct device *dev, struct wifi_config_params *params); #endif /* ZEPHYR_SUPP_MGMT_H */ diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 4549ab3160d2c..e33dcb2347b5f 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -95,6 +95,7 @@ static const struct wifi_mgmt_ops mgmt_ops = { #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE .enterprise_creds = supplicant_add_enterprise_creds, #endif + .config_params = supplicant_config_params, }; DEFINE_WIFI_NM_INSTANCE(wifi_supplicant, &mgmt_ops); diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 0183faab1d506..a432524cd09e9 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -1357,6 +1357,35 @@ static int wifi_pmksa_flush(uint64_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PMKSA_FLUSH, wifi_pmksa_flush); +static int wifi_config_params(uint64_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_config_params *params = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || + wifi_mgmt_api->config_params == NULL) { + return -ENOTSUP; + } + + if (!net_if_is_admin_up(iface)) { + return -ENETDOWN; + } + + if (!data || len != sizeof(*params)) { + return -EINVAL; + } + + return wifi_mgmt_api->config_params(dev, params); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONFIG_PARAM, wifi_config_params); + static int wifi_get_rts_threshold(uint64_t mgmt_request, struct net_if *iface, void *data, size_t len) { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a62d8e0eb8243..11a3fa56aaf04 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -3809,6 +3809,66 @@ static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[ return 0; } + +static int wifi_config_args_to_params(const struct shell *sh, size_t argc, char *argv[], + struct wifi_config_params *params) +{ + int opt; + int opt_index = 0; + struct getopt_state *state; + static const struct option long_options[] = { + {"okc", required_argument, 0, 'o'}, + {"iface", required_argument, 0, 'i'}, + {0, 0, 0, 0}}; + long val; + + while ((opt = getopt_long(argc, argv, "o:i:", + long_options, &opt_index)) != -1) { + state = getopt_state_get(); + switch (opt) { + case 'o': + if (!parse_number(sh, &val, state->optarg, "okc", 0, 1)) { + return -EINVAL; + } + params->okc = val; + params->type |= WIFI_CONFIG_PARAM_OKC; + break; + case 'i': + /* Unused, but parsing to avoid unknown option error */ + break; + default: + PR_ERROR("Invalid option %c\n", state->optopt); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + + return 0; +} + +static int cmd_wifi_config_params(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_config_params config_params = { 0 }; + int ret = -1; + + context.sh = sh; + + if (wifi_config_args_to_params(sh, argc, argv, &config_params)) { + return -ENOEXEC; + } + + ret = net_mgmt(NET_REQUEST_WIFI_CONFIG_PARAM, iface, + &config_params, sizeof(struct wifi_config_params)); + if (ret) { + PR_WARNING("Setting STA parameter failed: %s\n", + strerror(-ret)); + return -ENOEXEC; + } + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE( wifi_cmd_ap, SHELL_CMD_ARG(disable, NULL, "Disable Access Point mode.\n" @@ -4287,6 +4347,13 @@ SHELL_SUBCMD_ADD((wifi), ps_exit_strategy, NULL, cmd_wifi_ps_exit_strategy, 2, 2); +SHELL_SUBCMD_ADD((wifi), config, NULL, + "Configure STA parameters.\n" + "-o, --okc=<0/1>: Opportunistic Key Caching. 0: disable, 1: enable\n" + "[-i, --iface=] : Interface index.\n", + cmd_wifi_config_params, + 3, 12); + SHELL_CMD_REGISTER(wifi, &wifi_commands, "Wi-Fi commands", NULL); static int wifi_shell_init(void)