diff options
Diffstat (limited to 'wpa_supplicant/wpa_cli.c')
-rw-r--r-- | wpa_supplicant/wpa_cli.c | 1682 |
1 files changed, 505 insertions, 1177 deletions
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index bed13dd9..3986b9be 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -95,8 +95,11 @@ static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ -static void print_help(void); +static void print_help(const char *cmd); static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); +static void wpa_cli_close_connection(void); +static char * wpa_cli_get_default_ifname(void); +static char ** wpa_list_cmd_list(void); static void usage(void) @@ -113,7 +116,7 @@ static void usage(void) " -B = run a daemon in the background\n" " default path: " CONFIG_CTRL_IFACE_DIR "\n" " default interface: first interface found in socket path\n"); - print_help(); + print_help(NULL); } @@ -241,7 +244,7 @@ static char ** cli_txt_list_array(struct dl_list *txt_list) char **res; struct cli_txt_entry *e; - res = os_zalloc((count + 1) * sizeof(char *)); + res = os_calloc(count + 1, sizeof(char *)); if (res == NULL) return NULL; @@ -364,6 +367,7 @@ static int wpa_cli_open_connection(const char *ifname, int attach) } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); + wpa_cli_close_connection(); return -1; } } @@ -456,6 +460,58 @@ static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) } +static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc, + char *argv[]) +{ + int i, res; + char *pos, *end; + + pos = buf; + end = buf + buflen; + + res = os_snprintf(pos, end - pos, "%s", cmd); + if (res < 0 || res >= end - pos) + goto fail; + pos += res; + + for (i = 0; i < argc; i++) { + res = os_snprintf(pos, end - pos, " %s", argv[i]); + if (res < 0 || res >= end - pos) + goto fail; + pos += res; + } + + buf[buflen - 1] = '\0'; + return 0; + +fail: + printf("Too long command\n"); + return -1; +} + + +static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, + int argc, char *argv[]) +{ + char buf[256]; + if (argc < min_args) { + printf("Invalid %s command - at least %d argument%s " + "required.\n", cmd, min_args, + min_args > 1 ? "s are" : " is"); + return -1; + } + if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + +static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "IFNAME"); +} + + static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) { if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) @@ -480,14 +536,7 @@ static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int ret; - if (argc == 0) - return -1; - ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]); - if (ret < 0 || (size_t) ret >= sizeof(cmd)) - return -1; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); } @@ -505,11 +554,26 @@ static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - print_help(); + print_help(argc > 0 ? argv[0] : NULL); return 0; } +static char ** wpa_cli_complete_help(const char *str, int pos) +{ + int arg = get_cmd_arg_num(str, pos); + char **res = NULL; + + switch (arg) { + case 1: + res = wpa_list_cmd_list(); + break; + } + + return res; +} + + static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) { printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license); @@ -577,21 +641,7 @@ static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid GET command: need one argument (variable " - "name)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long GET command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); } @@ -617,100 +667,34 @@ static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid PREAUTH command: needs one argument " - "(BSSID)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long PREAUTH command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); } static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid AP_SCAN command: needs one argument (ap_scan " - "value)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long AP_SCAN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); } static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid SCAN_INTERVAL command: needs one argument " - "scan_interval value)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long SCAN_INTERVAL command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); } static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid BSS_EXPIRE_AGE command: needs one argument " - "(bss_expire_age value)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long BSS_EXPIRE_AGE command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); } static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid BSS_EXPIRE_COUNT command: needs one argument " - "(bss_expire_count value)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long BSS_EXPIRE_COUNT command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); } @@ -734,69 +718,24 @@ static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid STKSTART command: needs one argument " - "(Peer STA MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long STKSTART command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv); } static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid FT_DS command: needs one argument " - "(Target AP MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long FT_DS command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); } static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc == 0) { - /* Any BSSID */ - return wpa_ctrl_command(ctrl, "WPS_PBC"); - } - - /* Specific BSSID */ - res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_PBC command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); } static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc == 0) { printf("Invalid WPS_PIN command: need one or two arguments:\n" "- BSSID: use 'any' to select any\n" @@ -805,49 +744,14 @@ static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) return -1; } - if (argc == 1) { - /* Use dynamically generated PIN (returned as reply) */ - res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_PIN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); - } - - /* Use hardcoded PIN from a label */ - res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_PIN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); } static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1 && argc != 2) { - printf("Invalid WPS_CHECK_PIN command: needs one argument:\n" - "- PIN to be verified\n"); - return -1; - } - - if (argc == 2) - res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_CHECK_PIN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); } @@ -861,9 +765,6 @@ static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, #ifdef CONFIG_WPS_OOB static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc != 3 && argc != 4) { printf("Invalid WPS_OOB command: need three or four " "arguments:\n" @@ -876,17 +777,7 @@ static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[]) return -1; } - if (argc == 3) - res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", - argv[0], argv[1], argv[2]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s", - argv[0], argv[1], argv[2], argv[3]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_OOB command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_OOB", 3, argc, argv); } #endif /* CONFIG_WPS_OOB */ @@ -895,43 +786,14 @@ static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc >= 1) - res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC %s", - argv[0]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC"); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_NFC command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); } static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid WPS_NFC_TOKEN command: need one argument:\n" - "format: WPS or NDEF\n"); - return -1; - } - if (argc >= 1) - res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", - argv[0]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN"); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_NFC_TOKEN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); } @@ -1023,41 +885,14 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc < 1) { - printf("Invalid WPS_AP_PIN command: needs at least one " - "argument\n"); - return -1; - } - - if (argc > 2) - res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s", - argv[0], argv[1], argv[2]); - else if (argc > 1) - res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_AP_PIN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); } static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - if (argc > 0) { - os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]); - return wpa_ctrl_command(ctrl, cmd); - } - return wpa_ctrl_command(ctrl, "WPS_ER_START"); + return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); } @@ -1072,9 +907,6 @@ static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc < 2) { printf("Invalid WPS_ER_PIN command: need at least two " "arguments:\n" @@ -1084,48 +916,20 @@ static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, return -1; } - if (argc > 2) - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s", - argv[0], argv[1], argv[2]); - else - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_ER_PIN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); } static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid WPS_ER_PBC command: need one argument:\n" - "- UUID: Specify the Enrollee\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_ER_PBC command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); } static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc != 2) { printf("Invalid WPS_ER_LEARN command: need two arguments:\n" "- UUID: specify which AP to use\n" @@ -1133,22 +937,13 @@ static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_ER_LEARN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); } static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc != 2) { printf("Invalid WPS_ER_SET_CONFIG command: need two " "arguments:\n" @@ -1157,13 +952,7 @@ static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_ER_SET_CONFIG command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); } @@ -1222,9 +1011,6 @@ static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc != 2) { printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " "arguments:\n" @@ -1233,53 +1019,20 @@ static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_NFC_CONFIG_TOKEN %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long WPS_ER_NFC_CONFIG_TOKEN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); } #endif /* CONFIG_WPS_NFC */ static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid IBSS_RSN command: needs one argument " - "(Peer STA MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long IBSS_RSN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); } static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid LEVEL command: needs one argument (debug " - "level)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long LEVEL command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); } @@ -1484,85 +1237,25 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256], *pos, *end; - int i, ret; - if (argc < 2) { printf("Invalid BSSID command: needs two arguments (network " "id and BSSID)\n"); return -1; } - end = cmd + sizeof(cmd); - pos = cmd; - ret = os_snprintf(pos, end - pos, "BSSID"); - if (ret < 0 || ret >= end - pos) { - printf("Too long BSSID command.\n"); - return -1; - } - pos += ret; - for (i = 0; i < argc; i++) { - ret = os_snprintf(pos, end - pos, " %s", argv[i]); - if (ret < 0 || ret >= end - pos) { - printf("Too long BSSID command.\n"); - return -1; - } - pos += ret; - } - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); } static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256], *pos, *end; - int i, ret; - - end = cmd + sizeof(cmd); - pos = cmd; - ret = os_snprintf(pos, end - pos, "BLACKLIST"); - if (ret < 0 || ret >= end - pos) { - printf("Too long BLACKLIST command.\n"); - return -1; - } - pos += ret; - for (i = 0; i < argc; i++) { - ret = os_snprintf(pos, end - pos, " %s", argv[i]); - if (ret < 0 || ret >= end - pos) { - printf("Too long BLACKLIST command.\n"); - return -1; - } - pos += ret; - } - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); } static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256], *pos, *end; - int i, ret; - - end = cmd + sizeof(cmd); - pos = cmd; - ret = os_snprintf(pos, end - pos, "LOG_LEVEL"); - if (ret < 0 || ret >= end - pos) { - printf("Too long LOG_LEVEL command.\n"); - return -1; - } - pos += ret; - for (i = 0; i < argc; i++) { - ret = os_snprintf(pos, end - pos, " %s", argv[i]); - if (ret < 0 || ret >= end - pos) { - printf("Too long LOG_LEVEL command.\n"); - return -1; - } - pos += ret; - } - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); } @@ -1576,68 +1269,21 @@ static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[32]; - int res; - - if (argc < 1) { - printf("Invalid SELECT_NETWORK command: needs one argument " - "(network id)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); } static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[32]; - int res; - - if (argc < 1) { - printf("Invalid ENABLE_NETWORK command: needs one argument " - "(network id)\n"); - return -1; - } - - if (argc > 1) - res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); } static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[32]; - int res; - - if (argc < 1) { - printf("Invalid DISABLE_NETWORK command: needs one argument " - "(network id)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); } @@ -1651,21 +1297,7 @@ static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[32]; - int res; - - if (argc < 1) { - printf("Invalid REMOVE_NETWORK command: needs one argument " - "(network id)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); } @@ -1693,9 +1325,6 @@ static void wpa_cli_show_network_variables(void) static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc == 0) { wpa_cli_show_network_variables(); return 0; @@ -1707,22 +1336,13 @@ static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s", - argv[0], argv[1], argv[2]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long SET_NETWORK command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); } static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc == 0) { wpa_cli_show_network_variables(); return 0; @@ -1734,13 +1354,7 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long GET_NETWORK command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); } @@ -1760,42 +1374,19 @@ static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[32]; - int res; - - if (argc < 1) { - printf("Invalid REMOVE_CRED command: needs one argument " - "(cred id)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "REMOVE_CRED %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); } static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc != 3) { printf("Invalid SET_CRED command: needs three arguments\n" "(cred id, variable name, and value)\n"); return -1; } - res = os_snprintf(cmd, sizeof(cmd), "SET_CRED %s %s %s", - argv[0], argv[1], argv[2]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long SET_CRED command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); } @@ -1835,24 +1426,7 @@ static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[64]; - int res; - - if (argc < 1) { - printf("Invalid BSS command: need at least one argument" - "(index or BSSID)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "BSS %s%s%s%s%s", argv[0], - argc > 1 ? " " : "", argc > 1 ? argv[1] : "", - argc > 2 ? " " : "", argc > 2 ? argv[2] : ""); - - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); } @@ -1874,9 +1448,6 @@ static char ** wpa_cli_complete_bss(const char *str, int pos) static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[64]; - int res; - if (argc < 1 || argc > 2) { printf("Invalid GET_CAPABILITY command: need either one or " "two arguments\n"); @@ -1889,13 +1460,7 @@ static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, return -1; } - res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0], - (argc == 2) ? " strict" : ""); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); } @@ -1975,20 +1540,7 @@ static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid INTERFACE_REMOVE command: needs one argument " - "(interface name)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); } @@ -2002,14 +1554,7 @@ static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, #ifdef CONFIG_AP static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char buf[64]; - if (argc != 1) { - printf("Invalid 'sta' command - exactly one argument, STA " - "address, is required.\n"); - return -1; - } - os_snprintf(buf, sizeof(buf), "STA %s", argv[0]); - return wpa_ctrl_command(ctrl, buf); + return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); } @@ -2066,36 +1611,14 @@ static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char buf[64]; - if (argc < 1) { - printf("Invalid 'deauthenticate' command - exactly one " - "argument, STA address, is required.\n"); - return -1; - } - if (argc > 1) - os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s", - argv[0], argv[1]); - else - os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]); - return wpa_ctrl_command(ctrl, buf); + return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); } static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char buf[64]; - if (argc < 1) { - printf("Invalid 'disassociate' command - exactly one " - "argument, STA address, is required.\n"); - return -1; - } - if (argc > 1) - os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s", - argv[0], argv[1]); - else - os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]); - return wpa_ctrl_command(ctrl, buf); + return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); } #endif /* CONFIG_AP */ @@ -2120,21 +1643,7 @@ static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid ROAM command: needs one argument " - "(target AP's BSSID)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long ROAM command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); } @@ -2142,24 +1651,36 @@ static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; + return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); +} - if (argc == 0) - return wpa_ctrl_command(ctrl, "P2P_FIND"); - if (argc > 2) - res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s", - argv[0], argv[1], argv[2]); - else if (argc > 1) - res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); +static char ** wpa_cli_complete_p2p_find(const char *str, int pos) +{ + char **res = NULL; + int arg = get_cmd_arg_num(str, pos); + + res = os_calloc(6, sizeof(char *)); + if (res == NULL) + return NULL; + res[0] = os_strdup("type=social"); + if (res[0] == NULL) { + os_free(res); + return NULL; + } + res[1] = os_strdup("type=progressive"); + if (res[1] == NULL) + return res; + res[2] = os_strdup("delay="); + if (res[2] == NULL) + return res; + res[3] = os_strdup("dev_id="); + if (res[3] == NULL) + return res; + if (arg == 1) + res[4] = os_strdup("[timeout]"); + + return res; } @@ -2173,40 +1694,7 @@ static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc < 2) { - printf("Invalid P2P_CONNECT command: needs at least two " - "arguments (address and pbc/PIN)\n"); - return -1; - } -#ifdef ANDROID_P2P - if (argc > 5) - res = os_snprintf(cmd, sizeof(cmd), - "P2P_CONNECT %s %s %s %s %s %s", - argv[0], argv[1], argv[2], argv[3], - argv[4], argv[5]); - else -#endif - if (argc > 4) - res = os_snprintf(cmd, sizeof(cmd), - "P2P_CONNECT %s %s %s %s %s", - argv[0], argv[1], argv[2], argv[3], - argv[4]); - else if (argc > 3) - res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s", - argv[0], argv[1], argv[2], argv[3]); - else if (argc > 2) - res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s", - argv[0], argv[1], argv[2]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); } @@ -2228,37 +1716,14 @@ static char ** wpa_cli_complete_p2p_connect(const char *str, int pos) static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc == 0) - return wpa_ctrl_command(ctrl, "P2P_LISTEN"); - - res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); } static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid P2P_GROUP_REMOVE command: needs one argument " - "(interface name)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); } @@ -2280,31 +1745,13 @@ static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc == 0) - return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD"); - - if (argc > 1) - res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); } static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - if (argc != 2 && argc != 3) { printf("Invalid P2P_PROV_DISC command: needs at least " "two arguments, address and config method\n" @@ -2312,16 +1759,7 @@ static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, return -1; } - if (argc == 3) - res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s", - argv[0], argv[1], argv[2]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); } @@ -2336,7 +1774,6 @@ static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[4096]; - int res; if (argc != 2 && argc != 4) { printf("Invalid P2P_SERV_DISC_REQ command: needs two " @@ -2346,16 +1783,8 @@ static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, return -1; } - if (argc == 4) - res = os_snprintf(cmd, sizeof(cmd), - "P2P_SERV_DISC_REQ %s %s %s %s", - argv[0], argv[1], argv[2], argv[3]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) + if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) return -1; - cmd[sizeof(cmd) - 1] = '\0'; return wpa_ctrl_command(ctrl, cmd); } @@ -2363,21 +1792,7 @@ static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one " - "argument (pending request identifier)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); } @@ -2412,21 +1827,7 @@ static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one " - "argument (external processing: 0/1)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); } @@ -2494,60 +1895,20 @@ static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc != 1) { - printf("Invalid P2P_REJECT command: needs one argument " - "(peer address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); } static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[128]; - int res; - - if (argc < 1) { - printf("Invalid P2P_INVITE command: needs at least one " - "argument\n"); - return -1; - } - - if (argc > 2) - res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s", - argv[0], argv[1], argv[2]); - else if (argc > 1) - res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); } static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char buf[64]; - if (argc != 1) { - printf("Invalid 'p2p_peer' command - exactly one argument, " - "P2P peer device address, is required.\n"); - return -1; - } - os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]); - return wpa_ctrl_command(ctrl, buf); + return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); } @@ -2623,20 +1984,7 @@ static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - int res; - - if (argc != 2) { - printf("Invalid P2P_SET command: needs two arguments (field, " - "value)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); } @@ -2656,48 +2004,58 @@ static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - int res; + return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); +} - if (argc != 1) { - printf("Invalid P2P_UNAUTHORIZE command: needs one argument " - "(peer address)\n"); + +static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + if (argc != 0 && argc != 2 && argc != 4) { + printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " + "(preferred duration, interval; in microsecods).\n" + "Optional second pair can be used to provide " + "acceptable values.\n"); return -1; } - res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]); + return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); +} - if (res < 0 || (size_t) res >= sizeof(cmd)) + +static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + if (argc != 0 && argc != 2) { + printf("Invalid P2P_EXT_LISTEN command: needs two arguments " + "(availability period, availability interval; in " + "millisecods).\n" + "Extended Listen Timing can be cancelled with this " + "command when used without parameters.\n"); return -1; + } - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); } +#endif /* CONFIG_P2P */ -static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, - char *argv[]) +#ifdef CONFIG_WIFI_DISPLAY + +static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, + char *argv[]) { char cmd[100]; int res; - if (argc != 0 && argc != 2 && argc != 4) { - printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " - "(preferred duration, interval; in microsecods).\n" - "Optional second pair can be used to provide " - "acceptable values.\n"); + if (argc != 1 && argc != 2) { + printf("Invalid WFD_SUBELEM_SET command: needs one or two " + "arguments (subelem, hexdump)\n"); return -1; } - if (argc == 4) - res = os_snprintf(cmd, sizeof(cmd), - "P2P_PRESENCE_REQ %s %s %s %s", - argv[0], argv[1], argv[2], argv[3]); - else if (argc == 2) - res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ"); + res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", + argv[0], argc > 1 ? argv[1] : ""); if (res < 0 || (size_t) res >= sizeof(cmd)) return -1; cmd[sizeof(cmd) - 1] = '\0'; @@ -2705,33 +2063,26 @@ static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, } -static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, - char *argv[]) +static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, + char *argv[]) { char cmd[100]; int res; - if (argc != 0 && argc != 2) { - printf("Invalid P2P_EXT_LISTEN command: needs two arguments " - "(availability period, availability interval; in " - "millisecods).\n" - "Extended Listen Timing can be cancelled with this " - "command when used without parameters.\n"); + if (argc != 1) { + printf("Invalid WFD_SUBELEM_GET command: needs one " + "argument (subelem)\n"); return -1; } - if (argc == 2) - res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s", - argv[0], argv[1]); - else - res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN"); + res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", + argv[0]); if (res < 0 || (size_t) res >= sizeof(cmd)) return -1; cmd[sizeof(cmd) - 1] = '\0'; return wpa_ctrl_command(ctrl, cmd); } - -#endif /* CONFIG_P2P */ +#endif /* CONFIG_WIFI_DISPLAY */ #ifdef CONFIG_INTERWORKING @@ -2752,58 +2103,34 @@ static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - int res; - - if (argc == 0) - return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT"); - - res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); } static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - int res; + return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); +} - if (argc != 1) { - printf("Invalid INTERWORKING_CONNECT commands: needs one " - "argument (BSSID)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s", - argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); +static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); } -static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) +static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, + char *argv[]) { - char cmd[100]; - int res; + return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); +} - if (argc != 2) { - printf("Invalid ANQP_GET command: needs two arguments " - "(addr and info id list)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); +static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); } #endif /* CONFIG_INTERWORKING */ @@ -2813,21 +2140,7 @@ static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[100]; - int res; - - if (argc != 2) { - printf("Invalid HS20_ANQP_GET command: needs two arguments " - "(addr and subtype list)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "HS20_ANQP_GET %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd)) - return -1; - cmd[sizeof(cmd) - 1] = '\0'; - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); } @@ -2835,7 +2148,6 @@ static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[512]; - int res; if (argc == 0) { printf("Command needs one or two arguments (dst mac addr and " @@ -2843,18 +2155,9 @@ static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, return -1; } - if (argc == 1) - res = os_snprintf(cmd, sizeof(cmd), - "HS20_GET_NAI_HOME_REALM_LIST %s", - argv[0]); - else - res = os_snprintf(cmd, sizeof(cmd), - "HS20_GET_NAI_HOME_REALM_LIST %s %s", - argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long command.\n"); + if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", + argc, argv) < 0) return -1; - } return wpa_ctrl_command(ctrl, cmd); } @@ -2865,83 +2168,28 @@ static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid STA_AUTOCONNECT command: needs one argument " - "(0/1 = disable/enable automatic reconnection)\n"); - return -1; - } - res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long STA_AUTOCONNECT command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); } static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid TDLS_DISCOVER command: needs one argument " - "(Peer STA MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long TDLS_DISCOVER command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); } static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid TDLS_SETUP command: needs one argument " - "(Peer STA MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long TDLS_SETUP command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); } static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - - if (argc != 1) { - printf("Invalid TDLS_TEARDOWN command: needs one argument " - "(Peer STA MAC address)\n"); - return -1; - } - - res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long TDLS_TEARDOWN command.\n"); - return -1; - } - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); } @@ -2970,24 +2218,23 @@ static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - char cmd[256]; - int res; - if (argc == 0) return wpa_ctrl_command(ctrl, "AUTOSCAN "); - res = os_snprintf(cmd, sizeof(cmd), "AUTOSCAN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { - printf("Too long AUTOSCAN command.\n"); - return -1; - } - - return wpa_ctrl_command(ctrl, cmd); + return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); } #endif /* CONFIG_AUTOSCAN */ +static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + if (argc == 0) + return -1; + return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); +} + + #ifdef ANDROID static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3009,6 +2256,7 @@ static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) } #endif + enum wpa_cli_cmd_flags { cli_cmd_flag_none = 0x00, cli_cmd_flag_sensitive = 0x01 @@ -3017,401 +2265,433 @@ enum wpa_cli_cmd_flags { struct wpa_cli_cmd { const char *cmd; int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); + char ** (*completion)(const char *str, int pos); enum wpa_cli_cmd_flags flags; const char *usage; }; static struct wpa_cli_cmd wpa_cli_commands[] = { - { "status", wpa_cli_cmd_status, + { "status", wpa_cli_cmd_status, NULL, cli_cmd_flag_none, "[verbose] = get current WPA/EAPOL/EAP status" }, - { "ping", wpa_cli_cmd_ping, + { "ifname", wpa_cli_cmd_ifname, NULL, + cli_cmd_flag_none, + "= get current interface name" }, + { "ping", wpa_cli_cmd_ping, NULL, cli_cmd_flag_none, "= pings wpa_supplicant" }, - { "relog", wpa_cli_cmd_relog, + { "relog", wpa_cli_cmd_relog, NULL, cli_cmd_flag_none, "= re-open log-file (allow rolling logs)" }, - { "note", wpa_cli_cmd_note, + { "note", wpa_cli_cmd_note, NULL, cli_cmd_flag_none, "<text> = add a note to wpa_supplicant debug log" }, - { "mib", wpa_cli_cmd_mib, + { "mib", wpa_cli_cmd_mib, NULL, cli_cmd_flag_none, "= get MIB variables (dot1x, dot11)" }, - { "help", wpa_cli_cmd_help, + { "help", wpa_cli_cmd_help, wpa_cli_complete_help, cli_cmd_flag_none, - "= show this usage help" }, - { "interface", wpa_cli_cmd_interface, + "[command] = show usage help" }, + { "interface", wpa_cli_cmd_interface, NULL, cli_cmd_flag_none, "[ifname] = show interfaces/select interface" }, - { "level", wpa_cli_cmd_level, + { "level", wpa_cli_cmd_level, NULL, cli_cmd_flag_none, "<debug level> = change debug level" }, - { "license", wpa_cli_cmd_license, + { "license", wpa_cli_cmd_license, NULL, cli_cmd_flag_none, "= show full wpa_cli license" }, - { "quit", wpa_cli_cmd_quit, + { "quit", wpa_cli_cmd_quit, NULL, cli_cmd_flag_none, "= exit wpa_cli" }, - { "set", wpa_cli_cmd_set, + { "set", wpa_cli_cmd_set, NULL, cli_cmd_flag_none, "= set variables (shows list of variables when run without " "arguments)" }, - { "get", wpa_cli_cmd_get, + { "get", wpa_cli_cmd_get, NULL, cli_cmd_flag_none, "<name> = get information" }, - { "logon", wpa_cli_cmd_logon, + { "logon", wpa_cli_cmd_logon, NULL, cli_cmd_flag_none, "= IEEE 802.1X EAPOL state machine logon" }, - { "logoff", wpa_cli_cmd_logoff, + { "logoff", wpa_cli_cmd_logoff, NULL, cli_cmd_flag_none, "= IEEE 802.1X EAPOL state machine logoff" }, - { "pmksa", wpa_cli_cmd_pmksa, + { "pmksa", wpa_cli_cmd_pmksa, NULL, cli_cmd_flag_none, "= show PMKSA cache" }, - { "reassociate", wpa_cli_cmd_reassociate, + { "reassociate", wpa_cli_cmd_reassociate, NULL, cli_cmd_flag_none, "= force reassociation" }, - { "preauthenticate", wpa_cli_cmd_preauthenticate, + { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, cli_cmd_flag_none, "<BSSID> = force preauthentication" }, - { "identity", wpa_cli_cmd_identity, + { "identity", wpa_cli_cmd_identity, NULL, cli_cmd_flag_none, "<network id> <identity> = configure identity for an SSID" }, - { "password", wpa_cli_cmd_password, + { "password", wpa_cli_cmd_password, NULL, cli_cmd_flag_sensitive, "<network id> <password> = configure password for an SSID" }, - { "new_password", wpa_cli_cmd_new_password, + { "new_password", wpa_cli_cmd_new_password, NULL, cli_cmd_flag_sensitive, "<network id> <password> = change password for an SSID" }, - { "pin", wpa_cli_cmd_pin, + { "pin", wpa_cli_cmd_pin, NULL, cli_cmd_flag_sensitive, "<network id> <pin> = configure pin for an SSID" }, - { "otp", wpa_cli_cmd_otp, + { "otp", wpa_cli_cmd_otp, NULL, cli_cmd_flag_sensitive, "<network id> <password> = configure one-time-password for an SSID" }, - { "passphrase", wpa_cli_cmd_passphrase, + { "passphrase", wpa_cli_cmd_passphrase, NULL, cli_cmd_flag_sensitive, "<network id> <passphrase> = configure private key passphrase\n" " for an SSID" }, - { "bssid", wpa_cli_cmd_bssid, + { "bssid", wpa_cli_cmd_bssid, NULL, cli_cmd_flag_none, "<network id> <BSSID> = set preferred BSSID for an SSID" }, - { "blacklist", wpa_cli_cmd_blacklist, + { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, cli_cmd_flag_none, "<BSSID> = add a BSSID to the blacklist\n" "blacklist clear = clear the blacklist\n" "blacklist = display the blacklist" }, - { "log_level", wpa_cli_cmd_log_level, + { "log_level", wpa_cli_cmd_log_level, NULL, cli_cmd_flag_none, "<level> [<timestamp>] = update the log level/timestamp\n" "log_level = display the current log level and log options" }, - { "list_networks", wpa_cli_cmd_list_networks, + { "list_networks", wpa_cli_cmd_list_networks, NULL, cli_cmd_flag_none, "= list configured networks" }, - { "select_network", wpa_cli_cmd_select_network, + { "select_network", wpa_cli_cmd_select_network, NULL, cli_cmd_flag_none, "<network id> = select a network (disable others)" }, - { "enable_network", wpa_cli_cmd_enable_network, + { "enable_network", wpa_cli_cmd_enable_network, NULL, cli_cmd_flag_none, "<network id> = enable a network" }, - { "disable_network", wpa_cli_cmd_disable_network, + { "disable_network", wpa_cli_cmd_disable_network, NULL, cli_cmd_flag_none, "<network id> = disable a network" }, - { "add_network", wpa_cli_cmd_add_network, + { "add_network", wpa_cli_cmd_add_network, NULL, cli_cmd_flag_none, "= add a network" }, - { "remove_network", wpa_cli_cmd_remove_network, + { "remove_network", wpa_cli_cmd_remove_network, NULL, cli_cmd_flag_none, "<network id> = remove a network" }, - { "set_network", wpa_cli_cmd_set_network, + { "set_network", wpa_cli_cmd_set_network, NULL, cli_cmd_flag_sensitive, "<network id> <variable> <value> = set network variables (shows\n" " list of variables when run without arguments)" }, - { "get_network", wpa_cli_cmd_get_network, + { "get_network", wpa_cli_cmd_get_network, NULL, cli_cmd_flag_none, "<network id> <variable> = get network variables" }, - { "list_creds", wpa_cli_cmd_list_creds, + { "list_creds", wpa_cli_cmd_list_creds, NULL, cli_cmd_flag_none, "= list configured credentials" }, - { "add_cred", wpa_cli_cmd_add_cred, + { "add_cred", wpa_cli_cmd_add_cred, NULL, cli_cmd_flag_none, "= add a credential" }, - { "remove_cred", wpa_cli_cmd_remove_cred, + { "remove_cred", wpa_cli_cmd_remove_cred, NULL, cli_cmd_flag_none, "<cred id> = remove a credential" }, - { "set_cred", wpa_cli_cmd_set_cred, + { "set_cred", wpa_cli_cmd_set_cred, NULL, cli_cmd_flag_sensitive, "<cred id> <variable> <value> = set credential variables" }, - { "save_config", wpa_cli_cmd_save_config, + { "save_config", wpa_cli_cmd_save_config, NULL, cli_cmd_flag_none, "= save the current configuration" }, - { "disconnect", wpa_cli_cmd_disconnect, + { "disconnect", wpa_cli_cmd_disconnect, NULL, cli_cmd_flag_none, "= disconnect and wait for reassociate/reconnect command before\n" " connecting" }, - { "reconnect", wpa_cli_cmd_reconnect, + { "reconnect", wpa_cli_cmd_reconnect, NULL, cli_cmd_flag_none, "= like reassociate, but only takes effect if already disconnected" }, - { "scan", wpa_cli_cmd_scan, + { "scan", wpa_cli_cmd_scan, NULL, cli_cmd_flag_none, "= request new BSS scan" }, - { "scan_results", wpa_cli_cmd_scan_results, + { "scan_results", wpa_cli_cmd_scan_results, NULL, cli_cmd_flag_none, "= get latest scan results" }, - { "bss", wpa_cli_cmd_bss, + { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, cli_cmd_flag_none, "<<idx> | <bssid>> = get detailed scan result info" }, - { "get_capability", wpa_cli_cmd_get_capability, + { "get_capability", wpa_cli_cmd_get_capability, NULL, cli_cmd_flag_none, - "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels>\n" - " = get capabilities" }, - { "reconfigure", wpa_cli_cmd_reconfigure, + "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> " + "= get capabilies" }, + { "reconfigure", wpa_cli_cmd_reconfigure, NULL, cli_cmd_flag_none, "= force wpa_supplicant to re-read its configuration file" }, - { "terminate", wpa_cli_cmd_terminate, + { "terminate", wpa_cli_cmd_terminate, NULL, cli_cmd_flag_none, "= terminate wpa_supplicant" }, - { "interface_add", wpa_cli_cmd_interface_add, + { "interface_add", wpa_cli_cmd_interface_add, NULL, cli_cmd_flag_none, "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" " <bridge_name> = adds new interface, all parameters but <ifname>\n" " are optional" }, - { "interface_remove", wpa_cli_cmd_interface_remove, + { "interface_remove", wpa_cli_cmd_interface_remove, NULL, cli_cmd_flag_none, "<ifname> = removes the interface" }, - { "interface_list", wpa_cli_cmd_interface_list, + { "interface_list", wpa_cli_cmd_interface_list, NULL, cli_cmd_flag_none, "= list available interfaces" }, - { "ap_scan", wpa_cli_cmd_ap_scan, + { "ap_scan", wpa_cli_cmd_ap_scan, NULL, cli_cmd_flag_none, "<value> = set ap_scan parameter" }, - { "scan_interval", wpa_cli_cmd_scan_interval, + { "scan_interval", wpa_cli_cmd_scan_interval, NULL, cli_cmd_flag_none, "<value> = set scan_interval parameter (in seconds)" }, - { "bss_expire_age", wpa_cli_cmd_bss_expire_age, + { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, cli_cmd_flag_none, "<value> = set BSS expiration age parameter" }, - { "bss_expire_count", wpa_cli_cmd_bss_expire_count, + { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, cli_cmd_flag_none, "<value> = set BSS expiration scan count parameter" }, - { "bss_flush", wpa_cli_cmd_bss_flush, + { "bss_flush", wpa_cli_cmd_bss_flush, NULL, cli_cmd_flag_none, "<value> = set BSS flush age (0 by default)" }, - { "stkstart", wpa_cli_cmd_stkstart, + { "stkstart", wpa_cli_cmd_stkstart, NULL, cli_cmd_flag_none, "<addr> = request STK negotiation with <addr>" }, - { "ft_ds", wpa_cli_cmd_ft_ds, + { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, cli_cmd_flag_none, "<addr> = request over-the-DS FT with <addr>" }, - { "wps_pbc", wpa_cli_cmd_wps_pbc, + { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, cli_cmd_flag_none, "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, - { "wps_pin", wpa_cli_cmd_wps_pin, + { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, cli_cmd_flag_sensitive, "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " "hardcoded)" }, - { "wps_check_pin", wpa_cli_cmd_wps_check_pin, + { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, cli_cmd_flag_sensitive, "<PIN> = verify PIN checksum" }, - { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none, + { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, "Cancels the pending WPS operation" }, #ifdef CONFIG_WPS_OOB - { "wps_oob", wpa_cli_cmd_wps_oob, + { "wps_oob", wpa_cli_cmd_wps_oob, NULL, cli_cmd_flag_sensitive, "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" }, #endif /* CONFIG_WPS_OOB */ #ifdef CONFIG_WPS_NFC - { "wps_nfc", wpa_cli_cmd_wps_nfc, + { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, cli_cmd_flag_none, "[BSSID] = start Wi-Fi Protected Setup: NFC" }, - { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, + { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, cli_cmd_flag_none, "<WPS|NDEF> = create password token" }, - { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, + { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, cli_cmd_flag_sensitive, "<hexdump of payload> = report read NFC tag with WPS data" }, #endif /* CONFIG_WPS_NFC */ - { "wps_reg", wpa_cli_cmd_wps_reg, + { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, cli_cmd_flag_sensitive, "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, - { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, + { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, cli_cmd_flag_sensitive, "[params..] = enable/disable AP PIN" }, - { "wps_er_start", wpa_cli_cmd_wps_er_start, + { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, cli_cmd_flag_none, "[IP address] = start Wi-Fi Protected Setup External Registrar" }, - { "wps_er_stop", wpa_cli_cmd_wps_er_stop, + { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, cli_cmd_flag_none, "= stop Wi-Fi Protected Setup External Registrar" }, - { "wps_er_pin", wpa_cli_cmd_wps_er_pin, + { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, cli_cmd_flag_sensitive, "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, - { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, + { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, cli_cmd_flag_none, "<UUID> = accept an Enrollee PBC using External Registrar" }, - { "wps_er_learn", wpa_cli_cmd_wps_er_learn, + { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, cli_cmd_flag_sensitive, "<UUID> <PIN> = learn AP configuration" }, - { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, + { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, cli_cmd_flag_none, "<UUID> <network id> = set AP configuration for enrolling" }, - { "wps_er_config", wpa_cli_cmd_wps_er_config, + { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, cli_cmd_flag_sensitive, "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, #ifdef CONFIG_WPS_NFC - { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, + { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, cli_cmd_flag_none, "<WPS/NDEF> <UUID> = build NFC configuration token" }, #endif /* CONFIG_WPS_NFC */ - { "ibss_rsn", wpa_cli_cmd_ibss_rsn, + { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, cli_cmd_flag_none, "<addr> = request RSN authentication with <addr> in IBSS" }, #ifdef CONFIG_AP - { "sta", wpa_cli_cmd_sta, + { "sta", wpa_cli_cmd_sta, NULL, cli_cmd_flag_none, "<addr> = get information about an associated station (AP)" }, - { "all_sta", wpa_cli_cmd_all_sta, + { "all_sta", wpa_cli_cmd_all_sta, NULL, cli_cmd_flag_none, "= get information about all associated stations (AP)" }, - { "deauthenticate", wpa_cli_cmd_deauthenticate, + { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL, cli_cmd_flag_none, "<addr> = deauthenticate a station" }, - { "disassociate", wpa_cli_cmd_disassociate, + { "disassociate", wpa_cli_cmd_disassociate, NULL, cli_cmd_flag_none, "<addr> = disassociate a station" }, #endif /* CONFIG_AP */ - { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none, + { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, "= notification of suspend/hibernate" }, - { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none, + { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, "= notification of resume/thaw" }, - { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none, + { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, "= drop SA without deauth/disassoc (test command)" }, - { "roam", wpa_cli_cmd_roam, + { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, cli_cmd_flag_none, "<addr> = roam to the specified BSS" }, #ifdef CONFIG_P2P - { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none, + { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, + cli_cmd_flag_none, "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, - { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none, + { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, "= stop P2P Devices search" }, - { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none, - "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" }, - { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none, + { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, + cli_cmd_flag_none, + "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, + { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, "[timeout] = listen for P2P Devices for up-to timeout seconds" }, - { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none, + { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, + wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, "<ifname> = remove P2P group interface (terminate group if GO)" }, - { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none, - "= add a new P2P group (local end as GO)" }, - { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none, + { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, + "[ht40] = add a new P2P group (local end as GO)" }, + { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, + wpa_cli_complete_p2p_peer, cli_cmd_flag_none, "<addr> <method> = request provisioning discovery" }, - { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, + { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, cli_cmd_flag_none, "= get the passphrase for a group (GO only)" }, { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, - cli_cmd_flag_none, + wpa_cli_complete_p2p_peer, cli_cmd_flag_none, "<addr> <TLVs> = schedule service discovery request" }, { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, - cli_cmd_flag_none, + NULL, cli_cmd_flag_none, "<id> = cancel pending service discovery request" }, - { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, + { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, cli_cmd_flag_none, "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, - { "p2p_service_update", wpa_cli_cmd_p2p_service_update, + { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, cli_cmd_flag_none, "= indicate change in local services" }, - { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, + { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, cli_cmd_flag_none, "<external> = set external processing of service discovery" }, - { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, + { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, cli_cmd_flag_none, "= remove all stored service entries" }, - { "p2p_service_add", wpa_cli_cmd_p2p_service_add, + { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, cli_cmd_flag_none, "<bonjour|upnp> <query|version> <response|service> = add a local " "service" }, - { "p2p_service_del", wpa_cli_cmd_p2p_service_del, + { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, cli_cmd_flag_none, "<bonjour|upnp> <query|version> [|service] = remove a local " "service" }, - { "p2p_reject", wpa_cli_cmd_p2p_reject, + { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, cli_cmd_flag_none, "<addr> = reject connection attempts from a specific peer" }, - { "p2p_invite", wpa_cli_cmd_p2p_invite, + { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, cli_cmd_flag_none, "<cmd> [peer=addr] = invite peer" }, - { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none, + { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, "[discovered] = list known (optionally, only fully discovered) P2P " "peers" }, - { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none, + { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, + cli_cmd_flag_none, "<address> = show information about known P2P peer" }, - { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none, + { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none, "<field> <value> = set a P2P parameter" }, - { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none, + { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, "= flush P2P state" }, - { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none, + { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, "= cancel P2P group formation" }, - { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none, + { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, + wpa_cli_complete_p2p_peer, cli_cmd_flag_none, "<address> = unauthorize a peer" }, - { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none, + { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, + cli_cmd_flag_none, "[<duration> <interval>] [<duration> <interval>] = request GO " "presence" }, - { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none, + { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, + cli_cmd_flag_none, "[<period> <interval>] = set extended listen timing" }, #endif /* CONFIG_P2P */ - +#ifdef CONFIG_WIFI_DISPLAY + { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, + cli_cmd_flag_none, + "<subelem> [contents] = set Wi-Fi Display subelement" }, + { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, + cli_cmd_flag_none, + "<subelem> = get Wi-Fi Display subelement" }, +#endif /* CONFIG_WIFI_DISPLAY */ #ifdef CONFIG_INTERWORKING - { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none, + { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, "= fetch ANQP information for all APs" }, - { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none, + { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, + cli_cmd_flag_none, "= stop fetch_anqp operation" }, - { "interworking_select", wpa_cli_cmd_interworking_select, + { "interworking_select", wpa_cli_cmd_interworking_select, NULL, cli_cmd_flag_none, "[auto] = perform Interworking network selection" }, { "interworking_connect", wpa_cli_cmd_interworking_connect, - cli_cmd_flag_none, + wpa_cli_complete_bss, cli_cmd_flag_none, "<BSSID> = connect using Interworking credentials" }, - { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none, + { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, + cli_cmd_flag_none, "<addr> <info id>[,<info id>]... = request ANQP information" }, + { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, + cli_cmd_flag_none, + "<addr> <AdvProtoID> [QueryReq] = GAS request" }, + { "gas_response_get", wpa_cli_cmd_gas_response_get, + wpa_cli_complete_bss, cli_cmd_flag_none, + "<addr> <dialog token> [start,len] = Fetch last GAS response" }, #endif /* CONFIG_INTERWORKING */ #ifdef CONFIG_HS20 - { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, cli_cmd_flag_none, + { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, + cli_cmd_flag_none, "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" }, { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, - cli_cmd_flag_none, + wpa_cli_complete_bss, cli_cmd_flag_none, "<addr> <home realm> = get HS20 nai home realm list" }, #endif /* CONFIG_HS20 */ - { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none, + { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, + cli_cmd_flag_none, "<0/1> = disable/enable automatic reconnection" }, - { "tdls_discover", wpa_cli_cmd_tdls_discover, + { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, cli_cmd_flag_none, "<addr> = request TDLS discovery with <addr>" }, - { "tdls_setup", wpa_cli_cmd_tdls_setup, + { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, cli_cmd_flag_none, "<addr> = request TDLS setup with <addr>" }, - { "tdls_teardown", wpa_cli_cmd_tdls_teardown, + { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, cli_cmd_flag_none, "<addr> = tear down TDLS with <addr>" }, - { "signal_poll", wpa_cli_cmd_signal_poll, + { "signal_poll", wpa_cli_cmd_signal_poll, NULL, cli_cmd_flag_none, "= get signal parameters" }, - { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, + { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, cli_cmd_flag_none, "= get TX/RX packet counters" }, - { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none, + { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, + cli_cmd_flag_none, "= trigger IEEE 802.1X/EAPOL reauthentication" }, #ifdef CONFIG_AUTOSCAN - { "autoscan", wpa_cli_cmd_autoscan, cli_cmd_flag_none, + { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, "[params] = Set or unset (if none) autoscan parameters" }, #endif /* CONFIG_AUTOSCAN */ + { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, + "<params..> = Sent unprocessed command" }, #ifdef ANDROID - { "driver", wpa_cli_cmd_driver, + { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, "<command> = driver private commands" }, #endif - { NULL, NULL, cli_cmd_flag_none, NULL } + { NULL, NULL, NULL, cli_cmd_flag_none, NULL } }; @@ -3433,12 +2713,14 @@ static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad) } -static void print_help(void) +static void print_help(const char *cmd) { int n; printf("commands:\n"); - for (n = 0; wpa_cli_commands[n].cmd; n++) - print_cmd_help(&wpa_cli_commands[n], " "); + for (n = 0; wpa_cli_commands[n].cmd; n++) { + if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) + print_cmd_help(&wpa_cli_commands[n], " "); + } } @@ -3469,7 +2751,7 @@ static char ** wpa_list_cmd_list(void) int i, count; count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]); - res = os_zalloc(count * sizeof(char *)); + res = os_calloc(count, sizeof(char *)); if (res == NULL) return NULL; @@ -3488,19 +2770,11 @@ static char ** wpa_cli_cmd_completion(const char *cmd, const char *str, { int i; - if (os_strcasecmp(cmd, "bss") == 0) - return wpa_cli_complete_bss(str, pos); -#ifdef CONFIG_P2P - if (os_strcasecmp(cmd, "p2p_connect") == 0) - return wpa_cli_complete_p2p_connect(str, pos); - if (os_strcasecmp(cmd, "p2p_peer") == 0) - return wpa_cli_complete_p2p_peer(str, pos); - if (os_strcasecmp(cmd, "p2p_group_remove") == 0) - return wpa_cli_complete_p2p_group_remove(str, pos); -#endif /* CONFIG_P2P */ - for (i = 0; wpa_cli_commands[i].cmd; i++) { if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { + if (wpa_cli_commands[i].completion) + return wpa_cli_commands[i].completion(str, + pos); edit_clear_line(); printf("\r%s\n", wpa_cli_commands[i].usage); edit_redraw(); @@ -3711,7 +2985,14 @@ static void wpa_cli_action_cb(char *msg, size_t len) static void wpa_cli_reconnect(void) { wpa_cli_close_connection(); - wpa_cli_open_connection(ctrl_ifname, 1); + if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) + return; + + if (interactive) { + edit_clear_line(); + printf("\rConnection to wpa_supplicant re-established\n"); + edit_redraw(); + } } @@ -3783,6 +3064,33 @@ static void cli_event(const char *str) } +static int check_terminating(const char *msg) +{ + const char *pos = msg; + + if (*pos == '<') { + /* skip priority */ + pos = os_strchr(pos, '>'); + if (pos) + pos++; + else + pos = msg; + } + + if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { + edit_clear_line(); + printf("\rConnection to wpa_supplicant lost - trying to " + "reconnect\n"); + edit_redraw(); + wpa_cli_attached = 0; + wpa_cli_close_connection(); + return 1; + } + + return 0; +} + + static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) { if (ctrl_conn == NULL) { @@ -3803,6 +3111,9 @@ static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) printf("\r%s\n", buf); edit_redraw(); } + + if (interactive && check_terminating(buf) > 0) + return; } } else { printf("Could not read pending message.\n"); @@ -3862,12 +3173,6 @@ static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) } -static void wpa_cli_eloop_terminate(int sig, void *signal_ctx) -{ - eloop_terminate(); -} - - static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) { wpa_cli_recv_pending(mon_conn, 0); @@ -3890,11 +3195,18 @@ static void wpa_cli_edit_eof_cb(void *ctx) } -static void wpa_cli_interactive(void) +static int warning_displayed = 0; +static char *hfile = NULL; +static int edit_started = 0; + +static void start_edit(void) { - char *home, *hfile = NULL; + char *home; + char *ps = NULL; - printf("\nInteractive mode\n\n"); +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE + ps = wpa_ctrl_get_remote_ifname(ctrl_conn); +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ home = getenv("HOME"); if (home) { @@ -3905,17 +3217,52 @@ static void wpa_cli_interactive(void) os_snprintf(hfile, hfile_len, "%s/%s", home, fname); } - eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL); - edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, - wpa_cli_edit_completion_cb, NULL, hfile); + if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, + wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { + eloop_terminate(); + return; + } + + edit_started = 1; eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); +} + + +static void try_connection(void *eloop_ctx, void *timeout_ctx) +{ + if (ctrl_ifname == NULL) + ctrl_ifname = wpa_cli_get_default_ifname(); + + if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) { + if (!warning_displayed) { + printf("Could not connect to wpa_supplicant: " + "%s - re-trying\n", ctrl_ifname); + warning_displayed = 1; + } + eloop_register_timeout(1, 0, try_connection, NULL, NULL); + return; + } + + if (warning_displayed) + printf("Connection established.\n"); + start_edit(); +} + + +static void wpa_cli_interactive(void) +{ + printf("\nInteractive mode\n\n"); + + eloop_register_timeout(0, 0, try_connection, NULL, NULL); eloop_run(); + eloop_cancel_timeout(try_connection, NULL, NULL); cli_txt_list_flush(&p2p_peers); cli_txt_list_flush(&p2p_groups); cli_txt_list_flush(&bsses); - edit_deinit(hfile, wpa_cli_edit_filter_history_cb); + if (edit_started) + edit_deinit(hfile, wpa_cli_edit_filter_history_cb); os_free(hfile); eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); wpa_cli_close_connection(); @@ -3974,10 +3321,10 @@ static void wpa_cli_cleanup(void) os_program_deinit(); } -static void wpa_cli_terminate(int sig) + +static void wpa_cli_terminate(int sig, void *ctx) { - wpa_cli_cleanup(); - exit(0); + eloop_terminate(); } @@ -4051,7 +3398,6 @@ static char * wpa_cli_get_default_ifname(void) int main(int argc, char *argv[]) { - int warning_displayed = 0; int c; int daemonize = 0; int ret = 0; @@ -4121,30 +3467,13 @@ int main(int argc, char *argv[]) } } -#ifndef _WIN32_WCE - signal(SIGINT, wpa_cli_terminate); - signal(SIGTERM, wpa_cli_terminate); -#endif /* _WIN32_WCE */ + eloop_register_signal_terminate(wpa_cli_terminate, NULL); if (ctrl_ifname == NULL) ctrl_ifname = wpa_cli_get_default_ifname(); if (interactive) { - for (; !global;) { - if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { - if (warning_displayed) - printf("Connection established.\n"); - break; - } - - if (!warning_displayed) { - printf("Could not connect to wpa_supplicant: " - "%s - re-trying\n", ctrl_ifname); - warning_displayed = 1; - } - os_sleep(1, 0); - continue; - } + wpa_cli_interactive(); } else { if (!global && wpa_cli_open_connection(ctrl_ifname, 0) < 0) { @@ -4163,17 +3492,16 @@ int main(int argc, char *argv[]) return -1; } } - } - if (daemonize && os_daemonize(pid_file)) - return -1; + if (daemonize && os_daemonize(pid_file)) + return -1; - if (interactive) - wpa_cli_interactive(); - else if (action_file) - wpa_cli_action(ctrl_conn); - else - ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]); + if (action_file) + wpa_cli_action(ctrl_conn); + else + ret = wpa_request(ctrl_conn, argc - optind, + &argv[optind]); + } os_free(ctrl_ifname); eloop_destroy(); |