From 90847787570d9395ae2a5c946644d791eecc5f5f Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Tue, 28 May 2024 14:52:15 +0530 Subject: [PATCH 1/7] [nrf fromtree] net: wifi: shell: Support to print name Support to print name of the argument along with the value. Signed-off-by: Ajay Parida (cherry picked from commit 180c22a4fcbae1d2f640200d3a11bb36e132998a) --- subsys/net/l2/wifi/wifi_shell.c | 47 +++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ab2637a1271..7bdd9801650 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -75,7 +75,8 @@ struct wifi_ap_sta_node { }; static struct wifi_ap_sta_node sta_list[CONFIG_WIFI_SHELL_MAX_AP_STA]; -static bool parse_number(const struct shell *sh, long *param, char *str, long min, long max) +static bool parse_number(const struct shell *sh, long *param, char *str, + char *pname, long min, long max) { char *endptr; char *str_tmp = str; @@ -94,7 +95,13 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi } if ((num) < (min) || (num) > (max)) { - PR_WARNING("Value out of range: %s, (%ld-%ld)", str_tmp, min, max); + if (pname) { + PR_WARNING("%s value out of range: %s, (%ld-%ld)", + pname, str_tmp, min, max); + } else { + PR_WARNING("Value out of range: %s, (%ld-%ld)", + str_tmp, min, max); + } return false; } *param = num; @@ -1067,12 +1074,12 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.setup.trigger = 0; params.setup.announce = 0; - if (!parse_number(sh, &value, argv[idx++], 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { return -EINVAL; } params.setup.twt_wake_interval = (uint32_t)value; - if (!parse_number(sh, &value, argv[idx++], 1, WIFI_MAX_TWT_INTERVAL_US)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { return -EINVAL; } params.setup.twt_interval = (uint64_t)value; @@ -1105,59 +1112,59 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, params.operation = WIFI_TWT_SETUP; - if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_INDIVIDUAL, + if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_INDIVIDUAL, WIFI_TWT_WAKE_TBTT)) { return -EINVAL; } params.negotiation_type = (enum wifi_twt_negotiation_type)value; - if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, + if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND)) { return -EINVAL; } params.setup_cmd = (enum wifi_twt_setup_cmd)value; - if (!parse_number(sh, &value, argv[idx++], 1, 255)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, 255)) { return -EINVAL; } params.dialog_token = (uint8_t)value; - if (!parse_number(sh, &value, argv[idx++], 0, (WIFI_MAX_TWT_FLOWS - 1))) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, (WIFI_MAX_TWT_FLOWS - 1))) { return -EINVAL; } params.flow_id = (uint8_t)value; - if (!parse_number(sh, &value, argv[idx++], 0, 1)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { return -EINVAL; } params.setup.responder = (bool)value; - if (!parse_number(sh, &value, argv[idx++], 0, 1)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { return -EINVAL; } params.setup.trigger = (bool)value; - if (!parse_number(sh, &value, argv[idx++], 0, 1)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { return -EINVAL; } params.setup.implicit = (bool)value; - if (!parse_number(sh, &value, argv[idx++], 0, 1)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { return -EINVAL; } params.setup.announce = (bool)value; - if (!parse_number(sh, &value, argv[idx++], 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { return -EINVAL; } params.setup.twt_wake_interval = (uint32_t)value; - if (!parse_number(sh, &value, argv[idx++], 1, WIFI_MAX_TWT_INTERVAL_US)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { return -EINVAL; } params.setup.twt_interval = (uint64_t)value; - if (!parse_number(sh, &value, argv[idx++], 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { return -EINVAL; } params.setup.twt_wake_ahead_duration = (uint32_t)value; @@ -1190,24 +1197,24 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, params.operation = WIFI_TWT_TEARDOWN; - if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_INDIVIDUAL, + if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_INDIVIDUAL, WIFI_TWT_WAKE_TBTT)) { return -EINVAL; } params.negotiation_type = (enum wifi_twt_negotiation_type)value; - if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, + if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND)) { return -EINVAL; } params.setup_cmd = (enum wifi_twt_setup_cmd)value; - if (!parse_number(sh, &value, argv[idx++], 1, 255)) { + if (!parse_number(sh, &value, argv[idx++], NULL, 1, 255)) { return -EINVAL; } params.dialog_token = (uint8_t)value; - if (!parse_number(sh, &value, argv[idx++], 0, (WIFI_MAX_TWT_FLOWS - 1))) { + if (!parse_number(sh, &value, argv[idx++], NULL, 0, (WIFI_MAX_TWT_FLOWS - 1))) { return -EINVAL; } params.flow_id = (uint8_t)value; @@ -1441,7 +1448,7 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a context.sh = sh; - if (!parse_number(sh, &interval, argv[1], + if (!parse_number(sh, &interval, argv[1], NULL, WIFI_LISTEN_INTERVAL_MIN, WIFI_LISTEN_INTERVAL_MAX)) { return -EINVAL; From 9c8df225eec5a168b4ebd5d03315c932753276f3 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Wed, 8 May 2024 12:50:48 +0530 Subject: [PATCH 2/7] [nrf fromtree] net: wifi_mgmt: Support to configure AP mode parameter Support to set BSS parameter at compile and run time. Added support to configure `max_inactivity` BSS parameter. Station inactivity timeout is the period for which AP may keep a client in associated state while there is no traffic from that particular client. If a non-zero value is set, AP may choose to disassociate the client after the timeout. Signed-off-by: Ajay Parida (cherry picked from commit c6d1a91372082028b3e153a1246fde6f113eda80) --- include/zephyr/net/wifi.h | 6 +++ include/zephyr/net/wifi_mgmt.h | 30 ++++++++++++++- subsys/net/l2/wifi/Kconfig | 9 +++++ subsys/net/l2/wifi/wifi_mgmt.c | 25 +++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 65 +++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 5f47209b83f..ab00980a69c 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -494,6 +494,12 @@ static inline const char *wifi_ps_get_config_err_code_str(int16_t err_no) return ""; } +/** @brief Wi-Fi AP mode configuration parameter */ +enum wifi_ap_config_param { + /** Used for AP mode configuration parameter ap_max_inactivity */ + WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY = BIT(0), +}; + #ifdef __cplusplus } #endif diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8c2b61fa936..910ee030651 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -88,7 +88,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_VERSION, /** Set RTS threshold */ NET_REQUEST_WIFI_CMD_RTS_THRESHOLD, - + /** Configure AP parameter */ + NET_REQUEST_WIFI_CMD_AP_CONFIG_PARAM, /** @cond INTERNAL_HIDDEN */ NET_REQUEST_WIFI_CMD_MAX /** @endcond */ @@ -190,6 +191,12 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD); +/** Request a Wi-Fi AP parameters configuration */ +#define NET_REQUEST_WIFI_AP_CONFIG_PARAM \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_AP_CONFIG_PARAM) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM); + /** @brief Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -746,6 +753,18 @@ struct wifi_channel_info { enum wifi_mgmt_op oper; }; +/** @cond INTERNAL_HIDDEN */ +#define WIFI_AP_STA_MAX_INACTIVITY (LONG_MAX - 1) +/** @endcond */ + +/** @brief Wi-Fi AP configuration parameter */ +struct wifi_ap_config_params { + /** Parameter used to identify the different AP parameters */ + enum wifi_ap_config_param type; + /** Parameter used for setting maximum inactivity duration for stations */ + uint32_t max_inactivity; +}; + #include /** Scan result callback @@ -919,7 +938,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*set_rts_threshold)(const struct device *dev, unsigned int rts_threshold); - + /** Configure AP parameter + * + * @param dev Pointer to the device structure for the driver instance. + * @param params AP mode parameter configuration parameter info + * + * @return 0 if ok, < 0 if error + */ + int (*ap_config_params)(const struct device *dev, struct wifi_ap_config_params *params); }; /** Wi-Fi management offload API */ diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 2816be56d74..0ad0858fab2 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -93,3 +93,12 @@ module-str = Log level for Wi-Fi Network manager module module-help = Enables using the Wi-Fi Network managers to manage the Wi-Fi network interfaces. source "subsys/net/Kconfig.template.log_config.net" endif # WIFI_NM + +config WIFI_MGMT_AP_STA_INACTIVITY_TIMEOUT + int "Station inactivity timeout in seconds" + default 300 + help + Station inactivity timeout is the period for which AP may keep a client + in associated state while there is no traffic from that particular + client. If a non-zero value is set, AP may choose to disassociate the + client after the timeout. diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 51e76aec5fb..b6f4a6cd2c6 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -435,6 +435,31 @@ static int wifi_ap_sta_disconnect(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect); +static int wifi_ap_config_params(uint32_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_ap_config_params *params = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || + wifi_mgmt_api->ap_config_params == NULL) { + return -ENOTSUP; + } + + if (!data || len != sizeof(*params)) { + return -EINVAL; + } + + return wifi_mgmt_api->ap_config_params(dev, params); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM, wifi_ap_config_params); + static int wifi_iface_status(uint32_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 7bdd9801650..87930f7cbaf 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1370,6 +1370,65 @@ static int cmd_wifi_ap_sta_disconnect(const struct shell *sh, size_t argc, return 0; } +static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, char *argv[], + struct wifi_ap_config_params *params) +{ + struct getopt_state *state; + int opt; + static struct option long_options[] = {{"max_inactivity", required_argument, 0, 'i'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; + int opt_index = 0; + long val; + + while ((opt = getopt_long(argc, argv, "i:h", long_options, &opt_index)) != -1) { + state = getopt_state_get(); + switch (opt) { + case 'i': + if (!parse_number(sh, &val, optarg, "max_inactivity", + 0, WIFI_AP_STA_MAX_INACTIVITY)) { + return -EINVAL; + } + params->max_inactivity = (uint32_t)val; + params->type |= WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY; + break; + case 'h': + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + default: + PR_ERROR("Invalid option %c\n", optopt); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + + return 0; +} + +static int cmd_wifi_ap_config_params(const struct shell *sh, size_t argc, + char *argv[]) +{ + struct net_if *iface = net_if_get_first_wifi(); + struct wifi_ap_config_params ap_config_params = { 0 }; + int ret = -1; + + context.sh = sh; + + if (wifi_ap_config_args_to_params(sh, argc, argv, &ap_config_params)) { + return -ENOEXEC; + } + + ret = net_mgmt(NET_REQUEST_WIFI_AP_CONFIG_PARAM, iface, + &ap_config_params, sizeof(struct wifi_ap_config_params)); + if (ret) { + PR_WARNING("Setting AP parameter failed: %s\n", + strerror(-ret)); + return -ENOEXEC; + } + + return 0; +} + static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) { @@ -1893,6 +1952,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, "\n", cmd_wifi_ap_sta_disconnect, 2, 0), + SHELL_CMD_ARG(config, NULL, + "Configure AP parameters.\n" + "-i --max_inactivity=