xref: /freebsd/contrib/wpa/wpa_supplicant/wpa_cli.c (revision a90b9d0159070121c221b966469c3e36d912bf82)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * WPA Supplicant - command line interface for wpa_supplicant daemon
3ec080394SCy Schubert  * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
5f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo  * See README for more details.
739beb93cSSam Leffler  */
839beb93cSSam Leffler 
939beb93cSSam Leffler #include "includes.h"
1039beb93cSSam Leffler 
1139beb93cSSam Leffler #ifdef CONFIG_CTRL_IFACE
1239beb93cSSam Leffler 
1339beb93cSSam Leffler #ifdef CONFIG_CTRL_IFACE_UNIX
1439beb93cSSam Leffler #include <dirent.h>
1539beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE_UNIX */
1639beb93cSSam Leffler 
17780fb4a2SCy Schubert #include "common/cli.h"
18e28a4053SRui Paulo #include "common/wpa_ctrl.h"
19f05cddf9SRui Paulo #include "utils/common.h"
20f05cddf9SRui Paulo #include "utils/eloop.h"
21f05cddf9SRui Paulo #include "utils/edit.h"
22f05cddf9SRui Paulo #include "utils/list.h"
23e28a4053SRui Paulo #include "common/version.h"
24f05cddf9SRui Paulo #include "common/ieee802_11_defs.h"
25f05cddf9SRui Paulo #ifdef ANDROID
26f05cddf9SRui Paulo #include <cutils/properties.h>
27f05cddf9SRui Paulo #endif /* ANDROID */
2839beb93cSSam Leffler 
2939beb93cSSam Leffler 
30325151a3SRui Paulo static const char *const wpa_cli_version =
3139beb93cSSam Leffler "wpa_cli v" VERSION_STR "\n"
32*a90b9d01SCy Schubert "Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi> and contributors";
3339beb93cSSam Leffler 
34780fb4a2SCy Schubert #define VENDOR_ELEM_FRAME_ID \
35780fb4a2SCy Schubert 	"  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
36780fb4a2SCy Schubert 	"3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
37780fb4a2SCy Schubert 	"7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
38780fb4a2SCy Schubert 	"11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
3939beb93cSSam Leffler 
4039beb93cSSam Leffler static struct wpa_ctrl *ctrl_conn;
41e28a4053SRui Paulo static struct wpa_ctrl *mon_conn;
4239beb93cSSam Leffler static int wpa_cli_quit = 0;
4339beb93cSSam Leffler static int wpa_cli_attached = 0;
445b9c547cSRui Paulo static int wpa_cli_connected = -1;
4539beb93cSSam Leffler static int wpa_cli_last_id = 0;
46f05cddf9SRui Paulo #ifndef CONFIG_CTRL_IFACE_DIR
47f05cddf9SRui Paulo #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
48f05cddf9SRui Paulo #endif /* CONFIG_CTRL_IFACE_DIR */
49f05cddf9SRui Paulo static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
50325151a3SRui Paulo static const char *client_socket_dir = NULL;
5139beb93cSSam Leffler static char *ctrl_ifname = NULL;
524bc52338SCy Schubert static const char *global = NULL;
5339beb93cSSam Leffler static const char *pid_file = NULL;
5439beb93cSSam Leffler static const char *action_file = NULL;
55c1d255d3SCy Schubert static int reconnect = 0;
5639beb93cSSam Leffler static int ping_interval = 5;
57e28a4053SRui Paulo static int interactive = 0;
585b9c547cSRui Paulo static char *ifname_prefix = NULL;
5939beb93cSSam Leffler 
60f05cddf9SRui Paulo static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
61f05cddf9SRui Paulo static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
62f05cddf9SRui Paulo static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
635b9c547cSRui Paulo static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
64325151a3SRui Paulo static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */
6585732ac8SCy Schubert static DEFINE_DL_LIST(creds); /* struct cli_txt_entry */
6685732ac8SCy Schubert #ifdef CONFIG_AP
6785732ac8SCy Schubert static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */
6885732ac8SCy Schubert #endif /* CONFIG_AP */
69f05cddf9SRui Paulo 
70f05cddf9SRui Paulo 
71f05cddf9SRui Paulo static void print_help(const char *cmd);
72f05cddf9SRui Paulo static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
73f05cddf9SRui Paulo static void wpa_cli_close_connection(void);
74f05cddf9SRui Paulo static char * wpa_cli_get_default_ifname(void);
75f05cddf9SRui Paulo static char ** wpa_list_cmd_list(void);
7685732ac8SCy Schubert static void update_creds(struct wpa_ctrl *ctrl);
77325151a3SRui Paulo static void update_networks(struct wpa_ctrl *ctrl);
7885732ac8SCy Schubert static void update_stations(struct wpa_ctrl *ctrl);
794bc52338SCy Schubert static void update_ifnames(struct wpa_ctrl *ctrl);
8039beb93cSSam Leffler 
8139beb93cSSam Leffler 
usage(void)8239beb93cSSam Leffler static void usage(void)
8339beb93cSSam Leffler {
84c1d255d3SCy Schubert 	printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvBr] "
8539beb93cSSam Leffler 	       "[-a<action file>] \\\n"
8639beb93cSSam Leffler 	       "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
87325151a3SRui Paulo 	       "\\\n"
88325151a3SRui Paulo 	       "        [-s<wpa_client_socket_file_path>] "
8939beb93cSSam Leffler 	       "[command..]\n"
9039beb93cSSam Leffler 	       "  -h = help (show this usage text)\n"
9139beb93cSSam Leffler 	       "  -v = shown version information\n"
9239beb93cSSam Leffler 	       "  -a = run in daemon mode executing the action file based on "
9339beb93cSSam Leffler 	       "events from\n"
9439beb93cSSam Leffler 	       "       wpa_supplicant\n"
95c1d255d3SCy Schubert 	       "  -r = try to reconnect when client socket is disconnected.\n"
96c1d255d3SCy Schubert 	       "       This is useful only when used with -a.\n"
9739beb93cSSam Leffler 	       "  -B = run a daemon in the background\n"
98f05cddf9SRui Paulo 	       "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
9939beb93cSSam Leffler 	       "  default interface: first interface found in socket path\n");
100f05cddf9SRui Paulo 	print_help(NULL);
10139beb93cSSam Leffler }
10239beb93cSSam Leffler 
10339beb93cSSam Leffler 
wpa_cli_show_event(const char * event)104f05cddf9SRui Paulo static int wpa_cli_show_event(const char *event)
105f05cddf9SRui Paulo {
106f05cddf9SRui Paulo 	const char *start;
107f05cddf9SRui Paulo 
108f05cddf9SRui Paulo 	start = os_strchr(event, '>');
109f05cddf9SRui Paulo 	if (start == NULL)
110f05cddf9SRui Paulo 		return 1;
111f05cddf9SRui Paulo 
112f05cddf9SRui Paulo 	start++;
113f05cddf9SRui Paulo 	/*
114f05cddf9SRui Paulo 	 * Skip BSS added/removed events since they can be relatively frequent
115f05cddf9SRui Paulo 	 * and are likely of not much use for an interactive user.
116f05cddf9SRui Paulo 	 */
117f05cddf9SRui Paulo 	if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
118f05cddf9SRui Paulo 	    str_starts(start, WPA_EVENT_BSS_REMOVED))
119f05cddf9SRui Paulo 		return 0;
120f05cddf9SRui Paulo 
121f05cddf9SRui Paulo 	return 1;
122f05cddf9SRui Paulo }
123e28a4053SRui Paulo 
124e28a4053SRui Paulo 
wpa_cli_open_connection(const char * ifname,int attach)125e28a4053SRui Paulo static int wpa_cli_open_connection(const char *ifname, int attach)
12639beb93cSSam Leffler {
12739beb93cSSam Leffler #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
12839beb93cSSam Leffler 	ctrl_conn = wpa_ctrl_open(ifname);
129e28a4053SRui Paulo 	if (ctrl_conn == NULL)
130e28a4053SRui Paulo 		return -1;
131e28a4053SRui Paulo 
132e28a4053SRui Paulo 	if (attach && interactive)
133e28a4053SRui Paulo 		mon_conn = wpa_ctrl_open(ifname);
134e28a4053SRui Paulo 	else
135e28a4053SRui Paulo 		mon_conn = NULL;
13639beb93cSSam Leffler #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
137f05cddf9SRui Paulo 	char *cfile = NULL;
13839beb93cSSam Leffler 	int flen, res;
13939beb93cSSam Leffler 
14039beb93cSSam Leffler 	if (ifname == NULL)
141e28a4053SRui Paulo 		return -1;
14239beb93cSSam Leffler 
143f05cddf9SRui Paulo #ifdef ANDROID
144f05cddf9SRui Paulo 	if (access(ctrl_iface_dir, F_OK) < 0) {
145f05cddf9SRui Paulo 		cfile = os_strdup(ifname);
146f05cddf9SRui Paulo 		if (cfile == NULL)
147f05cddf9SRui Paulo 			return -1;
148f05cddf9SRui Paulo 	}
149f05cddf9SRui Paulo #endif /* ANDROID */
150f05cddf9SRui Paulo 
151325151a3SRui Paulo 	if (client_socket_dir && client_socket_dir[0] &&
152325151a3SRui Paulo 	    access(client_socket_dir, F_OK) < 0) {
153325151a3SRui Paulo 		perror(client_socket_dir);
154325151a3SRui Paulo 		os_free(cfile);
155325151a3SRui Paulo 		return -1;
156325151a3SRui Paulo 	}
157325151a3SRui Paulo 
158f05cddf9SRui Paulo 	if (cfile == NULL) {
15939beb93cSSam Leffler 		flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
16039beb93cSSam Leffler 		cfile = os_malloc(flen);
16139beb93cSSam Leffler 		if (cfile == NULL)
162f05cddf9SRui Paulo 			return -1;
163f05cddf9SRui Paulo 		res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
164f05cddf9SRui Paulo 				  ifname);
1655b9c547cSRui Paulo 		if (os_snprintf_error(flen, res)) {
16639beb93cSSam Leffler 			os_free(cfile);
167e28a4053SRui Paulo 			return -1;
16839beb93cSSam Leffler 		}
169f05cddf9SRui Paulo 	}
17039beb93cSSam Leffler 
171325151a3SRui Paulo 	ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir);
172e28a4053SRui Paulo 	if (ctrl_conn == NULL) {
17339beb93cSSam Leffler 		os_free(cfile);
174e28a4053SRui Paulo 		return -1;
175e28a4053SRui Paulo 	}
176e28a4053SRui Paulo 
177e28a4053SRui Paulo 	if (attach && interactive)
178325151a3SRui Paulo 		mon_conn = wpa_ctrl_open2(cfile, client_socket_dir);
179e28a4053SRui Paulo 	else
180e28a4053SRui Paulo 		mon_conn = NULL;
181e28a4053SRui Paulo 	os_free(cfile);
18239beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
183e28a4053SRui Paulo 
184e28a4053SRui Paulo 	if (mon_conn) {
185e28a4053SRui Paulo 		if (wpa_ctrl_attach(mon_conn) == 0) {
186e28a4053SRui Paulo 			wpa_cli_attached = 1;
187f05cddf9SRui Paulo 			if (interactive)
188f05cddf9SRui Paulo 				eloop_register_read_sock(
189f05cddf9SRui Paulo 					wpa_ctrl_get_fd(mon_conn),
190f05cddf9SRui Paulo 					wpa_cli_mon_receive, NULL, NULL);
191e28a4053SRui Paulo 		} else {
192e28a4053SRui Paulo 			printf("Warning: Failed to attach to "
193e28a4053SRui Paulo 			       "wpa_supplicant.\n");
194f05cddf9SRui Paulo 			wpa_cli_close_connection();
195e28a4053SRui Paulo 			return -1;
196e28a4053SRui Paulo 		}
197e28a4053SRui Paulo 	}
198e28a4053SRui Paulo 
199e28a4053SRui Paulo 	return 0;
20039beb93cSSam Leffler }
20139beb93cSSam Leffler 
20239beb93cSSam Leffler 
wpa_cli_close_connection(void)20339beb93cSSam Leffler static void wpa_cli_close_connection(void)
20439beb93cSSam Leffler {
20539beb93cSSam Leffler 	if (ctrl_conn == NULL)
20639beb93cSSam Leffler 		return;
20739beb93cSSam Leffler 
20839beb93cSSam Leffler 	if (wpa_cli_attached) {
209e28a4053SRui Paulo 		wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
21039beb93cSSam Leffler 		wpa_cli_attached = 0;
21139beb93cSSam Leffler 	}
21239beb93cSSam Leffler 	wpa_ctrl_close(ctrl_conn);
21339beb93cSSam Leffler 	ctrl_conn = NULL;
214e28a4053SRui Paulo 	if (mon_conn) {
215f05cddf9SRui Paulo 		eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
216e28a4053SRui Paulo 		wpa_ctrl_close(mon_conn);
217e28a4053SRui Paulo 		mon_conn = NULL;
218e28a4053SRui Paulo 	}
21939beb93cSSam Leffler }
22039beb93cSSam Leffler 
22139beb93cSSam Leffler 
wpa_cli_msg_cb(char * msg,size_t len)22239beb93cSSam Leffler static void wpa_cli_msg_cb(char *msg, size_t len)
22339beb93cSSam Leffler {
22439beb93cSSam Leffler 	printf("%s\n", msg);
22539beb93cSSam Leffler }
22639beb93cSSam Leffler 
22739beb93cSSam Leffler 
_wpa_ctrl_command(struct wpa_ctrl * ctrl,const char * cmd,int print)22885732ac8SCy Schubert static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print)
22939beb93cSSam Leffler {
2305b9c547cSRui Paulo 	char buf[4096];
23139beb93cSSam Leffler 	size_t len;
23239beb93cSSam Leffler 	int ret;
23339beb93cSSam Leffler 
23439beb93cSSam Leffler 	if (ctrl_conn == NULL) {
23539beb93cSSam Leffler 		printf("Not connected to wpa_supplicant - command dropped.\n");
23639beb93cSSam Leffler 		return -1;
23739beb93cSSam Leffler 	}
2385b9c547cSRui Paulo 	if (ifname_prefix) {
2395b9c547cSRui Paulo 		os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
2405b9c547cSRui Paulo 			    ifname_prefix, cmd);
2415b9c547cSRui Paulo 		buf[sizeof(buf) - 1] = '\0';
2425b9c547cSRui Paulo 		cmd = buf;
2435b9c547cSRui Paulo 	}
24439beb93cSSam Leffler 	len = sizeof(buf) - 1;
24539beb93cSSam Leffler 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
24639beb93cSSam Leffler 			       wpa_cli_msg_cb);
24739beb93cSSam Leffler 	if (ret == -2) {
24839beb93cSSam Leffler 		printf("'%s' command timed out.\n", cmd);
24939beb93cSSam Leffler 		return -2;
25039beb93cSSam Leffler 	} else if (ret < 0) {
25139beb93cSSam Leffler 		printf("'%s' command failed.\n", cmd);
25239beb93cSSam Leffler 		return -1;
25339beb93cSSam Leffler 	}
25439beb93cSSam Leffler 	if (print) {
25539beb93cSSam Leffler 		buf[len] = '\0';
25639beb93cSSam Leffler 		printf("%s", buf);
257f05cddf9SRui Paulo 		if (interactive && len > 0 && buf[len - 1] != '\n')
258f05cddf9SRui Paulo 			printf("\n");
25939beb93cSSam Leffler 	}
26039beb93cSSam Leffler 	return 0;
26139beb93cSSam Leffler }
26239beb93cSSam Leffler 
26339beb93cSSam Leffler 
wpa_ctrl_command(struct wpa_ctrl * ctrl,const char * cmd)26485732ac8SCy Schubert static int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd)
26539beb93cSSam Leffler {
26639beb93cSSam Leffler 	return _wpa_ctrl_command(ctrl, cmd, 1);
26739beb93cSSam Leffler }
26839beb93cSSam Leffler 
26939beb93cSSam Leffler 
wpa_cli_cmd(struct wpa_ctrl * ctrl,const char * cmd,int min_args,int argc,char * argv[])270f05cddf9SRui Paulo static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
271f05cddf9SRui Paulo 		       int argc, char *argv[])
272f05cddf9SRui Paulo {
2735b9c547cSRui Paulo 	char buf[4096];
274f05cddf9SRui Paulo 	if (argc < min_args) {
275f05cddf9SRui Paulo 		printf("Invalid %s command - at least %d argument%s "
276f05cddf9SRui Paulo 		       "required.\n", cmd, min_args,
277f05cddf9SRui Paulo 		       min_args > 1 ? "s are" : " is");
278f05cddf9SRui Paulo 		return -1;
279f05cddf9SRui Paulo 	}
280f05cddf9SRui Paulo 	if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
281f05cddf9SRui Paulo 		return -1;
282f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, buf);
283f05cddf9SRui Paulo }
284f05cddf9SRui Paulo 
285f05cddf9SRui Paulo 
wpa_cli_cmd_ifname(struct wpa_ctrl * ctrl,int argc,char * argv[])286f05cddf9SRui Paulo static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
287f05cddf9SRui Paulo {
288f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "IFNAME");
289f05cddf9SRui Paulo }
290f05cddf9SRui Paulo 
291f05cddf9SRui Paulo 
wpa_cli_cmd_status(struct wpa_ctrl * ctrl,int argc,char * argv[])29239beb93cSSam Leffler static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
29339beb93cSSam Leffler {
294f05cddf9SRui Paulo 	if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
295f05cddf9SRui Paulo 		return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
296f05cddf9SRui Paulo 	if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
297f05cddf9SRui Paulo 		return wpa_ctrl_command(ctrl, "STATUS-WPS");
2985b9c547cSRui Paulo 	if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
2995b9c547cSRui Paulo 		return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
300325151a3SRui Paulo #ifdef ANDROID
301325151a3SRui Paulo 	if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
302325151a3SRui Paulo 		return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
303325151a3SRui Paulo #endif /* ANDROID */
304f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "STATUS");
30539beb93cSSam Leffler }
30639beb93cSSam Leffler 
30739beb93cSSam Leffler 
wpa_cli_cmd_ping(struct wpa_ctrl * ctrl,int argc,char * argv[])30839beb93cSSam Leffler static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
30939beb93cSSam Leffler {
31039beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "PING");
31139beb93cSSam Leffler }
31239beb93cSSam Leffler 
31339beb93cSSam Leffler 
wpa_cli_cmd_relog(struct wpa_ctrl * ctrl,int argc,char * argv[])314f05cddf9SRui Paulo static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
315f05cddf9SRui Paulo {
316f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "RELOG");
317f05cddf9SRui Paulo }
318f05cddf9SRui Paulo 
319f05cddf9SRui Paulo 
wpa_cli_cmd_note(struct wpa_ctrl * ctrl,int argc,char * argv[])320f05cddf9SRui Paulo static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
321f05cddf9SRui Paulo {
322f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
323f05cddf9SRui Paulo }
324f05cddf9SRui Paulo 
325f05cddf9SRui Paulo 
wpa_cli_cmd_mib(struct wpa_ctrl * ctrl,int argc,char * argv[])32639beb93cSSam Leffler static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
32739beb93cSSam Leffler {
32839beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "MIB");
32939beb93cSSam Leffler }
33039beb93cSSam Leffler 
33139beb93cSSam Leffler 
wpa_cli_cmd_pmksa(struct wpa_ctrl * ctrl,int argc,char * argv[])33239beb93cSSam Leffler static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
33339beb93cSSam Leffler {
33439beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "PMKSA");
33539beb93cSSam Leffler }
33639beb93cSSam Leffler 
33739beb93cSSam Leffler 
wpa_cli_cmd_pmksa_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])3385b9c547cSRui Paulo static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
3395b9c547cSRui Paulo 				   char *argv[])
3405b9c547cSRui Paulo {
3415b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
3425b9c547cSRui Paulo }
3435b9c547cSRui Paulo 
3445b9c547cSRui Paulo 
34585732ac8SCy Schubert #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
34685732ac8SCy Schubert 
wpa_cli_cmd_pmksa_get(struct wpa_ctrl * ctrl,int argc,char * argv[])34785732ac8SCy Schubert static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
34885732ac8SCy Schubert {
34985732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv);
35085732ac8SCy Schubert }
35185732ac8SCy Schubert 
35285732ac8SCy Schubert 
wpa_cli_cmd_pmksa_add(struct wpa_ctrl * ctrl,int argc,char * argv[])35385732ac8SCy Schubert static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[])
35485732ac8SCy Schubert {
35585732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv);
35685732ac8SCy Schubert }
35785732ac8SCy Schubert 
35885732ac8SCy Schubert 
35985732ac8SCy Schubert #ifdef CONFIG_MESH
36085732ac8SCy Schubert 
wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl * ctrl,int argc,char * argv[])36185732ac8SCy Schubert static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc,
36285732ac8SCy Schubert 				      char *argv[])
36385732ac8SCy Schubert {
36485732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv);
36585732ac8SCy Schubert }
36685732ac8SCy Schubert 
36785732ac8SCy Schubert 
wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl * ctrl,int argc,char * argv[])36885732ac8SCy Schubert static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc,
36985732ac8SCy Schubert 				      char *argv[])
37085732ac8SCy Schubert {
37185732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv);
37285732ac8SCy Schubert }
37385732ac8SCy Schubert 
37485732ac8SCy Schubert #endif /* CONFIG_MESH */
37585732ac8SCy Schubert #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
37685732ac8SCy Schubert 
37785732ac8SCy Schubert 
wpa_cli_cmd_help(struct wpa_ctrl * ctrl,int argc,char * argv[])37839beb93cSSam Leffler static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
37939beb93cSSam Leffler {
380f05cddf9SRui Paulo 	print_help(argc > 0 ? argv[0] : NULL);
38139beb93cSSam Leffler 	return 0;
38239beb93cSSam Leffler }
38339beb93cSSam Leffler 
38439beb93cSSam Leffler 
wpa_cli_complete_help(const char * str,int pos)385f05cddf9SRui Paulo static char ** wpa_cli_complete_help(const char *str, int pos)
386f05cddf9SRui Paulo {
387f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
388f05cddf9SRui Paulo 	char **res = NULL;
389f05cddf9SRui Paulo 
390f05cddf9SRui Paulo 	switch (arg) {
391f05cddf9SRui Paulo 	case 1:
392f05cddf9SRui Paulo 		res = wpa_list_cmd_list();
393f05cddf9SRui Paulo 		break;
394f05cddf9SRui Paulo 	}
395f05cddf9SRui Paulo 
396f05cddf9SRui Paulo 	return res;
397f05cddf9SRui Paulo }
398f05cddf9SRui Paulo 
399f05cddf9SRui Paulo 
wpa_cli_cmd_license(struct wpa_ctrl * ctrl,int argc,char * argv[])40039beb93cSSam Leffler static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
40139beb93cSSam Leffler {
402780fb4a2SCy Schubert 	printf("%s\n\n%s\n", wpa_cli_version, cli_full_license);
40339beb93cSSam Leffler 	return 0;
40439beb93cSSam Leffler }
40539beb93cSSam Leffler 
40639beb93cSSam Leffler 
wpa_cli_cmd_quit(struct wpa_ctrl * ctrl,int argc,char * argv[])40739beb93cSSam Leffler static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
40839beb93cSSam Leffler {
40939beb93cSSam Leffler 	wpa_cli_quit = 1;
410f05cddf9SRui Paulo 	if (interactive)
411f05cddf9SRui Paulo 		eloop_terminate();
41239beb93cSSam Leffler 	return 0;
41339beb93cSSam Leffler }
41439beb93cSSam Leffler 
41539beb93cSSam Leffler 
wpa_cli_cmd_mlo_status(struct wpa_ctrl * ctrl,int argc,char * argv[])416*a90b9d01SCy Schubert static int wpa_cli_cmd_mlo_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
417*a90b9d01SCy Schubert {
418*a90b9d01SCy Schubert 	return wpa_ctrl_command(ctrl, "MLO_STATUS");
419*a90b9d01SCy Schubert }
420*a90b9d01SCy Schubert 
421*a90b9d01SCy Schubert 
wpa_cli_cmd_mlo_signal_poll(struct wpa_ctrl * ctrl,int argc,char * argv[])422*a90b9d01SCy Schubert static int wpa_cli_cmd_mlo_signal_poll(struct wpa_ctrl *ctrl, int argc, char *argv[])
423*a90b9d01SCy Schubert {
424*a90b9d01SCy Schubert 	return wpa_ctrl_command(ctrl, "MLO_SIGNAL_POLL");
425*a90b9d01SCy Schubert }
426*a90b9d01SCy Schubert 
427*a90b9d01SCy Schubert 
wpa_cli_cmd_set(struct wpa_ctrl * ctrl,int argc,char * argv[])42839beb93cSSam Leffler static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
42939beb93cSSam Leffler {
43039beb93cSSam Leffler 	char cmd[256];
43139beb93cSSam Leffler 	int res;
43239beb93cSSam Leffler 
4335b9c547cSRui Paulo 	if (argc == 1) {
434f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
4355b9c547cSRui Paulo 		if (os_snprintf_error(sizeof(cmd), res)) {
43639beb93cSSam Leffler 			printf("Too long SET command.\n");
43739beb93cSSam Leffler 			return -1;
43839beb93cSSam Leffler 		}
43939beb93cSSam Leffler 		return wpa_ctrl_command(ctrl, cmd);
44039beb93cSSam Leffler 	}
44139beb93cSSam Leffler 
4425b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
4435b9c547cSRui Paulo }
4445b9c547cSRui Paulo 
4455b9c547cSRui Paulo 
wpa_cli_complete_set(const char * str,int pos)4465b9c547cSRui Paulo static char ** wpa_cli_complete_set(const char *str, int pos)
4475b9c547cSRui Paulo {
4485b9c547cSRui Paulo 	int arg = get_cmd_arg_num(str, pos);
4495b9c547cSRui Paulo 	const char *fields[] = {
4505b9c547cSRui Paulo 		/* runtime values */
4515b9c547cSRui Paulo 		"EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
4525b9c547cSRui Paulo 		"EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
4535b9c547cSRui Paulo 		"dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
4545b9c547cSRui Paulo 		"wps_fragment_size", "wps_version_number", "ampdu",
4555b9c547cSRui Paulo 		"tdls_testing", "tdls_disabled", "pno", "radio_disabled",
4565b9c547cSRui Paulo 		"uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
4575b9c547cSRui Paulo 		"no_keep_alive",
4585b9c547cSRui Paulo 		/* global configuration parameters */
459325151a3SRui Paulo #ifdef CONFIG_CTRL_IFACE
460325151a3SRui Paulo 		"ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
461325151a3SRui Paulo #endif /* CONFIG_CTRL_IFACE */
462325151a3SRui Paulo 		"eapol_version", "ap_scan", "bgscan",
463325151a3SRui Paulo #ifdef CONFIG_MESH
464325151a3SRui Paulo 		"user_mpm", "max_peer_links", "mesh_max_inactivity",
465325151a3SRui Paulo 		"dot11RSNASAERetransPeriod",
466325151a3SRui Paulo #endif /* CONFIG_MESH */
467325151a3SRui Paulo 		"disable_scan_offload", "fast_reauth", "opensc_engine_path",
468325151a3SRui Paulo 		"pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
469325151a3SRui Paulo 		"pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
470325151a3SRui Paulo 		"dot11RSNAConfigPMKLifetime",
4715b9c547cSRui Paulo 		"dot11RSNAConfigPMKReauthThreshold",
4725b9c547cSRui Paulo 		"dot11RSNAConfigSATimeout",
473325151a3SRui Paulo #ifndef CONFIG_NO_CONFIG_WRITE
474325151a3SRui Paulo 		"update_config",
475325151a3SRui Paulo #endif /* CONFIG_NO_CONFIG_WRITE */
476325151a3SRui Paulo 		"load_dynamic_eap",
477325151a3SRui Paulo #ifdef CONFIG_WPS
478325151a3SRui Paulo 		"uuid", "device_name", "manufacturer", "model_name",
479325151a3SRui Paulo 		"model_number", "serial_number", "device_type", "os_version",
480325151a3SRui Paulo 		"config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
481325151a3SRui Paulo #endif /* CONFIG_WPS */
482325151a3SRui Paulo #ifdef CONFIG_P2P
483325151a3SRui Paulo 		"sec_device_type",
4845b9c547cSRui Paulo 		"p2p_listen_reg_class", "p2p_listen_channel",
485325151a3SRui Paulo 		"p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
486325151a3SRui Paulo 		"p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
487325151a3SRui Paulo 		"p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
488325151a3SRui Paulo 		"p2p_no_go_freq", "p2p_add_cli_chan",
489325151a3SRui Paulo 		"p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
490325151a3SRui Paulo 		"p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
491325151a3SRui Paulo 		"p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
492c1d255d3SCy Schubert 		"ip_addr_start", "ip_addr_end", "p2p_go_edmg",
493325151a3SRui Paulo #endif /* CONFIG_P2P */
494325151a3SRui Paulo 		"country", "bss_max_count", "bss_expiration_age",
495325151a3SRui Paulo 		"bss_expiration_scan_count", "filter_ssids", "filter_rssi",
49685732ac8SCy Schubert 		"max_num_sta", "disassoc_low_ack", "ap_isolate",
497325151a3SRui Paulo #ifdef CONFIG_HS20
498325151a3SRui Paulo 		"hs20",
499325151a3SRui Paulo #endif /* CONFIG_HS20 */
500325151a3SRui Paulo 		"interworking", "hessid", "access_network_type", "pbc_in_m1",
50185732ac8SCy Schubert 		"go_interworking", "go_access_network_type", "go_internet",
50285732ac8SCy Schubert 		"go_venue_group", "go_venue_type",
503325151a3SRui Paulo 		"autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
504325151a3SRui Paulo 		"wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
5055b9c547cSRui Paulo 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
506*a90b9d01SCy Schubert 		"sae_check_mfp", "sae_groups", "dtim_period", "beacon_int",
507325151a3SRui Paulo 		"ap_vendor_elements", "ignore_old_scan_res", "freq_list",
508c1d255d3SCy Schubert 		"scan_cur_freq", "scan_res_valid_for_connect",
509c1d255d3SCy Schubert 		"sched_scan_interval",
510325151a3SRui Paulo 		"tdls_external_control", "osu_dir", "wowlan_triggers",
511325151a3SRui Paulo 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
512325151a3SRui Paulo 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
513780fb4a2SCy Schubert 		"reassoc_same_bss_optim", "wps_priority",
5144b72b91aSCy Schubert 		"ap_assocresp_elements",
515780fb4a2SCy Schubert #ifdef CONFIG_TESTING_OPTIONS
516780fb4a2SCy Schubert 		"ignore_auth_resp",
517780fb4a2SCy Schubert #endif /* CONFIG_TESTING_OPTIONS */
51885732ac8SCy Schubert 		"relative_rssi", "relative_band_adjust",
519c1d255d3SCy Schubert 		"extended_key_id",
5205b9c547cSRui Paulo 	};
5215b9c547cSRui Paulo 	int i, num_fields = ARRAY_SIZE(fields);
5225b9c547cSRui Paulo 
5235b9c547cSRui Paulo 	if (arg == 1) {
5245b9c547cSRui Paulo 		char **res = os_calloc(num_fields + 1, sizeof(char *));
5255b9c547cSRui Paulo 		if (res == NULL)
5265b9c547cSRui Paulo 			return NULL;
5275b9c547cSRui Paulo 		for (i = 0; i < num_fields; i++) {
5285b9c547cSRui Paulo 			res[i] = os_strdup(fields[i]);
5295b9c547cSRui Paulo 			if (res[i] == NULL)
5305b9c547cSRui Paulo 				return res;
5315b9c547cSRui Paulo 		}
5325b9c547cSRui Paulo 		return res;
5335b9c547cSRui Paulo 	}
5345b9c547cSRui Paulo 
5355b9c547cSRui Paulo 	if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
5365b9c547cSRui Paulo 		return cli_txt_list_array(&bsses);
5375b9c547cSRui Paulo 
5385b9c547cSRui Paulo 	return NULL;
5395b9c547cSRui Paulo }
5405b9c547cSRui Paulo 
wpa_cli_cmd_dump(struct wpa_ctrl * ctrl,int argc,char * argv[])5415b9c547cSRui Paulo static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
5425b9c547cSRui Paulo {
5435b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "DUMP");
5445b9c547cSRui Paulo }
5455b9c547cSRui Paulo 
54639beb93cSSam Leffler 
wpa_cli_cmd_driver_flags(struct wpa_ctrl * ctrl,int argc,char * argv[])547780fb4a2SCy Schubert static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
548780fb4a2SCy Schubert 				    char *argv[])
549780fb4a2SCy Schubert {
550780fb4a2SCy Schubert 	return wpa_ctrl_command(ctrl, "DRIVER_FLAGS");
551780fb4a2SCy Schubert }
552780fb4a2SCy Schubert 
553780fb4a2SCy Schubert 
wpa_cli_cmd_driver_flags2(struct wpa_ctrl * ctrl,int argc,char * argv[])554*a90b9d01SCy Schubert static int wpa_cli_cmd_driver_flags2(struct wpa_ctrl *ctrl, int argc,
555*a90b9d01SCy Schubert 				     char *argv[])
556*a90b9d01SCy Schubert {
557*a90b9d01SCy Schubert 	return wpa_ctrl_command(ctrl, "DRIVER_FLAGS2");
558*a90b9d01SCy Schubert }
559*a90b9d01SCy Schubert 
560*a90b9d01SCy Schubert 
wpa_cli_cmd_get(struct wpa_ctrl * ctrl,int argc,char * argv[])561f05cddf9SRui Paulo static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
562f05cddf9SRui Paulo {
563f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
564f05cddf9SRui Paulo }
565f05cddf9SRui Paulo 
566f05cddf9SRui Paulo 
wpa_cli_complete_get(const char * str,int pos)567325151a3SRui Paulo static char ** wpa_cli_complete_get(const char *str, int pos)
568325151a3SRui Paulo {
569325151a3SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
570325151a3SRui Paulo 	const char *fields[] = {
571325151a3SRui Paulo #ifdef CONFIG_CTRL_IFACE
572325151a3SRui Paulo 		"ctrl_interface", "ctrl_interface_group",
573325151a3SRui Paulo #endif /* CONFIG_CTRL_IFACE */
574325151a3SRui Paulo 		"eapol_version", "ap_scan",
575325151a3SRui Paulo #ifdef CONFIG_MESH
576325151a3SRui Paulo 		"user_mpm", "max_peer_links", "mesh_max_inactivity",
577325151a3SRui Paulo #endif /* CONFIG_MESH */
578325151a3SRui Paulo 		"disable_scan_offload", "fast_reauth", "opensc_engine_path",
579325151a3SRui Paulo 		"pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
580325151a3SRui Paulo 		"pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
581325151a3SRui Paulo 		"dot11RSNAConfigPMKLifetime",
582325151a3SRui Paulo 		"dot11RSNAConfigPMKReauthThreshold",
583325151a3SRui Paulo 		"dot11RSNAConfigSATimeout",
584325151a3SRui Paulo #ifndef CONFIG_NO_CONFIG_WRITE
585325151a3SRui Paulo 		"update_config",
586325151a3SRui Paulo #endif /* CONFIG_NO_CONFIG_WRITE */
587325151a3SRui Paulo #ifdef CONFIG_WPS
588325151a3SRui Paulo 		"device_name", "manufacturer", "model_name", "model_number",
589325151a3SRui Paulo 		"serial_number", "config_methods", "wps_cred_processing",
590325151a3SRui Paulo #endif /* CONFIG_WPS */
591325151a3SRui Paulo #ifdef CONFIG_P2P
592325151a3SRui Paulo 		"p2p_listen_reg_class", "p2p_listen_channel",
593325151a3SRui Paulo 		"p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
594325151a3SRui Paulo 		"p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
595325151a3SRui Paulo 		"p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
596325151a3SRui Paulo 		"p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
597325151a3SRui Paulo 		"p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
598325151a3SRui Paulo 		"p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
599325151a3SRui Paulo 		"ip_addr_start", "ip_addr_end",
600325151a3SRui Paulo #endif /* CONFIG_P2P */
601325151a3SRui Paulo 		"bss_max_count", "bss_expiration_age",
602325151a3SRui Paulo 		"bss_expiration_scan_count", "filter_ssids", "filter_rssi",
60385732ac8SCy Schubert 		"max_num_sta", "disassoc_low_ack", "ap_isolate",
604325151a3SRui Paulo #ifdef CONFIG_HS20
605325151a3SRui Paulo 		"hs20",
606325151a3SRui Paulo #endif /* CONFIG_HS20 */
607325151a3SRui Paulo 		"interworking", "access_network_type", "pbc_in_m1", "autoscan",
60885732ac8SCy Schubert 		"go_interworking", "go_access_network_type", "go_internet",
60985732ac8SCy Schubert 		"go_venue_group", "go_venue_type",
610325151a3SRui Paulo 		"wps_nfc_dev_pw_id", "ext_password_backend",
611325151a3SRui Paulo 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
612*a90b9d01SCy Schubert 		"sae_check_mfp",
613325151a3SRui Paulo 		"dtim_period", "beacon_int", "ignore_old_scan_res",
614c1d255d3SCy Schubert 		"scan_cur_freq", "scan_res_valid_for_connect",
615c1d255d3SCy Schubert 		"sched_scan_interval",
61685732ac8SCy Schubert 		"sched_scan_start_delay",
617325151a3SRui Paulo 		"tdls_external_control", "osu_dir", "wowlan_triggers",
618325151a3SRui Paulo 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
619325151a3SRui Paulo 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
620c1d255d3SCy Schubert 		"reassoc_same_bss_optim", "extended_key_id"
621325151a3SRui Paulo 	};
622325151a3SRui Paulo 	int i, num_fields = ARRAY_SIZE(fields);
623325151a3SRui Paulo 
624325151a3SRui Paulo 	if (arg == 1) {
625325151a3SRui Paulo 		char **res = os_calloc(num_fields + 1, sizeof(char *));
626325151a3SRui Paulo 		if (res == NULL)
627325151a3SRui Paulo 			return NULL;
628325151a3SRui Paulo 		for (i = 0; i < num_fields; i++) {
629325151a3SRui Paulo 			res[i] = os_strdup(fields[i]);
630325151a3SRui Paulo 			if (res[i] == NULL)
631325151a3SRui Paulo 				return res;
632325151a3SRui Paulo 		}
633325151a3SRui Paulo 		return res;
634325151a3SRui Paulo 	}
635325151a3SRui Paulo 
636325151a3SRui Paulo 	return NULL;
637325151a3SRui Paulo }
638325151a3SRui Paulo 
639325151a3SRui Paulo 
wpa_cli_cmd_logoff(struct wpa_ctrl * ctrl,int argc,char * argv[])64039beb93cSSam Leffler static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
64139beb93cSSam Leffler {
64239beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "LOGOFF");
64339beb93cSSam Leffler }
64439beb93cSSam Leffler 
64539beb93cSSam Leffler 
wpa_cli_cmd_logon(struct wpa_ctrl * ctrl,int argc,char * argv[])64639beb93cSSam Leffler static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
64739beb93cSSam Leffler {
64839beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "LOGON");
64939beb93cSSam Leffler }
65039beb93cSSam Leffler 
65139beb93cSSam Leffler 
wpa_cli_cmd_reassociate(struct wpa_ctrl * ctrl,int argc,char * argv[])65239beb93cSSam Leffler static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
65339beb93cSSam Leffler 				   char *argv[])
65439beb93cSSam Leffler {
65539beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "REASSOCIATE");
65639beb93cSSam Leffler }
65739beb93cSSam Leffler 
65839beb93cSSam Leffler 
wpa_cli_cmd_reattach(struct wpa_ctrl * ctrl,int argc,char * argv[])6595b9c547cSRui Paulo static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
6605b9c547cSRui Paulo {
6615b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "REATTACH");
6625b9c547cSRui Paulo }
6635b9c547cSRui Paulo 
6645b9c547cSRui Paulo 
wpa_cli_cmd_preauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])66539beb93cSSam Leffler static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
66639beb93cSSam Leffler 				       char *argv[])
66739beb93cSSam Leffler {
668f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
66939beb93cSSam Leffler }
67039beb93cSSam Leffler 
67139beb93cSSam Leffler 
wpa_cli_cmd_ap_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])67239beb93cSSam Leffler static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
67339beb93cSSam Leffler {
674f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
675f05cddf9SRui Paulo }
676f05cddf9SRui Paulo 
677f05cddf9SRui Paulo 
wpa_cli_cmd_scan_interval(struct wpa_ctrl * ctrl,int argc,char * argv[])678f05cddf9SRui Paulo static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
679f05cddf9SRui Paulo 				     char *argv[])
680f05cddf9SRui Paulo {
681f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
682f05cddf9SRui Paulo }
683f05cddf9SRui Paulo 
684f05cddf9SRui Paulo 
wpa_cli_cmd_bss_expire_age(struct wpa_ctrl * ctrl,int argc,char * argv[])685f05cddf9SRui Paulo static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
686f05cddf9SRui Paulo 				      char *argv[])
687f05cddf9SRui Paulo {
688f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
689f05cddf9SRui Paulo }
690f05cddf9SRui Paulo 
691f05cddf9SRui Paulo 
wpa_cli_cmd_bss_expire_count(struct wpa_ctrl * ctrl,int argc,char * argv[])692f05cddf9SRui Paulo static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
693f05cddf9SRui Paulo 				        char *argv[])
694f05cddf9SRui Paulo {
695f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
696f05cddf9SRui Paulo }
697f05cddf9SRui Paulo 
698f05cddf9SRui Paulo 
wpa_cli_cmd_bss_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])699f05cddf9SRui Paulo static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
700f05cddf9SRui Paulo {
70139beb93cSSam Leffler 	char cmd[256];
70239beb93cSSam Leffler 	int res;
70339beb93cSSam Leffler 
704f05cddf9SRui Paulo 	if (argc < 1)
705f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
706f05cddf9SRui Paulo 	else
707f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
7085b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res)) {
709f05cddf9SRui Paulo 		printf("Too long BSS_FLUSH command.\n");
71039beb93cSSam Leffler 		return -1;
71139beb93cSSam Leffler 	}
71239beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
71339beb93cSSam Leffler }
71439beb93cSSam Leffler 
71539beb93cSSam Leffler 
wpa_cli_cmd_ft_ds(struct wpa_ctrl * ctrl,int argc,char * argv[])71639beb93cSSam Leffler static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
71739beb93cSSam Leffler {
718f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
71939beb93cSSam Leffler }
72039beb93cSSam Leffler 
72139beb93cSSam Leffler 
wpa_cli_cmd_wps_pbc(struct wpa_ctrl * ctrl,int argc,char * argv[])72239beb93cSSam Leffler static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
72339beb93cSSam Leffler {
724f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
72539beb93cSSam Leffler }
72639beb93cSSam Leffler 
72739beb93cSSam Leffler 
wpa_cli_cmd_wps_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])72839beb93cSSam Leffler static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
72939beb93cSSam Leffler {
73039beb93cSSam Leffler 	if (argc == 0) {
73139beb93cSSam Leffler 		printf("Invalid WPS_PIN command: need one or two arguments:\n"
73239beb93cSSam Leffler 		       "- BSSID: use 'any' to select any\n"
73339beb93cSSam Leffler 		       "- PIN: optional, used only with devices that have no "
73439beb93cSSam Leffler 		       "display\n");
73539beb93cSSam Leffler 		return -1;
73639beb93cSSam Leffler 	}
73739beb93cSSam Leffler 
738f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
73939beb93cSSam Leffler }
74039beb93cSSam Leffler 
74139beb93cSSam Leffler 
wpa_cli_cmd_wps_check_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])742f05cddf9SRui Paulo static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
743f05cddf9SRui Paulo 				     char *argv[])
744e28a4053SRui Paulo {
745f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
746f05cddf9SRui Paulo }
747e28a4053SRui Paulo 
748f05cddf9SRui Paulo 
wpa_cli_cmd_wps_cancel(struct wpa_ctrl * ctrl,int argc,char * argv[])749f05cddf9SRui Paulo static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
750f05cddf9SRui Paulo 				  char *argv[])
751f05cddf9SRui Paulo {
752f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "WPS_CANCEL");
753f05cddf9SRui Paulo }
754f05cddf9SRui Paulo 
755f05cddf9SRui Paulo 
756f05cddf9SRui Paulo #ifdef CONFIG_WPS_NFC
757f05cddf9SRui Paulo 
wpa_cli_cmd_wps_nfc(struct wpa_ctrl * ctrl,int argc,char * argv[])758f05cddf9SRui Paulo static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
759f05cddf9SRui Paulo {
760f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
761f05cddf9SRui Paulo }
762f05cddf9SRui Paulo 
763f05cddf9SRui Paulo 
wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl * ctrl,int argc,char * argv[])7645b9c547cSRui Paulo static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
7655b9c547cSRui Paulo 					    char *argv[])
7665b9c547cSRui Paulo {
7675b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
7685b9c547cSRui Paulo }
7695b9c547cSRui Paulo 
7705b9c547cSRui Paulo 
wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl * ctrl,int argc,char * argv[])771f05cddf9SRui Paulo static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
772f05cddf9SRui Paulo 				     char *argv[])
773f05cddf9SRui Paulo {
774f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
775f05cddf9SRui Paulo }
776f05cddf9SRui Paulo 
777f05cddf9SRui Paulo 
wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl * ctrl,int argc,char * argv[])778f05cddf9SRui Paulo static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
779f05cddf9SRui Paulo 					char *argv[])
780f05cddf9SRui Paulo {
781f05cddf9SRui Paulo 	int ret;
782f05cddf9SRui Paulo 	char *buf;
783f05cddf9SRui Paulo 	size_t buflen;
784f05cddf9SRui Paulo 
785f05cddf9SRui Paulo 	if (argc != 1) {
786f05cddf9SRui Paulo 		printf("Invalid 'wps_nfc_tag_read' command - one argument "
787f05cddf9SRui Paulo 		       "is required.\n");
788e28a4053SRui Paulo 		return -1;
789e28a4053SRui Paulo 	}
790e28a4053SRui Paulo 
791f05cddf9SRui Paulo 	buflen = 18 + os_strlen(argv[0]);
792f05cddf9SRui Paulo 	buf = os_malloc(buflen);
793f05cddf9SRui Paulo 	if (buf == NULL)
794f05cddf9SRui Paulo 		return -1;
795f05cddf9SRui Paulo 	os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
796f05cddf9SRui Paulo 
797f05cddf9SRui Paulo 	ret = wpa_ctrl_command(ctrl, buf);
798f05cddf9SRui Paulo 	os_free(buf);
799f05cddf9SRui Paulo 
800f05cddf9SRui Paulo 	return ret;
801f05cddf9SRui Paulo }
802f05cddf9SRui Paulo 
803f05cddf9SRui Paulo 
wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl * ctrl,int argc,char * argv[])804f05cddf9SRui Paulo static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
805f05cddf9SRui Paulo 					    char *argv[])
806f05cddf9SRui Paulo {
807f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
808f05cddf9SRui Paulo }
809f05cddf9SRui Paulo 
810f05cddf9SRui Paulo 
wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl * ctrl,int argc,char * argv[])811f05cddf9SRui Paulo static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
812f05cddf9SRui Paulo 					    char *argv[])
813f05cddf9SRui Paulo {
814f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
815f05cddf9SRui Paulo }
816f05cddf9SRui Paulo 
817f05cddf9SRui Paulo 
wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl * ctrl,int argc,char * argv[])8185b9c547cSRui Paulo static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
819f05cddf9SRui Paulo 					   char *argv[])
820f05cddf9SRui Paulo {
8215b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
822f05cddf9SRui Paulo }
823f05cddf9SRui Paulo 
824f05cddf9SRui Paulo #endif /* CONFIG_WPS_NFC */
825e28a4053SRui Paulo 
826e28a4053SRui Paulo 
wpa_cli_cmd_wps_reg(struct wpa_ctrl * ctrl,int argc,char * argv[])82739beb93cSSam Leffler static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
82839beb93cSSam Leffler {
82939beb93cSSam Leffler 	char cmd[256];
83039beb93cSSam Leffler 	int res;
83139beb93cSSam Leffler 
832e28a4053SRui Paulo 	if (argc == 2)
833e28a4053SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
834e28a4053SRui Paulo 				  argv[0], argv[1]);
835f05cddf9SRui Paulo 	else if (argc == 5 || argc == 6) {
836325151a3SRui Paulo 		char ssid_hex[2 * SSID_MAX_LEN + 1];
837e28a4053SRui Paulo 		char key_hex[2 * 64 + 1];
838e28a4053SRui Paulo 		int i;
839e28a4053SRui Paulo 
840e28a4053SRui Paulo 		ssid_hex[0] = '\0';
841325151a3SRui Paulo 		for (i = 0; i < SSID_MAX_LEN; i++) {
842e28a4053SRui Paulo 			if (argv[2][i] == '\0')
843e28a4053SRui Paulo 				break;
844e28a4053SRui Paulo 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
845e28a4053SRui Paulo 		}
846e28a4053SRui Paulo 
847e28a4053SRui Paulo 		key_hex[0] = '\0';
848f05cddf9SRui Paulo 		if (argc == 6) {
849e28a4053SRui Paulo 			for (i = 0; i < 64; i++) {
850e28a4053SRui Paulo 				if (argv[5][i] == '\0')
851e28a4053SRui Paulo 					break;
852f05cddf9SRui Paulo 				os_snprintf(&key_hex[i * 2], 3, "%02x",
853f05cddf9SRui Paulo 					    argv[5][i]);
854f05cddf9SRui Paulo 			}
855e28a4053SRui Paulo 		}
856e28a4053SRui Paulo 
857e28a4053SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd),
858e28a4053SRui Paulo 				  "WPS_REG %s %s %s %s %s %s",
859e28a4053SRui Paulo 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
860e28a4053SRui Paulo 				  key_hex);
861e28a4053SRui Paulo 	} else {
86239beb93cSSam Leffler 		printf("Invalid WPS_REG command: need two arguments:\n"
863f05cddf9SRui Paulo 		       "- BSSID of the target AP\n"
86439beb93cSSam Leffler 		       "- AP PIN\n");
865e28a4053SRui Paulo 		printf("Alternatively, six arguments can be used to "
866e28a4053SRui Paulo 		       "reconfigure the AP:\n"
867f05cddf9SRui Paulo 		       "- BSSID of the target AP\n"
868e28a4053SRui Paulo 		       "- AP PIN\n"
869e28a4053SRui Paulo 		       "- new SSID\n"
870e28a4053SRui Paulo 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
871e28a4053SRui Paulo 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
872e28a4053SRui Paulo 		       "- new key\n");
87339beb93cSSam Leffler 		return -1;
87439beb93cSSam Leffler 	}
87539beb93cSSam Leffler 
8765b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res)) {
87739beb93cSSam Leffler 		printf("Too long WPS_REG command.\n");
87839beb93cSSam Leffler 		return -1;
87939beb93cSSam Leffler 	}
88039beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
88139beb93cSSam Leffler }
88239beb93cSSam Leffler 
88339beb93cSSam Leffler 
wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])884f05cddf9SRui Paulo static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
885f05cddf9SRui Paulo 				  char *argv[])
886f05cddf9SRui Paulo {
887f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
888f05cddf9SRui Paulo }
889f05cddf9SRui Paulo 
890f05cddf9SRui Paulo 
wpa_cli_cmd_wps_er_start(struct wpa_ctrl * ctrl,int argc,char * argv[])891e28a4053SRui Paulo static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
892e28a4053SRui Paulo 				    char *argv[])
893e28a4053SRui Paulo {
894f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
895e28a4053SRui Paulo }
896e28a4053SRui Paulo 
897e28a4053SRui Paulo 
wpa_cli_cmd_wps_er_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])898e28a4053SRui Paulo static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
899e28a4053SRui Paulo 				   char *argv[])
900e28a4053SRui Paulo {
901e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
902e28a4053SRui Paulo 
903e28a4053SRui Paulo }
904e28a4053SRui Paulo 
905e28a4053SRui Paulo 
wpa_cli_cmd_wps_er_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])906e28a4053SRui Paulo static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
907e28a4053SRui Paulo 				  char *argv[])
908e28a4053SRui Paulo {
909f05cddf9SRui Paulo 	if (argc < 2) {
910f05cddf9SRui Paulo 		printf("Invalid WPS_ER_PIN command: need at least two "
911f05cddf9SRui Paulo 		       "arguments:\n"
912e28a4053SRui Paulo 		       "- UUID: use 'any' to select any\n"
913f05cddf9SRui Paulo 		       "- PIN: Enrollee PIN\n"
914f05cddf9SRui Paulo 		       "optional: - Enrollee MAC address\n");
915e28a4053SRui Paulo 		return -1;
916e28a4053SRui Paulo 	}
917e28a4053SRui Paulo 
918f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
919e28a4053SRui Paulo }
920e28a4053SRui Paulo 
921e28a4053SRui Paulo 
wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl * ctrl,int argc,char * argv[])922e28a4053SRui Paulo static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
923e28a4053SRui Paulo 				  char *argv[])
924e28a4053SRui Paulo {
925f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
926e28a4053SRui Paulo }
927e28a4053SRui Paulo 
928e28a4053SRui Paulo 
wpa_cli_cmd_wps_er_learn(struct wpa_ctrl * ctrl,int argc,char * argv[])929e28a4053SRui Paulo static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
930e28a4053SRui Paulo 				    char *argv[])
931e28a4053SRui Paulo {
932e28a4053SRui Paulo 	if (argc != 2) {
933e28a4053SRui Paulo 		printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
934e28a4053SRui Paulo 		       "- UUID: specify which AP to use\n"
935e28a4053SRui Paulo 		       "- PIN: AP PIN\n");
936e28a4053SRui Paulo 		return -1;
937e28a4053SRui Paulo 	}
938e28a4053SRui Paulo 
939f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
940f05cddf9SRui Paulo }
941f05cddf9SRui Paulo 
942f05cddf9SRui Paulo 
wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl * ctrl,int argc,char * argv[])943f05cddf9SRui Paulo static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
944f05cddf9SRui Paulo 					 char *argv[])
945f05cddf9SRui Paulo {
946f05cddf9SRui Paulo 	if (argc != 2) {
947f05cddf9SRui Paulo 		printf("Invalid WPS_ER_SET_CONFIG command: need two "
948f05cddf9SRui Paulo 		       "arguments:\n"
949f05cddf9SRui Paulo 		       "- UUID: specify which AP to use\n"
950f05cddf9SRui Paulo 		       "- Network configuration id\n");
951e28a4053SRui Paulo 		return -1;
952e28a4053SRui Paulo 	}
953f05cddf9SRui Paulo 
954f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
955e28a4053SRui Paulo }
956e28a4053SRui Paulo 
957e28a4053SRui Paulo 
wpa_cli_cmd_wps_er_config(struct wpa_ctrl * ctrl,int argc,char * argv[])958f05cddf9SRui Paulo static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
959f05cddf9SRui Paulo 				     char *argv[])
960e28a4053SRui Paulo {
961e28a4053SRui Paulo 	char cmd[256];
962e28a4053SRui Paulo 	int res;
963e28a4053SRui Paulo 
964f05cddf9SRui Paulo 	if (argc == 5 || argc == 6) {
965325151a3SRui Paulo 		char ssid_hex[2 * SSID_MAX_LEN + 1];
966f05cddf9SRui Paulo 		char key_hex[2 * 64 + 1];
967f05cddf9SRui Paulo 		int i;
968f05cddf9SRui Paulo 
969f05cddf9SRui Paulo 		ssid_hex[0] = '\0';
970325151a3SRui Paulo 		for (i = 0; i < SSID_MAX_LEN; i++) {
971f05cddf9SRui Paulo 			if (argv[2][i] == '\0')
972f05cddf9SRui Paulo 				break;
973f05cddf9SRui Paulo 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
974f05cddf9SRui Paulo 		}
975f05cddf9SRui Paulo 
976f05cddf9SRui Paulo 		key_hex[0] = '\0';
977f05cddf9SRui Paulo 		if (argc == 6) {
978f05cddf9SRui Paulo 			for (i = 0; i < 64; i++) {
979f05cddf9SRui Paulo 				if (argv[5][i] == '\0')
980f05cddf9SRui Paulo 					break;
981f05cddf9SRui Paulo 				os_snprintf(&key_hex[i * 2], 3, "%02x",
982f05cddf9SRui Paulo 					    argv[5][i]);
983f05cddf9SRui Paulo 			}
984f05cddf9SRui Paulo 		}
985f05cddf9SRui Paulo 
986f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd),
987f05cddf9SRui Paulo 				  "WPS_ER_CONFIG %s %s %s %s %s %s",
988f05cddf9SRui Paulo 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
989f05cddf9SRui Paulo 				  key_hex);
990f05cddf9SRui Paulo 	} else {
991f05cddf9SRui Paulo 		printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
992f05cddf9SRui Paulo 		       "- AP UUID\n"
993f05cddf9SRui Paulo 		       "- AP PIN\n"
994f05cddf9SRui Paulo 		       "- new SSID\n"
995f05cddf9SRui Paulo 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
996f05cddf9SRui Paulo 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
997f05cddf9SRui Paulo 		       "- new key\n");
998e28a4053SRui Paulo 		return -1;
999e28a4053SRui Paulo 	}
1000e28a4053SRui Paulo 
10015b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res)) {
1002f05cddf9SRui Paulo 		printf("Too long WPS_ER_CONFIG command.\n");
1003e28a4053SRui Paulo 		return -1;
1004e28a4053SRui Paulo 	}
1005e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
1006e28a4053SRui Paulo }
1007e28a4053SRui Paulo 
1008e28a4053SRui Paulo 
1009f05cddf9SRui Paulo #ifdef CONFIG_WPS_NFC
wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl * ctrl,int argc,char * argv[])1010f05cddf9SRui Paulo static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1011f05cddf9SRui Paulo 					       char *argv[])
1012f05cddf9SRui Paulo {
1013f05cddf9SRui Paulo 	if (argc != 2) {
1014f05cddf9SRui Paulo 		printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1015f05cddf9SRui Paulo 		       "arguments:\n"
1016f05cddf9SRui Paulo 		       "- WPS/NDEF: token format\n"
1017f05cddf9SRui Paulo 		       "- UUID: specify which AP to use\n");
1018f05cddf9SRui Paulo 		return -1;
1019f05cddf9SRui Paulo 	}
1020f05cddf9SRui Paulo 
1021f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1022f05cddf9SRui Paulo }
1023f05cddf9SRui Paulo #endif /* CONFIG_WPS_NFC */
1024f05cddf9SRui Paulo 
1025f05cddf9SRui Paulo 
wpa_cli_cmd_ibss_rsn(struct wpa_ctrl * ctrl,int argc,char * argv[])1026f05cddf9SRui Paulo static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1027f05cddf9SRui Paulo {
1028f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1029f05cddf9SRui Paulo }
1030f05cddf9SRui Paulo 
1031f05cddf9SRui Paulo 
wpa_cli_cmd_level(struct wpa_ctrl * ctrl,int argc,char * argv[])103239beb93cSSam Leffler static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
103339beb93cSSam Leffler {
1034f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
103539beb93cSSam Leffler }
103639beb93cSSam Leffler 
103739beb93cSSam Leffler 
wpa_cli_cmd_identity(struct wpa_ctrl * ctrl,int argc,char * argv[])103839beb93cSSam Leffler static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
103939beb93cSSam Leffler {
104039beb93cSSam Leffler 	char cmd[256], *pos, *end;
104139beb93cSSam Leffler 	int i, ret;
104239beb93cSSam Leffler 
104339beb93cSSam Leffler 	if (argc < 2) {
104439beb93cSSam Leffler 		printf("Invalid IDENTITY command: needs two arguments "
104539beb93cSSam Leffler 		       "(network id and identity)\n");
104639beb93cSSam Leffler 		return -1;
104739beb93cSSam Leffler 	}
104839beb93cSSam Leffler 
104939beb93cSSam Leffler 	end = cmd + sizeof(cmd);
105039beb93cSSam Leffler 	pos = cmd;
105139beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
105239beb93cSSam Leffler 			  argv[0], argv[1]);
10535b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
105439beb93cSSam Leffler 		printf("Too long IDENTITY command.\n");
105539beb93cSSam Leffler 		return -1;
105639beb93cSSam Leffler 	}
105739beb93cSSam Leffler 	pos += ret;
105839beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
105939beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
10605b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
106139beb93cSSam Leffler 			printf("Too long IDENTITY command.\n");
106239beb93cSSam Leffler 			return -1;
106339beb93cSSam Leffler 		}
106439beb93cSSam Leffler 		pos += ret;
106539beb93cSSam Leffler 	}
106639beb93cSSam Leffler 
106739beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
106839beb93cSSam Leffler }
106939beb93cSSam Leffler 
107039beb93cSSam Leffler 
wpa_cli_cmd_password(struct wpa_ctrl * ctrl,int argc,char * argv[])107139beb93cSSam Leffler static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
107239beb93cSSam Leffler {
107339beb93cSSam Leffler 	char cmd[256], *pos, *end;
107439beb93cSSam Leffler 	int i, ret;
107539beb93cSSam Leffler 
107639beb93cSSam Leffler 	if (argc < 2) {
107739beb93cSSam Leffler 		printf("Invalid PASSWORD command: needs two arguments "
107839beb93cSSam Leffler 		       "(network id and password)\n");
107939beb93cSSam Leffler 		return -1;
108039beb93cSSam Leffler 	}
108139beb93cSSam Leffler 
108239beb93cSSam Leffler 	end = cmd + sizeof(cmd);
108339beb93cSSam Leffler 	pos = cmd;
108439beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
108539beb93cSSam Leffler 			  argv[0], argv[1]);
10865b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
108739beb93cSSam Leffler 		printf("Too long PASSWORD command.\n");
108839beb93cSSam Leffler 		return -1;
108939beb93cSSam Leffler 	}
109039beb93cSSam Leffler 	pos += ret;
109139beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
109239beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
10935b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
109439beb93cSSam Leffler 			printf("Too long PASSWORD command.\n");
109539beb93cSSam Leffler 			return -1;
109639beb93cSSam Leffler 		}
109739beb93cSSam Leffler 		pos += ret;
109839beb93cSSam Leffler 	}
109939beb93cSSam Leffler 
110039beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
110139beb93cSSam Leffler }
110239beb93cSSam Leffler 
110339beb93cSSam Leffler 
wpa_cli_cmd_new_password(struct wpa_ctrl * ctrl,int argc,char * argv[])110439beb93cSSam Leffler static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
110539beb93cSSam Leffler 				    char *argv[])
110639beb93cSSam Leffler {
110739beb93cSSam Leffler 	char cmd[256], *pos, *end;
110839beb93cSSam Leffler 	int i, ret;
110939beb93cSSam Leffler 
111039beb93cSSam Leffler 	if (argc < 2) {
111139beb93cSSam Leffler 		printf("Invalid NEW_PASSWORD command: needs two arguments "
111239beb93cSSam Leffler 		       "(network id and password)\n");
111339beb93cSSam Leffler 		return -1;
111439beb93cSSam Leffler 	}
111539beb93cSSam Leffler 
111639beb93cSSam Leffler 	end = cmd + sizeof(cmd);
111739beb93cSSam Leffler 	pos = cmd;
111839beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
111939beb93cSSam Leffler 			  argv[0], argv[1]);
11205b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
112139beb93cSSam Leffler 		printf("Too long NEW_PASSWORD command.\n");
112239beb93cSSam Leffler 		return -1;
112339beb93cSSam Leffler 	}
112439beb93cSSam Leffler 	pos += ret;
112539beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
112639beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
11275b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
112839beb93cSSam Leffler 			printf("Too long NEW_PASSWORD command.\n");
112939beb93cSSam Leffler 			return -1;
113039beb93cSSam Leffler 		}
113139beb93cSSam Leffler 		pos += ret;
113239beb93cSSam Leffler 	}
113339beb93cSSam Leffler 
113439beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
113539beb93cSSam Leffler }
113639beb93cSSam Leffler 
113739beb93cSSam Leffler 
wpa_cli_cmd_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])113839beb93cSSam Leffler static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
113939beb93cSSam Leffler {
114039beb93cSSam Leffler 	char cmd[256], *pos, *end;
114139beb93cSSam Leffler 	int i, ret;
114239beb93cSSam Leffler 
114339beb93cSSam Leffler 	if (argc < 2) {
114439beb93cSSam Leffler 		printf("Invalid PIN command: needs two arguments "
114539beb93cSSam Leffler 		       "(network id and pin)\n");
114639beb93cSSam Leffler 		return -1;
114739beb93cSSam Leffler 	}
114839beb93cSSam Leffler 
114939beb93cSSam Leffler 	end = cmd + sizeof(cmd);
115039beb93cSSam Leffler 	pos = cmd;
115139beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
115239beb93cSSam Leffler 			  argv[0], argv[1]);
11535b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
115439beb93cSSam Leffler 		printf("Too long PIN command.\n");
115539beb93cSSam Leffler 		return -1;
115639beb93cSSam Leffler 	}
115739beb93cSSam Leffler 	pos += ret;
115839beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
115939beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
11605b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
116139beb93cSSam Leffler 			printf("Too long PIN command.\n");
116239beb93cSSam Leffler 			return -1;
116339beb93cSSam Leffler 		}
116439beb93cSSam Leffler 		pos += ret;
116539beb93cSSam Leffler 	}
116639beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
116739beb93cSSam Leffler }
116839beb93cSSam Leffler 
116939beb93cSSam Leffler 
wpa_cli_cmd_otp(struct wpa_ctrl * ctrl,int argc,char * argv[])117039beb93cSSam Leffler static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
117139beb93cSSam Leffler {
117239beb93cSSam Leffler 	char cmd[256], *pos, *end;
117339beb93cSSam Leffler 	int i, ret;
117439beb93cSSam Leffler 
117539beb93cSSam Leffler 	if (argc < 2) {
117639beb93cSSam Leffler 		printf("Invalid OTP command: needs two arguments (network "
117739beb93cSSam Leffler 		       "id and password)\n");
117839beb93cSSam Leffler 		return -1;
117939beb93cSSam Leffler 	}
118039beb93cSSam Leffler 
118139beb93cSSam Leffler 	end = cmd + sizeof(cmd);
118239beb93cSSam Leffler 	pos = cmd;
118339beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
118439beb93cSSam Leffler 			  argv[0], argv[1]);
11855b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
118639beb93cSSam Leffler 		printf("Too long OTP command.\n");
118739beb93cSSam Leffler 		return -1;
118839beb93cSSam Leffler 	}
118939beb93cSSam Leffler 	pos += ret;
119039beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
119139beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
11925b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
119339beb93cSSam Leffler 			printf("Too long OTP command.\n");
119439beb93cSSam Leffler 			return -1;
119539beb93cSSam Leffler 		}
119639beb93cSSam Leffler 		pos += ret;
119739beb93cSSam Leffler 	}
119839beb93cSSam Leffler 
119939beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
120039beb93cSSam Leffler }
120139beb93cSSam Leffler 
120239beb93cSSam Leffler 
wpa_cli_cmd_sim(struct wpa_ctrl * ctrl,int argc,char * argv[])12035b9c547cSRui Paulo static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
12045b9c547cSRui Paulo {
12055b9c547cSRui Paulo 	char cmd[256], *pos, *end;
12065b9c547cSRui Paulo 	int i, ret;
12075b9c547cSRui Paulo 
12085b9c547cSRui Paulo 	if (argc < 2) {
12095b9c547cSRui Paulo 		printf("Invalid SIM command: needs two arguments "
12105b9c547cSRui Paulo 		       "(network id and SIM operation response)\n");
12115b9c547cSRui Paulo 		return -1;
12125b9c547cSRui Paulo 	}
12135b9c547cSRui Paulo 
12145b9c547cSRui Paulo 	end = cmd + sizeof(cmd);
12155b9c547cSRui Paulo 	pos = cmd;
12165b9c547cSRui Paulo 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
12175b9c547cSRui Paulo 			  argv[0], argv[1]);
12185b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
12195b9c547cSRui Paulo 		printf("Too long SIM command.\n");
12205b9c547cSRui Paulo 		return -1;
12215b9c547cSRui Paulo 	}
12225b9c547cSRui Paulo 	pos += ret;
12235b9c547cSRui Paulo 	for (i = 2; i < argc; i++) {
12245b9c547cSRui Paulo 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
12255b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
12265b9c547cSRui Paulo 			printf("Too long SIM command.\n");
12275b9c547cSRui Paulo 			return -1;
12285b9c547cSRui Paulo 		}
12295b9c547cSRui Paulo 		pos += ret;
12305b9c547cSRui Paulo 	}
12315b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
12325b9c547cSRui Paulo }
12335b9c547cSRui Paulo 
12345b9c547cSRui Paulo 
wpa_cli_cmd_psk_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])12354bc52338SCy Schubert static int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc,
12364bc52338SCy Schubert 				      char *argv[])
12374bc52338SCy Schubert {
12384bc52338SCy Schubert 	char cmd[256], *pos, *end;
12394bc52338SCy Schubert 	int i, ret;
12404bc52338SCy Schubert 
12414bc52338SCy Schubert 	if (argc < 2) {
12424bc52338SCy Schubert 		printf("Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n");
12434bc52338SCy Schubert 		return -1;
12444bc52338SCy Schubert 	}
12454bc52338SCy Schubert 
12464bc52338SCy Schubert 	end = cmd + sizeof(cmd);
12474bc52338SCy Schubert 	pos = cmd;
12484bc52338SCy Schubert 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s",
12494bc52338SCy Schubert 			  argv[0], argv[1]);
12504bc52338SCy Schubert 	if (os_snprintf_error(end - pos, ret)) {
12514bc52338SCy Schubert 		printf("Too long PSK_PASSPHRASE command.\n");
12524bc52338SCy Schubert 		return -1;
12534bc52338SCy Schubert 	}
12544bc52338SCy Schubert 	pos += ret;
12554bc52338SCy Schubert 	for (i = 2; i < argc; i++) {
12564bc52338SCy Schubert 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
12574bc52338SCy Schubert 		if (os_snprintf_error(end - pos, ret)) {
12584bc52338SCy Schubert 			printf("Too long PSK_PASSPHRASE command.\n");
12594bc52338SCy Schubert 			return -1;
12604bc52338SCy Schubert 		}
12614bc52338SCy Schubert 		pos += ret;
12624bc52338SCy Schubert 	}
12634bc52338SCy Schubert 
12644bc52338SCy Schubert 	return wpa_ctrl_command(ctrl, cmd);
12654bc52338SCy Schubert }
12664bc52338SCy Schubert 
12674bc52338SCy Schubert 
wpa_cli_cmd_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])126839beb93cSSam Leffler static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
126939beb93cSSam Leffler 				  char *argv[])
127039beb93cSSam Leffler {
127139beb93cSSam Leffler 	char cmd[256], *pos, *end;
127239beb93cSSam Leffler 	int i, ret;
127339beb93cSSam Leffler 
127439beb93cSSam Leffler 	if (argc < 2) {
127539beb93cSSam Leffler 		printf("Invalid PASSPHRASE command: needs two arguments "
127639beb93cSSam Leffler 		       "(network id and passphrase)\n");
127739beb93cSSam Leffler 		return -1;
127839beb93cSSam Leffler 	}
127939beb93cSSam Leffler 
128039beb93cSSam Leffler 	end = cmd + sizeof(cmd);
128139beb93cSSam Leffler 	pos = cmd;
128239beb93cSSam Leffler 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
128339beb93cSSam Leffler 			  argv[0], argv[1]);
12845b9c547cSRui Paulo 	if (os_snprintf_error(end - pos, ret)) {
128539beb93cSSam Leffler 		printf("Too long PASSPHRASE command.\n");
128639beb93cSSam Leffler 		return -1;
128739beb93cSSam Leffler 	}
128839beb93cSSam Leffler 	pos += ret;
128939beb93cSSam Leffler 	for (i = 2; i < argc; i++) {
129039beb93cSSam Leffler 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
12915b9c547cSRui Paulo 		if (os_snprintf_error(end - pos, ret)) {
129239beb93cSSam Leffler 			printf("Too long PASSPHRASE command.\n");
129339beb93cSSam Leffler 			return -1;
129439beb93cSSam Leffler 		}
129539beb93cSSam Leffler 		pos += ret;
129639beb93cSSam Leffler 	}
129739beb93cSSam Leffler 
129839beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
129939beb93cSSam Leffler }
130039beb93cSSam Leffler 
130139beb93cSSam Leffler 
wpa_cli_cmd_bssid(struct wpa_ctrl * ctrl,int argc,char * argv[])130239beb93cSSam Leffler static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
130339beb93cSSam Leffler {
130439beb93cSSam Leffler 	if (argc < 2) {
130539beb93cSSam Leffler 		printf("Invalid BSSID command: needs two arguments (network "
130639beb93cSSam Leffler 		       "id and BSSID)\n");
130739beb93cSSam Leffler 		return -1;
130839beb93cSSam Leffler 	}
130939beb93cSSam Leffler 
1310f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
131139beb93cSSam Leffler }
131239beb93cSSam Leffler 
1313f05cddf9SRui Paulo 
wpa_cli_cmd_bssid_ignore(struct wpa_ctrl * ctrl,int argc,char * argv[])1314c1d255d3SCy Schubert static int wpa_cli_cmd_bssid_ignore(struct wpa_ctrl *ctrl, int argc,
1315c1d255d3SCy Schubert 				    char *argv[])
1316f05cddf9SRui Paulo {
1317c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "BSSID_IGNORE", 0, argc, argv);
1318f05cddf9SRui Paulo }
1319f05cddf9SRui Paulo 
1320f05cddf9SRui Paulo 
wpa_cli_cmd_log_level(struct wpa_ctrl * ctrl,int argc,char * argv[])1321f05cddf9SRui Paulo static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1322f05cddf9SRui Paulo {
1323f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
132439beb93cSSam Leffler }
132539beb93cSSam Leffler 
132639beb93cSSam Leffler 
wpa_cli_cmd_list_networks(struct wpa_ctrl * ctrl,int argc,char * argv[])132739beb93cSSam Leffler static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
132839beb93cSSam Leffler 				     char *argv[])
132939beb93cSSam Leffler {
1330c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "LIST_NETWORKS", 0, argc, argv);
133139beb93cSSam Leffler }
133239beb93cSSam Leffler 
133339beb93cSSam Leffler 
wpa_cli_cmd_select_network(struct wpa_ctrl * ctrl,int argc,char * argv[])133439beb93cSSam Leffler static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
133539beb93cSSam Leffler 				      char *argv[])
133639beb93cSSam Leffler {
1337f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
133839beb93cSSam Leffler }
133939beb93cSSam Leffler 
134039beb93cSSam Leffler 
wpa_cli_cmd_enable_network(struct wpa_ctrl * ctrl,int argc,char * argv[])134139beb93cSSam Leffler static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
134239beb93cSSam Leffler 				      char *argv[])
134339beb93cSSam Leffler {
1344f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
134539beb93cSSam Leffler }
134639beb93cSSam Leffler 
134739beb93cSSam Leffler 
wpa_cli_cmd_disable_network(struct wpa_ctrl * ctrl,int argc,char * argv[])134839beb93cSSam Leffler static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
134939beb93cSSam Leffler 				       char *argv[])
135039beb93cSSam Leffler {
1351f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
135239beb93cSSam Leffler }
135339beb93cSSam Leffler 
135439beb93cSSam Leffler 
wpa_cli_cmd_add_network(struct wpa_ctrl * ctrl,int argc,char * argv[])135539beb93cSSam Leffler static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
135639beb93cSSam Leffler 				   char *argv[])
135739beb93cSSam Leffler {
1358325151a3SRui Paulo 	int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
1359325151a3SRui Paulo 	if (interactive)
1360325151a3SRui Paulo 		update_networks(ctrl);
1361325151a3SRui Paulo 	return res;
136239beb93cSSam Leffler }
136339beb93cSSam Leffler 
136439beb93cSSam Leffler 
wpa_cli_cmd_remove_network(struct wpa_ctrl * ctrl,int argc,char * argv[])136539beb93cSSam Leffler static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
136639beb93cSSam Leffler 				      char *argv[])
136739beb93cSSam Leffler {
1368325151a3SRui Paulo 	int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1369325151a3SRui Paulo 	if (interactive)
1370325151a3SRui Paulo 		update_networks(ctrl);
1371325151a3SRui Paulo 	return res;
137239beb93cSSam Leffler }
137339beb93cSSam Leffler 
137439beb93cSSam Leffler 
wpa_cli_show_network_variables(void)137539beb93cSSam Leffler static void wpa_cli_show_network_variables(void)
137639beb93cSSam Leffler {
137739beb93cSSam Leffler 	printf("set_network variables:\n"
137839beb93cSSam Leffler 	       "  ssid (network name, SSID)\n"
137939beb93cSSam Leffler 	       "  psk (WPA passphrase or pre-shared key)\n"
138039beb93cSSam Leffler 	       "  key_mgmt (key management protocol)\n"
138139beb93cSSam Leffler 	       "  identity (EAP identity)\n"
138239beb93cSSam Leffler 	       "  password (EAP password)\n"
138339beb93cSSam Leffler 	       "  ...\n"
138439beb93cSSam Leffler 	       "\n"
138539beb93cSSam Leffler 	       "Note: Values are entered in the same format as the "
138639beb93cSSam Leffler 	       "configuration file is using,\n"
138739beb93cSSam Leffler 	       "i.e., strings values need to be inside double quotation "
138839beb93cSSam Leffler 	       "marks.\n"
138939beb93cSSam Leffler 	       "For example: set_network 1 ssid \"network name\"\n"
139039beb93cSSam Leffler 	       "\n"
139139beb93cSSam Leffler 	       "Please see wpa_supplicant.conf documentation for full list "
139239beb93cSSam Leffler 	       "of\navailable variables.\n");
139339beb93cSSam Leffler }
139439beb93cSSam Leffler 
139539beb93cSSam Leffler 
wpa_cli_cmd_set_network(struct wpa_ctrl * ctrl,int argc,char * argv[])139639beb93cSSam Leffler static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
139739beb93cSSam Leffler 				   char *argv[])
139839beb93cSSam Leffler {
139939beb93cSSam Leffler 	if (argc == 0) {
140039beb93cSSam Leffler 		wpa_cli_show_network_variables();
140139beb93cSSam Leffler 		return 0;
140239beb93cSSam Leffler 	}
140339beb93cSSam Leffler 
1404f05cddf9SRui Paulo 	if (argc < 3) {
140539beb93cSSam Leffler 		printf("Invalid SET_NETWORK command: needs three arguments\n"
140639beb93cSSam Leffler 		       "(network id, variable name, and value)\n");
140739beb93cSSam Leffler 		return -1;
140839beb93cSSam Leffler 	}
140939beb93cSSam Leffler 
1410f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
141139beb93cSSam Leffler }
141239beb93cSSam Leffler 
141339beb93cSSam Leffler 
wpa_cli_cmd_get_network(struct wpa_ctrl * ctrl,int argc,char * argv[])141439beb93cSSam Leffler static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
141539beb93cSSam Leffler 				   char *argv[])
141639beb93cSSam Leffler {
141739beb93cSSam Leffler 	if (argc == 0) {
141839beb93cSSam Leffler 		wpa_cli_show_network_variables();
141939beb93cSSam Leffler 		return 0;
142039beb93cSSam Leffler 	}
142139beb93cSSam Leffler 
142239beb93cSSam Leffler 	if (argc != 2) {
142339beb93cSSam Leffler 		printf("Invalid GET_NETWORK command: needs two arguments\n"
142439beb93cSSam Leffler 		       "(network id and variable name)\n");
142539beb93cSSam Leffler 		return -1;
142639beb93cSSam Leffler 	}
142739beb93cSSam Leffler 
1428f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1429f05cddf9SRui Paulo }
1430f05cddf9SRui Paulo 
1431f05cddf9SRui Paulo 
1432325151a3SRui Paulo static const char *network_fields[] = {
1433c1d255d3SCy Schubert 	"ssid", "scan_ssid", "bssid", "bssid_ignore",
1434c1d255d3SCy Schubert 	"bssid_accept", "psk", "proto", "key_mgmt",
1435325151a3SRui Paulo 	"bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
143685732ac8SCy Schubert 	"freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1",
1437*a90b9d01SCy Schubert 	"vht_center_freq2", "ht", "edmg", "he",
1438325151a3SRui Paulo #ifdef IEEE8021X_EAPOL
1439325151a3SRui Paulo 	"eap", "identity", "anonymous_identity", "password", "ca_cert",
1440325151a3SRui Paulo 	"ca_path", "client_cert", "private_key", "private_key_passwd",
1441*a90b9d01SCy Schubert 	"subject_match", "altsubject_match",
14424bc52338SCy Schubert 	"check_cert_subject",
1443325151a3SRui Paulo 	"domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
1444325151a3SRui Paulo 	"client_cert2", "private_key2", "private_key2_passwd",
1445*a90b9d01SCy Schubert 	"subject_match2", "altsubject_match2",
14464bc52338SCy Schubert 	"check_cert_subject2",
1447325151a3SRui Paulo 	"domain_suffix_match2", "domain_match2", "phase1", "phase2",
1448325151a3SRui Paulo 	"pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
1449325151a3SRui Paulo 	"pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
1450325151a3SRui Paulo 	"engine", "engine2", "eapol_flags", "sim_num",
1451325151a3SRui Paulo 	"openssl_ciphers", "erp",
1452325151a3SRui Paulo #endif /* IEEE8021X_EAPOL */
1453325151a3SRui Paulo 	"wep_key0", "wep_key1", "wep_key2", "wep_key3",
1454325151a3SRui Paulo 	"wep_tx_keyidx", "priority",
1455325151a3SRui Paulo #ifdef IEEE8021X_EAPOL
1456325151a3SRui Paulo 	"eap_workaround", "pac_file", "fragment_size", "ocsp",
1457325151a3SRui Paulo #endif /* IEEE8021X_EAPOL */
1458325151a3SRui Paulo 	"mode",
1459325151a3SRui Paulo 	"proactive_key_caching", "disabled", "id_str",
1460325151a3SRui Paulo 	"ieee80211w",
146185732ac8SCy Schubert 	"mixed_cell", "frequency", "fixed_freq",
1462325151a3SRui Paulo #ifdef CONFIG_MESH
1463c1d255d3SCy Schubert 	"no_auto_peer", "mesh_rssi_threshold",
1464325151a3SRui Paulo 	"mesh_basic_rates", "dot11MeshMaxRetries",
1465325151a3SRui Paulo 	"dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
1466325151a3SRui Paulo 	"dot11MeshHoldingTimeout",
1467325151a3SRui Paulo #endif /* CONFIG_MESH */
1468325151a3SRui Paulo 	"wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
1469c1d255d3SCy Schubert 	"wpa_deny_ptk0_rekey",
1470c1d255d3SCy Schubert 	"enable_edmg", "edmg_channel",
1471325151a3SRui Paulo #ifdef CONFIG_P2P
1472325151a3SRui Paulo 	"go_p2p_dev_addr", "p2p_client_list", "psk_list",
1473325151a3SRui Paulo #endif /* CONFIG_P2P */
1474325151a3SRui Paulo #ifdef CONFIG_HT_OVERRIDES
1475325151a3SRui Paulo 	"disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
1476325151a3SRui Paulo 	"ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
14774bc52338SCy Schubert 	"ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc",
1478325151a3SRui Paulo #endif /* CONFIG_HT_OVERRIDES */
1479325151a3SRui Paulo #ifdef CONFIG_VHT_OVERRIDES
1480325151a3SRui Paulo 	"disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
1481325151a3SRui Paulo 	"vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
1482325151a3SRui Paulo 	"vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
1483325151a3SRui Paulo 	"vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
1484325151a3SRui Paulo 	"vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
1485325151a3SRui Paulo 	"vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
1486325151a3SRui Paulo #endif /* CONFIG_VHT_OVERRIDES */
1487c1d255d3SCy Schubert #ifdef CONFIG_HE_OVERRIDES
1488c1d255d3SCy Schubert 	"disable_he",
1489c1d255d3SCy Schubert #endif /* CONFIG_HE_OVERRIDES */
1490*a90b9d01SCy Schubert 	"disable_eht",
1491325151a3SRui Paulo 	"ap_max_inactivity", "dtim_period", "beacon_int",
1492325151a3SRui Paulo #ifdef CONFIG_MACSEC
1493325151a3SRui Paulo 	"macsec_policy",
149485732ac8SCy Schubert 	"macsec_integ_only",
14954bc52338SCy Schubert 	"macsec_replay_protect",
14964bc52338SCy Schubert 	"macsec_replay_window",
1497*a90b9d01SCy Schubert 	"macsec_offload",
149885732ac8SCy Schubert 	"macsec_port",
149985732ac8SCy Schubert 	"mka_priority",
1500325151a3SRui Paulo #endif /* CONFIG_MACSEC */
1501325151a3SRui Paulo #ifdef CONFIG_HS20
1502325151a3SRui Paulo 	"update_identifier",
1503325151a3SRui Paulo #endif /* CONFIG_HS20 */
1504780fb4a2SCy Schubert 	"mac_addr", "pbss", "wps_disabled"
1505325151a3SRui Paulo };
1506325151a3SRui Paulo 
1507325151a3SRui Paulo 
wpa_cli_complete_network(const char * str,int pos)1508325151a3SRui Paulo static char ** wpa_cli_complete_network(const char *str, int pos)
1509325151a3SRui Paulo {
1510325151a3SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
1511325151a3SRui Paulo 	int i, num_fields = ARRAY_SIZE(network_fields);
1512325151a3SRui Paulo 	char **res = NULL;
1513325151a3SRui Paulo 
1514325151a3SRui Paulo 	switch (arg) {
1515325151a3SRui Paulo 	case 1:
1516325151a3SRui Paulo 		res = cli_txt_list_array(&networks);
1517325151a3SRui Paulo 		break;
1518325151a3SRui Paulo 	case 2:
1519325151a3SRui Paulo 		res = os_calloc(num_fields + 1, sizeof(char *));
1520325151a3SRui Paulo 		if (res == NULL)
1521325151a3SRui Paulo 			return NULL;
1522325151a3SRui Paulo 		for (i = 0; i < num_fields; i++) {
1523325151a3SRui Paulo 			res[i] = os_strdup(network_fields[i]);
1524325151a3SRui Paulo 			if (res[i] == NULL)
1525325151a3SRui Paulo 				break;
1526325151a3SRui Paulo 		}
1527325151a3SRui Paulo 	}
1528325151a3SRui Paulo 	return res;
1529325151a3SRui Paulo }
1530325151a3SRui Paulo 
1531325151a3SRui Paulo 
wpa_cli_complete_network_id(const char * str,int pos)1532325151a3SRui Paulo static char ** wpa_cli_complete_network_id(const char *str, int pos)
1533325151a3SRui Paulo {
1534325151a3SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
1535325151a3SRui Paulo 	if (arg == 1)
1536325151a3SRui Paulo 		return cli_txt_list_array(&networks);
1537325151a3SRui Paulo 	return NULL;
1538325151a3SRui Paulo }
1539325151a3SRui Paulo 
1540325151a3SRui Paulo 
wpa_cli_cmd_dup_network(struct wpa_ctrl * ctrl,int argc,char * argv[])15415b9c547cSRui Paulo static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
15425b9c547cSRui Paulo 				   char *argv[])
15435b9c547cSRui Paulo {
15445b9c547cSRui Paulo 	if (argc == 0) {
15455b9c547cSRui Paulo 		wpa_cli_show_network_variables();
15465b9c547cSRui Paulo 		return 0;
15475b9c547cSRui Paulo 	}
15485b9c547cSRui Paulo 
15495b9c547cSRui Paulo 	if (argc < 3) {
15505b9c547cSRui Paulo 		printf("Invalid DUP_NETWORK command: needs three arguments\n"
15515b9c547cSRui Paulo 		       "(src netid, dest netid, and variable name)\n");
15525b9c547cSRui Paulo 		return -1;
15535b9c547cSRui Paulo 	}
15545b9c547cSRui Paulo 
15555b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
15565b9c547cSRui Paulo }
15575b9c547cSRui Paulo 
15585b9c547cSRui Paulo 
wpa_cli_complete_dup_network(const char * str,int pos)1559325151a3SRui Paulo static char ** wpa_cli_complete_dup_network(const char *str, int pos)
1560325151a3SRui Paulo {
1561325151a3SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
1562325151a3SRui Paulo 	int i, num_fields = ARRAY_SIZE(network_fields);
1563325151a3SRui Paulo 	char **res = NULL;
1564325151a3SRui Paulo 
1565325151a3SRui Paulo 	switch (arg) {
1566325151a3SRui Paulo 	case 1:
1567325151a3SRui Paulo 	case 2:
1568325151a3SRui Paulo 		res = cli_txt_list_array(&networks);
1569325151a3SRui Paulo 		break;
1570325151a3SRui Paulo 	case 3:
1571325151a3SRui Paulo 		res = os_calloc(num_fields + 1, sizeof(char *));
1572325151a3SRui Paulo 		if (res == NULL)
1573325151a3SRui Paulo 			return NULL;
1574325151a3SRui Paulo 		for (i = 0; i < num_fields; i++) {
1575325151a3SRui Paulo 			res[i] = os_strdup(network_fields[i]);
1576325151a3SRui Paulo 			if (res[i] == NULL)
1577325151a3SRui Paulo 				break;
1578325151a3SRui Paulo 		}
1579325151a3SRui Paulo 	}
1580325151a3SRui Paulo 	return res;
1581325151a3SRui Paulo }
1582325151a3SRui Paulo 
1583325151a3SRui Paulo 
wpa_cli_cmd_list_creds(struct wpa_ctrl * ctrl,int argc,char * argv[])1584f05cddf9SRui Paulo static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1585f05cddf9SRui Paulo 				  char *argv[])
1586f05cddf9SRui Paulo {
1587f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "LIST_CREDS");
1588f05cddf9SRui Paulo }
1589f05cddf9SRui Paulo 
1590f05cddf9SRui Paulo 
wpa_cli_cmd_add_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1591f05cddf9SRui Paulo static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1592f05cddf9SRui Paulo {
159385732ac8SCy Schubert 	int res = wpa_ctrl_command(ctrl, "ADD_CRED");
159485732ac8SCy Schubert 	if (interactive)
159585732ac8SCy Schubert 		update_creds(ctrl);
159685732ac8SCy Schubert 	return res;
1597f05cddf9SRui Paulo }
1598f05cddf9SRui Paulo 
1599f05cddf9SRui Paulo 
wpa_cli_cmd_remove_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1600f05cddf9SRui Paulo static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1601f05cddf9SRui Paulo 				   char *argv[])
1602f05cddf9SRui Paulo {
160385732ac8SCy Schubert 	int res = wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
160485732ac8SCy Schubert 	if (interactive)
160585732ac8SCy Schubert 		update_creds(ctrl);
160685732ac8SCy Schubert 	return res;
160785732ac8SCy Schubert }
160885732ac8SCy Schubert 
160985732ac8SCy Schubert 
161085732ac8SCy Schubert static const char * const cred_fields[] = {
161185732ac8SCy Schubert 	"temporary", "priority", "sp_priority", "pcsc", "eap",
161285732ac8SCy Schubert 	"update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home",
161385732ac8SCy Schubert 	"min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load",
161485732ac8SCy Schubert 	"req_conn_capab", "ocsp", "sim_num", "realm", "username", "password",
161585732ac8SCy Schubert 	"ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi",
161632a95656SCy Schubert 	"ca_cert_id", "cert_id", "key_id", "engine_id", "engine",
161785732ac8SCy Schubert 	"milenage", "domain_suffix_match", "domain", "phase1", "phase2",
161885732ac8SCy Schubert 	"roaming_consortium", "required_roaming_consortium", "excluded_ssid",
161985732ac8SCy Schubert 	"roaming_partner", "provisioning_sp"
162085732ac8SCy Schubert };
162185732ac8SCy Schubert 
162285732ac8SCy Schubert 
wpa_cli_complete_cred(const char * str,int pos)162385732ac8SCy Schubert static char ** wpa_cli_complete_cred(const char *str, int pos)
162485732ac8SCy Schubert {
162585732ac8SCy Schubert 	int arg = get_cmd_arg_num(str, pos);
162685732ac8SCy Schubert 	int i, num_fields = ARRAY_SIZE(cred_fields);
162785732ac8SCy Schubert 	char **res = NULL;
162885732ac8SCy Schubert 
162985732ac8SCy Schubert 	switch (arg) {
163085732ac8SCy Schubert 	case 1:
163185732ac8SCy Schubert 		res = cli_txt_list_array(&creds);
163285732ac8SCy Schubert 		break;
163385732ac8SCy Schubert 	case 2:
163485732ac8SCy Schubert 		res = os_calloc(num_fields + 1, sizeof(char *));
163585732ac8SCy Schubert 		if (res == NULL)
163685732ac8SCy Schubert 			return NULL;
163785732ac8SCy Schubert 		for (i = 0; i < num_fields; i++) {
163885732ac8SCy Schubert 			res[i] = os_strdup(cred_fields[i]);
163985732ac8SCy Schubert 			if (res[i] == NULL)
164085732ac8SCy Schubert 				break;
164185732ac8SCy Schubert 		}
164285732ac8SCy Schubert 	}
164385732ac8SCy Schubert 	return res;
1644f05cddf9SRui Paulo }
1645f05cddf9SRui Paulo 
1646f05cddf9SRui Paulo 
wpa_cli_cmd_set_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1647f05cddf9SRui Paulo static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1648f05cddf9SRui Paulo {
1649f05cddf9SRui Paulo 	if (argc != 3) {
1650f05cddf9SRui Paulo 		printf("Invalid SET_CRED command: needs three arguments\n"
1651f05cddf9SRui Paulo 		       "(cred id, variable name, and value)\n");
165239beb93cSSam Leffler 		return -1;
165339beb93cSSam Leffler 	}
1654f05cddf9SRui Paulo 
1655f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
165639beb93cSSam Leffler }
165739beb93cSSam Leffler 
165839beb93cSSam Leffler 
wpa_cli_cmd_get_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])16595b9c547cSRui Paulo static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
16605b9c547cSRui Paulo {
16615b9c547cSRui Paulo 	if (argc != 2) {
16625b9c547cSRui Paulo 		printf("Invalid GET_CRED command: needs two arguments\n"
16635b9c547cSRui Paulo 		       "(cred id, variable name)\n");
16645b9c547cSRui Paulo 		return -1;
16655b9c547cSRui Paulo 	}
16665b9c547cSRui Paulo 
16675b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
16685b9c547cSRui Paulo }
16695b9c547cSRui Paulo 
16705b9c547cSRui Paulo 
wpa_cli_cmd_disconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])167139beb93cSSam Leffler static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
167239beb93cSSam Leffler 				  char *argv[])
167339beb93cSSam Leffler {
167439beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "DISCONNECT");
167539beb93cSSam Leffler }
167639beb93cSSam Leffler 
167739beb93cSSam Leffler 
wpa_cli_cmd_reconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])167839beb93cSSam Leffler static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
167939beb93cSSam Leffler 				  char *argv[])
168039beb93cSSam Leffler {
168139beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "RECONNECT");
168239beb93cSSam Leffler }
168339beb93cSSam Leffler 
168439beb93cSSam Leffler 
wpa_cli_cmd_save_config(struct wpa_ctrl * ctrl,int argc,char * argv[])168539beb93cSSam Leffler static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
168639beb93cSSam Leffler 				   char *argv[])
168739beb93cSSam Leffler {
168839beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
168939beb93cSSam Leffler }
169039beb93cSSam Leffler 
169139beb93cSSam Leffler 
wpa_cli_cmd_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])169239beb93cSSam Leffler static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
169339beb93cSSam Leffler {
16945b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
169539beb93cSSam Leffler }
169639beb93cSSam Leffler 
169739beb93cSSam Leffler 
wpa_cli_cmd_scan_results(struct wpa_ctrl * ctrl,int argc,char * argv[])169839beb93cSSam Leffler static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
169939beb93cSSam Leffler 				    char *argv[])
170039beb93cSSam Leffler {
170139beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
170239beb93cSSam Leffler }
170339beb93cSSam Leffler 
170439beb93cSSam Leffler 
wpa_cli_cmd_abort_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])1705780fb4a2SCy Schubert static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
1706780fb4a2SCy Schubert 				  char *argv[])
1707780fb4a2SCy Schubert {
1708780fb4a2SCy Schubert 	return wpa_ctrl_command(ctrl, "ABORT_SCAN");
1709780fb4a2SCy Schubert }
1710780fb4a2SCy Schubert 
1711780fb4a2SCy Schubert 
wpa_cli_cmd_bss(struct wpa_ctrl * ctrl,int argc,char * argv[])171239beb93cSSam Leffler static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
171339beb93cSSam Leffler {
1714f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
171539beb93cSSam Leffler }
171639beb93cSSam Leffler 
171739beb93cSSam Leffler 
wpa_cli_complete_bss(const char * str,int pos)1718f05cddf9SRui Paulo static char ** wpa_cli_complete_bss(const char *str, int pos)
1719f05cddf9SRui Paulo {
1720f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
1721f05cddf9SRui Paulo 	char **res = NULL;
1722f05cddf9SRui Paulo 
1723f05cddf9SRui Paulo 	switch (arg) {
1724f05cddf9SRui Paulo 	case 1:
1725f05cddf9SRui Paulo 		res = cli_txt_list_array(&bsses);
1726f05cddf9SRui Paulo 		break;
1727f05cddf9SRui Paulo 	}
1728f05cddf9SRui Paulo 
1729f05cddf9SRui Paulo 	return res;
173039beb93cSSam Leffler }
173139beb93cSSam Leffler 
173239beb93cSSam Leffler 
wpa_cli_cmd_get_capability(struct wpa_ctrl * ctrl,int argc,char * argv[])173339beb93cSSam Leffler static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
173439beb93cSSam Leffler 				      char *argv[])
173539beb93cSSam Leffler {
1736c1d255d3SCy Schubert 	if (argc < 1 || argc > 3) {
1737c1d255d3SCy Schubert 		printf("Invalid GET_CAPABILITY command: need at least one argument and max three arguments\n");
173839beb93cSSam Leffler 		return -1;
173939beb93cSSam Leffler 	}
174039beb93cSSam Leffler 
1741c1d255d3SCy Schubert 	if (argc > 1 && os_strcmp(argv[0], "key_mgmt") != 0 &&
1742c1d255d3SCy Schubert 	    os_strncmp(argv[1], "iftype=", 7) == 0) {
1743c1d255d3SCy Schubert 		printf("Invalid GET_CAPABILITY command: 'iftype=' param is allowed only for 'key_mgmt'\n");
1744c1d255d3SCy Schubert 		return -1;
1745c1d255d3SCy Schubert 	}
1746c1d255d3SCy Schubert 
1747c1d255d3SCy Schubert 	if (argc == 2 && os_strcmp(argv[1], "strict") != 0 &&
1748c1d255d3SCy Schubert 	    os_strncmp(argv[1], "iftype=", 7) != 0) {
1749c1d255d3SCy Schubert 		printf("Invalid GET_CAPABILITY command: the second argument, if any, must be 'strict' OR 'iftype=<iftype_name>'\n");
1750c1d255d3SCy Schubert 		return -1;
1751c1d255d3SCy Schubert 	}
1752c1d255d3SCy Schubert 
1753c1d255d3SCy Schubert 	if (argc == 3 && os_strcmp(argv[2], "strict") != 0) {
1754c1d255d3SCy Schubert 		printf("Invalid GET_CAPABILITY command: the third argument, if any, must be 'strict'\n");
175539beb93cSSam Leffler 		return -1;
175639beb93cSSam Leffler 	}
175739beb93cSSam Leffler 
1758f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
175939beb93cSSam Leffler }
176039beb93cSSam Leffler 
176139beb93cSSam Leffler 
wpa_cli_complete_get_capability(const char * str,int pos)1762780fb4a2SCy Schubert static char ** wpa_cli_complete_get_capability(const char *str, int pos)
1763780fb4a2SCy Schubert {
1764780fb4a2SCy Schubert 	int arg = get_cmd_arg_num(str, pos);
1765780fb4a2SCy Schubert 	const char *fields[] = {
1766780fb4a2SCy Schubert 		"eap", "pairwise", "group", "group_mgmt", "key_mgmt",
1767780fb4a2SCy Schubert 		"proto", "auth_alg", "modes", "channels", "freq",
1768780fb4a2SCy Schubert #ifdef CONFIG_TDLS
1769780fb4a2SCy Schubert 		"tdls",
1770780fb4a2SCy Schubert #endif /* CONFIG_TDLS */
1771780fb4a2SCy Schubert #ifdef CONFIG_ERP
1772780fb4a2SCy Schubert 		"erp",
1773780fb4a2SCy Schubert #endif /* CONFIG_ERP */
1774780fb4a2SCy Schubert #ifdef CONFIG_FIPS
1775780fb4a2SCy Schubert 		"fips",
1776780fb4a2SCy Schubert #endif /* CONFIG_FIPS */
1777780fb4a2SCy Schubert #ifdef CONFIG_ACS
1778780fb4a2SCy Schubert 		"acs",
1779780fb4a2SCy Schubert #endif /* CONFIG_ACS */
1780780fb4a2SCy Schubert 	};
1781c1d255d3SCy Schubert 	const char *iftypes[] = {
1782c1d255d3SCy Schubert 		"iftype=STATION", "iftype=AP", "iftype=P2P_CLIENT",
1783c1d255d3SCy Schubert 		"iftype=P2P_GO", "iftype=AP_VLAN", "iftype=IBSS", "iftype=NAN",
1784c1d255d3SCy Schubert 		"iftype=P2P_DEVICE", "iftype=MESH",
1785c1d255d3SCy Schubert 	};
1786780fb4a2SCy Schubert 	int i, num_fields = ARRAY_SIZE(fields);
1787c1d255d3SCy Schubert 	int num_iftypes = ARRAY_SIZE(iftypes);
1788780fb4a2SCy Schubert 	char **res = NULL;
1789780fb4a2SCy Schubert 
1790780fb4a2SCy Schubert 	if (arg == 1) {
1791780fb4a2SCy Schubert 		res = os_calloc(num_fields + 1, sizeof(char *));
1792780fb4a2SCy Schubert 		if (res == NULL)
1793780fb4a2SCy Schubert 			return NULL;
1794780fb4a2SCy Schubert 		for (i = 0; i < num_fields; i++) {
1795780fb4a2SCy Schubert 			res[i] = os_strdup(fields[i]);
1796780fb4a2SCy Schubert 			if (res[i] == NULL)
1797780fb4a2SCy Schubert 				return res;
1798780fb4a2SCy Schubert 		}
1799780fb4a2SCy Schubert 	}
1800780fb4a2SCy Schubert 	if (arg == 2) {
1801c1d255d3SCy Schubert 		/* the second argument can be "iftype=<iftype_name>" OR
1802c1d255d3SCy Schubert 		 * "strict" */
1803c1d255d3SCy Schubert 		res = os_calloc(num_iftypes + 2, sizeof(char *));
1804c1d255d3SCy Schubert 		if (!res)
1805c1d255d3SCy Schubert 			return NULL;
1806c1d255d3SCy Schubert 		res[0] = os_strdup("strict");
1807c1d255d3SCy Schubert 		if (!res[0])
1808c1d255d3SCy Schubert 			return res;
1809c1d255d3SCy Schubert 		for (i = 0; i < num_iftypes; i++) {
1810c1d255d3SCy Schubert 			res[i + 1] = os_strdup(iftypes[i]);
1811c1d255d3SCy Schubert 			if (!res[i + 1])
1812c1d255d3SCy Schubert 				return res;
1813c1d255d3SCy Schubert 		}
1814c1d255d3SCy Schubert 	}
1815c1d255d3SCy Schubert 	if (arg == 3) {
1816780fb4a2SCy Schubert 		res = os_calloc(1 + 1, sizeof(char *));
1817780fb4a2SCy Schubert 		if (res == NULL)
1818780fb4a2SCy Schubert 			return NULL;
1819780fb4a2SCy Schubert 		res[0] = os_strdup("strict");
1820780fb4a2SCy Schubert 	}
1821780fb4a2SCy Schubert 	return res;
1822780fb4a2SCy Schubert }
1823780fb4a2SCy Schubert 
1824780fb4a2SCy Schubert 
wpa_cli_list_interfaces(struct wpa_ctrl * ctrl)182539beb93cSSam Leffler static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
182639beb93cSSam Leffler {
182739beb93cSSam Leffler 	printf("Available interfaces:\n");
182839beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "INTERFACES");
182939beb93cSSam Leffler }
183039beb93cSSam Leffler 
183139beb93cSSam Leffler 
wpa_cli_cmd_interface(struct wpa_ctrl * ctrl,int argc,char * argv[])183239beb93cSSam Leffler static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
183339beb93cSSam Leffler {
183439beb93cSSam Leffler 	if (argc < 1) {
183539beb93cSSam Leffler 		wpa_cli_list_interfaces(ctrl);
183639beb93cSSam Leffler 		return 0;
183739beb93cSSam Leffler 	}
183839beb93cSSam Leffler 
183939beb93cSSam Leffler 	wpa_cli_close_connection();
184039beb93cSSam Leffler 	os_free(ctrl_ifname);
184139beb93cSSam Leffler 	ctrl_ifname = os_strdup(argv[0]);
18425b9c547cSRui Paulo 	if (!ctrl_ifname) {
18435b9c547cSRui Paulo 		printf("Failed to allocate memory\n");
18445b9c547cSRui Paulo 		return 0;
18455b9c547cSRui Paulo 	}
184639beb93cSSam Leffler 
18475b9c547cSRui Paulo 	if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1848c1d255d3SCy Schubert 		printf("Connected to interface '%s'.\n", ctrl_ifname);
184939beb93cSSam Leffler 	} else {
185039beb93cSSam Leffler 		printf("Could not connect to interface '%s' - re-trying\n",
185139beb93cSSam Leffler 		       ctrl_ifname);
185239beb93cSSam Leffler 	}
185339beb93cSSam Leffler 	return 0;
185439beb93cSSam Leffler }
185539beb93cSSam Leffler 
185639beb93cSSam Leffler 
wpa_cli_cmd_reconfigure(struct wpa_ctrl * ctrl,int argc,char * argv[])185739beb93cSSam Leffler static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
185839beb93cSSam Leffler 				   char *argv[])
185939beb93cSSam Leffler {
186039beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "RECONFIGURE");
186139beb93cSSam Leffler }
186239beb93cSSam Leffler 
186339beb93cSSam Leffler 
wpa_cli_cmd_terminate(struct wpa_ctrl * ctrl,int argc,char * argv[])186439beb93cSSam Leffler static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
186539beb93cSSam Leffler 				 char *argv[])
186639beb93cSSam Leffler {
186739beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "TERMINATE");
186839beb93cSSam Leffler }
186939beb93cSSam Leffler 
187039beb93cSSam Leffler 
wpa_cli_cmd_interface_add(struct wpa_ctrl * ctrl,int argc,char * argv[])187139beb93cSSam Leffler static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
187239beb93cSSam Leffler 				     char *argv[])
187339beb93cSSam Leffler {
187439beb93cSSam Leffler 	char cmd[256];
187539beb93cSSam Leffler 	int res;
187639beb93cSSam Leffler 
187739beb93cSSam Leffler 	if (argc < 1) {
187839beb93cSSam Leffler 		printf("Invalid INTERFACE_ADD command: needs at least one "
187939beb93cSSam Leffler 		       "argument (interface name)\n"
188039beb93cSSam Leffler 		       "All arguments: ifname confname driver ctrl_interface "
1881325151a3SRui Paulo 		       "driver_param bridge_name [create]\n");
188239beb93cSSam Leffler 		return -1;
188339beb93cSSam Leffler 	}
188439beb93cSSam Leffler 
188539beb93cSSam Leffler 	/*
188639beb93cSSam Leffler 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1887780fb4a2SCy Schubert 	 * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
188839beb93cSSam Leffler 	 */
188939beb93cSSam Leffler 	res = os_snprintf(cmd, sizeof(cmd),
1890780fb4a2SCy Schubert 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
189139beb93cSSam Leffler 			  argv[0],
189239beb93cSSam Leffler 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
189339beb93cSSam Leffler 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1894780fb4a2SCy Schubert 			  argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
1895780fb4a2SCy Schubert 			  argc > 7 ? argv[7] : "");
18965b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res))
189739beb93cSSam Leffler 		return -1;
189839beb93cSSam Leffler 	cmd[sizeof(cmd) - 1] = '\0';
189939beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, cmd);
190039beb93cSSam Leffler }
190139beb93cSSam Leffler 
190239beb93cSSam Leffler 
wpa_cli_cmd_interface_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])190339beb93cSSam Leffler static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
190439beb93cSSam Leffler 					char *argv[])
190539beb93cSSam Leffler {
1906f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
190739beb93cSSam Leffler }
190839beb93cSSam Leffler 
190939beb93cSSam Leffler 
wpa_cli_cmd_interface_list(struct wpa_ctrl * ctrl,int argc,char * argv[])191039beb93cSSam Leffler static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
191139beb93cSSam Leffler 				      char *argv[])
191239beb93cSSam Leffler {
191339beb93cSSam Leffler 	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
191439beb93cSSam Leffler }
191539beb93cSSam Leffler 
191639beb93cSSam Leffler 
1917e28a4053SRui Paulo #ifdef CONFIG_AP
wpa_cli_cmd_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])1918e28a4053SRui Paulo static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1919e28a4053SRui Paulo {
1920f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1921e28a4053SRui Paulo }
1922e28a4053SRui Paulo 
1923e28a4053SRui Paulo 
wpa_cli_complete_sta(const char * str,int pos)192485732ac8SCy Schubert static char ** wpa_cli_complete_sta(const char *str, int pos)
192585732ac8SCy Schubert {
192685732ac8SCy Schubert 	int arg = get_cmd_arg_num(str, pos);
192785732ac8SCy Schubert 	char **res = NULL;
192885732ac8SCy Schubert 
192985732ac8SCy Schubert 	switch (arg) {
193085732ac8SCy Schubert 	case 1:
193185732ac8SCy Schubert 		res = cli_txt_list_array(&stations);
193285732ac8SCy Schubert 		break;
193385732ac8SCy Schubert 	}
193485732ac8SCy Schubert 
193585732ac8SCy Schubert 	return res;
193685732ac8SCy Schubert }
193785732ac8SCy Schubert 
193885732ac8SCy Schubert 
wpa_ctrl_command_sta(struct wpa_ctrl * ctrl,const char * cmd,char * addr,size_t addr_len,int print)193985732ac8SCy Schubert static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd,
194085732ac8SCy Schubert 				char *addr, size_t addr_len, int print)
1941e28a4053SRui Paulo {
1942e28a4053SRui Paulo 	char buf[4096], *pos;
1943e28a4053SRui Paulo 	size_t len;
1944e28a4053SRui Paulo 	int ret;
1945e28a4053SRui Paulo 
1946e28a4053SRui Paulo 	if (ctrl_conn == NULL) {
1947e28a4053SRui Paulo 		printf("Not connected to hostapd - command dropped.\n");
1948e28a4053SRui Paulo 		return -1;
1949e28a4053SRui Paulo 	}
1950780fb4a2SCy Schubert 	if (ifname_prefix) {
1951780fb4a2SCy Schubert 		os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
1952780fb4a2SCy Schubert 			    ifname_prefix, cmd);
1953780fb4a2SCy Schubert 		buf[sizeof(buf) - 1] = '\0';
1954780fb4a2SCy Schubert 		cmd = buf;
1955780fb4a2SCy Schubert 	}
1956e28a4053SRui Paulo 	len = sizeof(buf) - 1;
1957f05cddf9SRui Paulo 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1958e28a4053SRui Paulo 			       wpa_cli_msg_cb);
1959e28a4053SRui Paulo 	if (ret == -2) {
1960e28a4053SRui Paulo 		printf("'%s' command timed out.\n", cmd);
1961e28a4053SRui Paulo 		return -2;
1962e28a4053SRui Paulo 	} else if (ret < 0) {
1963e28a4053SRui Paulo 		printf("'%s' command failed.\n", cmd);
1964e28a4053SRui Paulo 		return -1;
1965e28a4053SRui Paulo 	}
1966e28a4053SRui Paulo 
1967e28a4053SRui Paulo 	buf[len] = '\0';
196885732ac8SCy Schubert 	if (os_memcmp(buf, "FAIL", 4) == 0 ||
196985732ac8SCy Schubert 	    os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0)
1970e28a4053SRui Paulo 		return -1;
197185732ac8SCy Schubert 	if (print)
1972e28a4053SRui Paulo 		printf("%s", buf);
1973e28a4053SRui Paulo 
1974e28a4053SRui Paulo 	pos = buf;
1975e28a4053SRui Paulo 	while (*pos != '\0' && *pos != '\n')
1976e28a4053SRui Paulo 		pos++;
1977e28a4053SRui Paulo 	*pos = '\0';
1978e28a4053SRui Paulo 	os_strlcpy(addr, buf, addr_len);
1979e28a4053SRui Paulo 	return 0;
1980e28a4053SRui Paulo }
1981e28a4053SRui Paulo 
1982e28a4053SRui Paulo 
wpa_cli_cmd_all_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])1983e28a4053SRui Paulo static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1984e28a4053SRui Paulo {
1985e28a4053SRui Paulo 	char addr[32], cmd[64];
1986e28a4053SRui Paulo 
198785732ac8SCy Schubert 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1))
1988e28a4053SRui Paulo 		return 0;
1989e28a4053SRui Paulo 	do {
1990e28a4053SRui Paulo 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
199185732ac8SCy Schubert 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0);
1992e28a4053SRui Paulo 
1993e28a4053SRui Paulo 	return -1;
1994e28a4053SRui Paulo }
1995f05cddf9SRui Paulo 
1996f05cddf9SRui Paulo 
wpa_cli_cmd_list_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])199785732ac8SCy Schubert static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc,
199885732ac8SCy Schubert 				char *argv[])
199985732ac8SCy Schubert {
200085732ac8SCy Schubert 	char addr[32], cmd[64];
200185732ac8SCy Schubert 
200285732ac8SCy Schubert 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0))
200385732ac8SCy Schubert 		return 0;
200485732ac8SCy Schubert 	do {
200585732ac8SCy Schubert 		if (os_strcmp(addr, "") != 0)
200685732ac8SCy Schubert 			printf("%s\n", addr);
200785732ac8SCy Schubert 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
200885732ac8SCy Schubert 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0);
200985732ac8SCy Schubert 
201085732ac8SCy Schubert 	return 0;
201185732ac8SCy Schubert }
201285732ac8SCy Schubert 
201385732ac8SCy Schubert 
wpa_cli_cmd_deauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])2014f05cddf9SRui Paulo static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
2015f05cddf9SRui Paulo 				      char *argv[])
2016f05cddf9SRui Paulo {
2017f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
2018f05cddf9SRui Paulo }
2019f05cddf9SRui Paulo 
2020f05cddf9SRui Paulo 
wpa_cli_complete_deauthenticate(const char * str,int pos)202185732ac8SCy Schubert static char ** wpa_cli_complete_deauthenticate(const char *str, int pos)
202285732ac8SCy Schubert {
202385732ac8SCy Schubert 	int arg = get_cmd_arg_num(str, pos);
202485732ac8SCy Schubert 	char **res = NULL;
202585732ac8SCy Schubert 
202685732ac8SCy Schubert 	switch (arg) {
202785732ac8SCy Schubert 	case 1:
202885732ac8SCy Schubert 		res = cli_txt_list_array(&stations);
202985732ac8SCy Schubert 		break;
203085732ac8SCy Schubert 	}
203185732ac8SCy Schubert 
203285732ac8SCy Schubert 	return res;
203385732ac8SCy Schubert }
203485732ac8SCy Schubert 
203585732ac8SCy Schubert 
wpa_cli_cmd_disassociate(struct wpa_ctrl * ctrl,int argc,char * argv[])2036f05cddf9SRui Paulo static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
2037f05cddf9SRui Paulo 				    char *argv[])
2038f05cddf9SRui Paulo {
2039f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
2040f05cddf9SRui Paulo }
20415b9c547cSRui Paulo 
204285732ac8SCy Schubert 
wpa_cli_complete_disassociate(const char * str,int pos)204385732ac8SCy Schubert static char ** wpa_cli_complete_disassociate(const char *str, int pos)
204485732ac8SCy Schubert {
204585732ac8SCy Schubert 	int arg = get_cmd_arg_num(str, pos);
204685732ac8SCy Schubert 	char **res = NULL;
204785732ac8SCy Schubert 
204885732ac8SCy Schubert 	switch (arg) {
204985732ac8SCy Schubert 	case 1:
205085732ac8SCy Schubert 		res = cli_txt_list_array(&stations);
205185732ac8SCy Schubert 		break;
205285732ac8SCy Schubert 	}
205385732ac8SCy Schubert 
205485732ac8SCy Schubert 	return res;
205585732ac8SCy Schubert }
205685732ac8SCy Schubert 
205785732ac8SCy Schubert 
wpa_cli_cmd_chanswitch(struct wpa_ctrl * ctrl,int argc,char * argv[])20585b9c547cSRui Paulo static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
20595b9c547cSRui Paulo 				    char *argv[])
20605b9c547cSRui Paulo {
20615b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
20625b9c547cSRui Paulo }
20635b9c547cSRui Paulo 
20644b72b91aSCy Schubert 
wpa_cli_cmd_update_beacon(struct wpa_ctrl * ctrl,int argc,char * argv[])20654b72b91aSCy Schubert static int wpa_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
20664b72b91aSCy Schubert 				     char *argv[])
20674b72b91aSCy Schubert {
20684b72b91aSCy Schubert 	return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
20694b72b91aSCy Schubert }
20704b72b91aSCy Schubert 
2071*a90b9d01SCy Schubert 
wpa_cli_cmd_accept_macacl(struct wpa_ctrl * ctrl,int argc,char * argv[])2072*a90b9d01SCy Schubert static int wpa_cli_cmd_accept_macacl(struct wpa_ctrl *ctrl, int argc,
2073*a90b9d01SCy Schubert 				     char *argv[])
2074*a90b9d01SCy Schubert {
2075*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "ACCEPT_ACL", 1, argc, argv);
2076*a90b9d01SCy Schubert }
2077*a90b9d01SCy Schubert 
2078*a90b9d01SCy Schubert 
wpa_cli_cmd_deny_macacl(struct wpa_ctrl * ctrl,int argc,char * argv[])2079*a90b9d01SCy Schubert static int wpa_cli_cmd_deny_macacl(struct wpa_ctrl *ctrl, int argc,
2080*a90b9d01SCy Schubert 				   char *argv[])
2081*a90b9d01SCy Schubert {
2082*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "DENY_ACL", 1, argc, argv);
2083*a90b9d01SCy Schubert }
2084*a90b9d01SCy Schubert 
2085e28a4053SRui Paulo #endif /* CONFIG_AP */
2086e28a4053SRui Paulo 
2087e28a4053SRui Paulo 
wpa_cli_cmd_suspend(struct wpa_ctrl * ctrl,int argc,char * argv[])2088e28a4053SRui Paulo static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
2089e28a4053SRui Paulo {
2090e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, "SUSPEND");
2091e28a4053SRui Paulo }
2092e28a4053SRui Paulo 
2093e28a4053SRui Paulo 
wpa_cli_cmd_resume(struct wpa_ctrl * ctrl,int argc,char * argv[])2094e28a4053SRui Paulo static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
2095e28a4053SRui Paulo {
2096e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, "RESUME");
2097e28a4053SRui Paulo }
2098e28a4053SRui Paulo 
2099e28a4053SRui Paulo 
21005b9c547cSRui Paulo #ifdef CONFIG_TESTING_OPTIONS
2101*a90b9d01SCy Schubert 
wpa_cli_cmd_drop_sa(struct wpa_ctrl * ctrl,int argc,char * argv[])2102e28a4053SRui Paulo static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
2103e28a4053SRui Paulo {
2104e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, "DROP_SA");
2105e28a4053SRui Paulo }
2106*a90b9d01SCy Schubert 
2107*a90b9d01SCy Schubert 
wpa_cli_cmd_ml_probe_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2108*a90b9d01SCy Schubert static int wpa_cli_cmd_ml_probe_req(struct wpa_ctrl *ctrl,
2109*a90b9d01SCy Schubert 				    int argc, char *argv[])
2110*a90b9d01SCy Schubert {
2111*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "ML_PROBE_REQ", 2, argc, argv);
2112*a90b9d01SCy Schubert }
2113*a90b9d01SCy Schubert 
21145b9c547cSRui Paulo #endif /* CONFIG_TESTING_OPTIONS */
2115e28a4053SRui Paulo 
2116e28a4053SRui Paulo 
wpa_cli_cmd_roam(struct wpa_ctrl * ctrl,int argc,char * argv[])2117e28a4053SRui Paulo static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
2118e28a4053SRui Paulo {
2119f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
2120f05cddf9SRui Paulo }
2121f05cddf9SRui Paulo 
2122f05cddf9SRui Paulo 
21235b9c547cSRui Paulo #ifdef CONFIG_MESH
21245b9c547cSRui Paulo 
wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl * ctrl,int argc,char * argv[])21255b9c547cSRui Paulo static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
21265b9c547cSRui Paulo 					  char *argv[])
21275b9c547cSRui Paulo {
21285b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
21295b9c547cSRui Paulo }
21305b9c547cSRui Paulo 
21315b9c547cSRui Paulo 
wpa_cli_cmd_mesh_group_add(struct wpa_ctrl * ctrl,int argc,char * argv[])21325b9c547cSRui Paulo static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
21335b9c547cSRui Paulo 				      char *argv[])
21345b9c547cSRui Paulo {
21355b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
21365b9c547cSRui Paulo }
21375b9c547cSRui Paulo 
21385b9c547cSRui Paulo 
wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])21395b9c547cSRui Paulo static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
21405b9c547cSRui Paulo 					 char *argv[])
21415b9c547cSRui Paulo {
21425b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
21435b9c547cSRui Paulo }
21445b9c547cSRui Paulo 
2145780fb4a2SCy Schubert 
wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2146780fb4a2SCy Schubert static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
2147780fb4a2SCy Schubert 					char *argv[])
2148780fb4a2SCy Schubert {
2149780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
2150780fb4a2SCy Schubert }
2151780fb4a2SCy Schubert 
2152780fb4a2SCy Schubert 
wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2153780fb4a2SCy Schubert static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
2154780fb4a2SCy Schubert 				     char *argv[])
2155780fb4a2SCy Schubert {
2156780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
2157780fb4a2SCy Schubert }
2158780fb4a2SCy Schubert 
2159206b73d0SCy Schubert 
wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl * ctrl,int argc,char * argv[])2160206b73d0SCy Schubert static int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc,
2161206b73d0SCy Schubert 				       char *argv[])
2162206b73d0SCy Schubert {
2163206b73d0SCy Schubert 	return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv);
2164206b73d0SCy Schubert }
2165206b73d0SCy Schubert 
21665b9c547cSRui Paulo #endif /* CONFIG_MESH */
21675b9c547cSRui Paulo 
21685b9c547cSRui Paulo 
2169f05cddf9SRui Paulo #ifdef CONFIG_P2P
2170f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_find(struct wpa_ctrl * ctrl,int argc,char * argv[])2171f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2172f05cddf9SRui Paulo {
2173f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
2174f05cddf9SRui Paulo }
2175f05cddf9SRui Paulo 
2176f05cddf9SRui Paulo 
wpa_cli_complete_p2p_find(const char * str,int pos)2177f05cddf9SRui Paulo static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
2178f05cddf9SRui Paulo {
2179f05cddf9SRui Paulo 	char **res = NULL;
2180f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
2181f05cddf9SRui Paulo 
2182f05cddf9SRui Paulo 	res = os_calloc(6, sizeof(char *));
2183f05cddf9SRui Paulo 	if (res == NULL)
2184f05cddf9SRui Paulo 		return NULL;
2185f05cddf9SRui Paulo 	res[0] = os_strdup("type=social");
2186f05cddf9SRui Paulo 	if (res[0] == NULL) {
2187f05cddf9SRui Paulo 		os_free(res);
2188f05cddf9SRui Paulo 		return NULL;
2189f05cddf9SRui Paulo 	}
2190f05cddf9SRui Paulo 	res[1] = os_strdup("type=progressive");
2191f05cddf9SRui Paulo 	if (res[1] == NULL)
2192f05cddf9SRui Paulo 		return res;
2193f05cddf9SRui Paulo 	res[2] = os_strdup("delay=");
2194f05cddf9SRui Paulo 	if (res[2] == NULL)
2195f05cddf9SRui Paulo 		return res;
2196f05cddf9SRui Paulo 	res[3] = os_strdup("dev_id=");
2197f05cddf9SRui Paulo 	if (res[3] == NULL)
2198f05cddf9SRui Paulo 		return res;
2199f05cddf9SRui Paulo 	if (arg == 1)
2200f05cddf9SRui Paulo 		res[4] = os_strdup("[timeout]");
2201f05cddf9SRui Paulo 
2202f05cddf9SRui Paulo 	return res;
2203f05cddf9SRui Paulo }
2204f05cddf9SRui Paulo 
2205f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl * ctrl,int argc,char * argv[])2206f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2207f05cddf9SRui Paulo 				     char *argv[])
2208f05cddf9SRui Paulo {
2209f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2210f05cddf9SRui Paulo }
2211f05cddf9SRui Paulo 
2212f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl * ctrl,int argc,char * argv[])22135b9c547cSRui Paulo static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
22145b9c547cSRui Paulo 					 char *argv[])
22155b9c547cSRui Paulo {
22165b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
22175b9c547cSRui Paulo }
22185b9c547cSRui Paulo 
22195b9c547cSRui Paulo 
wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])22205b9c547cSRui Paulo static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
22215b9c547cSRui Paulo 					      char *argv[])
22225b9c547cSRui Paulo {
22235b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
22245b9c547cSRui Paulo }
22255b9c547cSRui Paulo 
22265b9c547cSRui Paulo 
wpa_cli_cmd_p2p_connect(struct wpa_ctrl * ctrl,int argc,char * argv[])2227f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2228f05cddf9SRui Paulo 				   char *argv[])
2229f05cddf9SRui Paulo {
2230f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
2231f05cddf9SRui Paulo }
2232f05cddf9SRui Paulo 
2233f05cddf9SRui Paulo 
wpa_cli_complete_p2p_connect(const char * str,int pos)2234f05cddf9SRui Paulo static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2235f05cddf9SRui Paulo {
2236f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
2237f05cddf9SRui Paulo 	char **res = NULL;
2238f05cddf9SRui Paulo 
2239f05cddf9SRui Paulo 	switch (arg) {
2240f05cddf9SRui Paulo 	case 1:
2241f05cddf9SRui Paulo 		res = cli_txt_list_array(&p2p_peers);
2242f05cddf9SRui Paulo 		break;
2243f05cddf9SRui Paulo 	}
2244f05cddf9SRui Paulo 
2245f05cddf9SRui Paulo 	return res;
2246f05cddf9SRui Paulo }
2247f05cddf9SRui Paulo 
2248f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])2249f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2250f05cddf9SRui Paulo 				  char *argv[])
2251f05cddf9SRui Paulo {
2252f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
2253f05cddf9SRui Paulo }
2254f05cddf9SRui Paulo 
2255f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2256f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2257f05cddf9SRui Paulo 					char *argv[])
2258f05cddf9SRui Paulo {
2259f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
2260f05cddf9SRui Paulo }
2261f05cddf9SRui Paulo 
2262f05cddf9SRui Paulo 
wpa_cli_complete_p2p_group_remove(const char * str,int pos)2263f05cddf9SRui Paulo static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2264f05cddf9SRui Paulo {
2265f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
2266f05cddf9SRui Paulo 	char **res = NULL;
2267f05cddf9SRui Paulo 
2268f05cddf9SRui Paulo 	switch (arg) {
2269f05cddf9SRui Paulo 	case 1:
2270f05cddf9SRui Paulo 		res = cli_txt_list_array(&p2p_groups);
2271f05cddf9SRui Paulo 		break;
2272f05cddf9SRui Paulo 	}
2273f05cddf9SRui Paulo 
2274f05cddf9SRui Paulo 	return res;
2275f05cddf9SRui Paulo }
2276f05cddf9SRui Paulo 
2277f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_group_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2278f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2279f05cddf9SRui Paulo 					char *argv[])
2280f05cddf9SRui Paulo {
2281f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2282f05cddf9SRui Paulo }
2283f05cddf9SRui Paulo 
2284f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_group_member(struct wpa_ctrl * ctrl,int argc,char * argv[])2285780fb4a2SCy Schubert static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
2286780fb4a2SCy Schubert 					char *argv[])
2287780fb4a2SCy Schubert {
2288780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
2289780fb4a2SCy Schubert }
2290780fb4a2SCy Schubert 
2291780fb4a2SCy Schubert 
wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl * ctrl,int argc,char * argv[])2292f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2293f05cddf9SRui Paulo 				     char *argv[])
2294f05cddf9SRui Paulo {
2295f05cddf9SRui Paulo 	if (argc != 2 && argc != 3) {
2296f05cddf9SRui Paulo 		printf("Invalid P2P_PROV_DISC command: needs at least "
2297f05cddf9SRui Paulo 		       "two arguments, address and config method\n"
2298f05cddf9SRui Paulo 		       "(display, keypad, or pbc) and an optional join\n");
2299f05cddf9SRui Paulo 		return -1;
2300f05cddf9SRui Paulo 	}
2301f05cddf9SRui Paulo 
2302f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2303f05cddf9SRui Paulo }
2304f05cddf9SRui Paulo 
2305f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])2306f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2307f05cddf9SRui Paulo 					  char *argv[])
2308f05cddf9SRui Paulo {
2309f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2310f05cddf9SRui Paulo }
2311f05cddf9SRui Paulo 
2312f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2313f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2314f05cddf9SRui Paulo 					 char *argv[])
2315f05cddf9SRui Paulo {
2316f05cddf9SRui Paulo 	char cmd[4096];
2317f05cddf9SRui Paulo 
23185b9c547cSRui Paulo 	if (argc < 2) {
2319f05cddf9SRui Paulo 		printf("Invalid P2P_SERV_DISC_REQ command: needs two "
23205b9c547cSRui Paulo 		       "or more arguments (address and TLVs)\n");
2321f05cddf9SRui Paulo 		return -1;
2322f05cddf9SRui Paulo 	}
2323f05cddf9SRui Paulo 
2324f05cddf9SRui Paulo 	if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2325f05cddf9SRui Paulo 		return -1;
2326f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2327f05cddf9SRui Paulo }
2328f05cddf9SRui Paulo 
2329f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2330f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2331f05cddf9SRui Paulo 						int argc, char *argv[])
2332f05cddf9SRui Paulo {
2333f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2334f05cddf9SRui Paulo }
2335f05cddf9SRui Paulo 
2336f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])2337f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2338f05cddf9SRui Paulo 					  char *argv[])
2339f05cddf9SRui Paulo {
2340f05cddf9SRui Paulo 	char cmd[4096];
2341f05cddf9SRui Paulo 	int res;
2342f05cddf9SRui Paulo 
2343f05cddf9SRui Paulo 	if (argc != 4) {
2344f05cddf9SRui Paulo 		printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2345f05cddf9SRui Paulo 		       "arguments (freq, address, dialog token, and TLVs)\n");
2346f05cddf9SRui Paulo 		return -1;
2347f05cddf9SRui Paulo 	}
2348f05cddf9SRui Paulo 
2349f05cddf9SRui Paulo 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2350f05cddf9SRui Paulo 			  argv[0], argv[1], argv[2], argv[3]);
23515b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res))
2352f05cddf9SRui Paulo 		return -1;
2353f05cddf9SRui Paulo 	cmd[sizeof(cmd) - 1] = '\0';
2354f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2355f05cddf9SRui Paulo }
2356f05cddf9SRui Paulo 
2357f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_service_update(struct wpa_ctrl * ctrl,int argc,char * argv[])2358f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2359f05cddf9SRui Paulo 					  char *argv[])
2360f05cddf9SRui Paulo {
2361f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2362f05cddf9SRui Paulo }
2363f05cddf9SRui Paulo 
2364f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl * ctrl,int argc,char * argv[])2365f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2366f05cddf9SRui Paulo 					      int argc, char *argv[])
2367f05cddf9SRui Paulo {
2368f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2369f05cddf9SRui Paulo }
2370f05cddf9SRui Paulo 
2371f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2372f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2373f05cddf9SRui Paulo 					 char *argv[])
2374f05cddf9SRui Paulo {
2375f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2376f05cddf9SRui Paulo }
2377f05cddf9SRui Paulo 
2378f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_service_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2379f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2380f05cddf9SRui Paulo 				       char *argv[])
2381f05cddf9SRui Paulo {
23825b9c547cSRui Paulo 	if (argc < 3) {
23835b9c547cSRui Paulo 		printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
23845b9c547cSRui Paulo 		return -1;
23855b9c547cSRui Paulo 	}
2386f05cddf9SRui Paulo 
23875b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
23885b9c547cSRui Paulo }
23895b9c547cSRui Paulo 
23905b9c547cSRui Paulo 
wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl * ctrl,int argc,char * argv[])23915b9c547cSRui Paulo static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
23925b9c547cSRui Paulo 				       char *argv[])
23935b9c547cSRui Paulo {
23945b9c547cSRui Paulo 	if (argc < 5 || argc > 6) {
23955b9c547cSRui Paulo 		printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2396f05cddf9SRui Paulo 		       "arguments\n");
2397f05cddf9SRui Paulo 		return -1;
2398f05cddf9SRui Paulo 	}
2399f05cddf9SRui Paulo 
24005b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2401f05cddf9SRui Paulo }
2402f05cddf9SRui Paulo 
2403f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_service_del(struct wpa_ctrl * ctrl,int argc,char * argv[])2404f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2405f05cddf9SRui Paulo 				       char *argv[])
2406f05cddf9SRui Paulo {
2407f05cddf9SRui Paulo 	char cmd[4096];
2408f05cddf9SRui Paulo 	int res;
2409f05cddf9SRui Paulo 
2410f05cddf9SRui Paulo 	if (argc != 2 && argc != 3) {
2411f05cddf9SRui Paulo 		printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2412f05cddf9SRui Paulo 		       "arguments\n");
2413f05cddf9SRui Paulo 		return -1;
2414f05cddf9SRui Paulo 	}
2415f05cddf9SRui Paulo 
2416f05cddf9SRui Paulo 	if (argc == 3)
2417f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd),
2418f05cddf9SRui Paulo 				  "P2P_SERVICE_DEL %s %s %s",
2419f05cddf9SRui Paulo 				  argv[0], argv[1], argv[2]);
2420f05cddf9SRui Paulo 	else
2421f05cddf9SRui Paulo 		res = os_snprintf(cmd, sizeof(cmd),
2422f05cddf9SRui Paulo 				  "P2P_SERVICE_DEL %s %s",
2423f05cddf9SRui Paulo 				  argv[0], argv[1]);
24245b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res))
2425f05cddf9SRui Paulo 		return -1;
2426f05cddf9SRui Paulo 	cmd[sizeof(cmd) - 1] = '\0';
2427f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2428f05cddf9SRui Paulo }
2429f05cddf9SRui Paulo 
2430f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_reject(struct wpa_ctrl * ctrl,int argc,char * argv[])2431f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2432f05cddf9SRui Paulo 				  int argc, char *argv[])
2433f05cddf9SRui Paulo {
2434f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2435f05cddf9SRui Paulo }
2436f05cddf9SRui Paulo 
2437f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_invite(struct wpa_ctrl * ctrl,int argc,char * argv[])2438f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2439f05cddf9SRui Paulo 				  int argc, char *argv[])
2440f05cddf9SRui Paulo {
2441f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2442f05cddf9SRui Paulo }
2443f05cddf9SRui Paulo 
2444f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_peer(struct wpa_ctrl * ctrl,int argc,char * argv[])2445f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2446f05cddf9SRui Paulo {
2447f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2448f05cddf9SRui Paulo }
2449f05cddf9SRui Paulo 
2450f05cddf9SRui Paulo 
wpa_cli_complete_p2p_peer(const char * str,int pos)2451f05cddf9SRui Paulo static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2452f05cddf9SRui Paulo {
2453f05cddf9SRui Paulo 	int arg = get_cmd_arg_num(str, pos);
2454f05cddf9SRui Paulo 	char **res = NULL;
2455f05cddf9SRui Paulo 
2456f05cddf9SRui Paulo 	switch (arg) {
2457f05cddf9SRui Paulo 	case 1:
2458f05cddf9SRui Paulo 		res = cli_txt_list_array(&p2p_peers);
2459f05cddf9SRui Paulo 		break;
2460f05cddf9SRui Paulo 	}
2461f05cddf9SRui Paulo 
2462f05cddf9SRui Paulo 	return res;
2463f05cddf9SRui Paulo }
2464f05cddf9SRui Paulo 
2465f05cddf9SRui Paulo 
wpa_ctrl_command_p2p_peer(struct wpa_ctrl * ctrl,const char * cmd,char * addr,size_t addr_len,int discovered)246685732ac8SCy Schubert static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd,
2467f05cddf9SRui Paulo 				     char *addr, size_t addr_len,
2468f05cddf9SRui Paulo 				     int discovered)
2469f05cddf9SRui Paulo {
2470f05cddf9SRui Paulo 	char buf[4096], *pos;
2471f05cddf9SRui Paulo 	size_t len;
2472f05cddf9SRui Paulo 	int ret;
2473f05cddf9SRui Paulo 
2474f05cddf9SRui Paulo 	if (ctrl_conn == NULL)
2475f05cddf9SRui Paulo 		return -1;
2476f05cddf9SRui Paulo 	len = sizeof(buf) - 1;
2477f05cddf9SRui Paulo 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2478f05cddf9SRui Paulo 			       wpa_cli_msg_cb);
2479f05cddf9SRui Paulo 	if (ret == -2) {
2480f05cddf9SRui Paulo 		printf("'%s' command timed out.\n", cmd);
2481f05cddf9SRui Paulo 		return -2;
2482f05cddf9SRui Paulo 	} else if (ret < 0) {
2483f05cddf9SRui Paulo 		printf("'%s' command failed.\n", cmd);
2484f05cddf9SRui Paulo 		return -1;
2485f05cddf9SRui Paulo 	}
2486f05cddf9SRui Paulo 
2487f05cddf9SRui Paulo 	buf[len] = '\0';
2488f05cddf9SRui Paulo 	if (os_memcmp(buf, "FAIL", 4) == 0)
2489f05cddf9SRui Paulo 		return -1;
2490f05cddf9SRui Paulo 
2491f05cddf9SRui Paulo 	pos = buf;
2492f05cddf9SRui Paulo 	while (*pos != '\0' && *pos != '\n')
2493f05cddf9SRui Paulo 		pos++;
2494f05cddf9SRui Paulo 	*pos++ = '\0';
2495f05cddf9SRui Paulo 	os_strlcpy(addr, buf, addr_len);
2496f05cddf9SRui Paulo 	if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2497f05cddf9SRui Paulo 		printf("%s\n", addr);
2498f05cddf9SRui Paulo 	return 0;
2499f05cddf9SRui Paulo }
2500f05cddf9SRui Paulo 
2501f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_peers(struct wpa_ctrl * ctrl,int argc,char * argv[])2502f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2503f05cddf9SRui Paulo {
2504f05cddf9SRui Paulo 	char addr[32], cmd[64];
2505f05cddf9SRui Paulo 	int discovered;
2506f05cddf9SRui Paulo 
2507f05cddf9SRui Paulo 	discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2508f05cddf9SRui Paulo 
2509f05cddf9SRui Paulo 	if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2510f05cddf9SRui Paulo 				      addr, sizeof(addr), discovered))
2511f05cddf9SRui Paulo 		return -1;
2512f05cddf9SRui Paulo 	do {
2513f05cddf9SRui Paulo 		os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2514f05cddf9SRui Paulo 	} while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2515f05cddf9SRui Paulo 			 discovered) == 0);
2516f05cddf9SRui Paulo 
2517f05cddf9SRui Paulo 	return 0;
2518f05cddf9SRui Paulo }
2519f05cddf9SRui Paulo 
2520f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_set(struct wpa_ctrl * ctrl,int argc,char * argv[])2521f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2522f05cddf9SRui Paulo {
2523f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2524f05cddf9SRui Paulo }
2525f05cddf9SRui Paulo 
2526f05cddf9SRui Paulo 
wpa_cli_complete_p2p_set(const char * str,int pos)25275b9c547cSRui Paulo static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
25285b9c547cSRui Paulo {
25295b9c547cSRui Paulo 	int arg = get_cmd_arg_num(str, pos);
25305b9c547cSRui Paulo 	const char *fields[] = {
25315b9c547cSRui Paulo 		"discoverability",
25325b9c547cSRui Paulo 		"managed",
25335b9c547cSRui Paulo 		"listen_channel",
25345b9c547cSRui Paulo 		"ssid_postfix",
25355b9c547cSRui Paulo 		"noa",
25365b9c547cSRui Paulo 		"ps",
25375b9c547cSRui Paulo 		"oppps",
25385b9c547cSRui Paulo 		"ctwindow",
25395b9c547cSRui Paulo 		"disabled",
25405b9c547cSRui Paulo 		"conc_pref",
25415b9c547cSRui Paulo 		"force_long_sd",
25425b9c547cSRui Paulo 		"peer_filter",
25435b9c547cSRui Paulo 		"cross_connect",
25445b9c547cSRui Paulo 		"go_apsd",
25455b9c547cSRui Paulo 		"client_apsd",
25465b9c547cSRui Paulo 		"disallow_freq",
25475b9c547cSRui Paulo 		"disc_int",
25485b9c547cSRui Paulo 		"per_sta_psk",
25495b9c547cSRui Paulo 	};
25505b9c547cSRui Paulo 	int i, num_fields = ARRAY_SIZE(fields);
25515b9c547cSRui Paulo 
25525b9c547cSRui Paulo 	if (arg == 1) {
25535b9c547cSRui Paulo 		char **res = os_calloc(num_fields + 1, sizeof(char *));
25545b9c547cSRui Paulo 		if (res == NULL)
25555b9c547cSRui Paulo 			return NULL;
25565b9c547cSRui Paulo 		for (i = 0; i < num_fields; i++) {
25575b9c547cSRui Paulo 			res[i] = os_strdup(fields[i]);
25585b9c547cSRui Paulo 			if (res[i] == NULL)
25595b9c547cSRui Paulo 				return res;
25605b9c547cSRui Paulo 		}
25615b9c547cSRui Paulo 		return res;
25625b9c547cSRui Paulo 	}
25635b9c547cSRui Paulo 
25645b9c547cSRui Paulo 	if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
25655b9c547cSRui Paulo 		return cli_txt_list_array(&p2p_peers);
25665b9c547cSRui Paulo 
25675b9c547cSRui Paulo 	return NULL;
25685b9c547cSRui Paulo }
25695b9c547cSRui Paulo 
25705b9c547cSRui Paulo 
wpa_cli_cmd_p2p_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2571f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2572f05cddf9SRui Paulo {
2573f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2574f05cddf9SRui Paulo }
2575f05cddf9SRui Paulo 
2576f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_cancel(struct wpa_ctrl * ctrl,int argc,char * argv[])2577f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2578f05cddf9SRui Paulo 				  char *argv[])
2579f05cddf9SRui Paulo {
2580f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2581f05cddf9SRui Paulo }
2582f05cddf9SRui Paulo 
2583f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl * ctrl,int argc,char * argv[])2584f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2585f05cddf9SRui Paulo 				       char *argv[])
2586f05cddf9SRui Paulo {
2587f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2588f05cddf9SRui Paulo }
2589f05cddf9SRui Paulo 
2590f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2591f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2592f05cddf9SRui Paulo 					char *argv[])
2593f05cddf9SRui Paulo {
2594f05cddf9SRui Paulo 	if (argc != 0 && argc != 2 && argc != 4) {
2595f05cddf9SRui Paulo 		printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2596f05cddf9SRui Paulo 		       "(preferred duration, interval; in microsecods).\n"
2597f05cddf9SRui Paulo 		       "Optional second pair can be used to provide "
2598f05cddf9SRui Paulo 		       "acceptable values.\n");
2599f05cddf9SRui Paulo 		return -1;
2600f05cddf9SRui Paulo 	}
2601f05cddf9SRui Paulo 
2602f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2603f05cddf9SRui Paulo }
2604f05cddf9SRui Paulo 
2605f05cddf9SRui Paulo 
wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])2606f05cddf9SRui Paulo static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2607f05cddf9SRui Paulo 				      char *argv[])
2608f05cddf9SRui Paulo {
2609f05cddf9SRui Paulo 	if (argc != 0 && argc != 2) {
2610f05cddf9SRui Paulo 		printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2611f05cddf9SRui Paulo 		       "(availability period, availability interval; in "
2612f05cddf9SRui Paulo 		       "millisecods).\n"
2613f05cddf9SRui Paulo 		       "Extended Listen Timing can be cancelled with this "
2614f05cddf9SRui Paulo 		       "command when used without parameters.\n");
2615f05cddf9SRui Paulo 		return -1;
2616f05cddf9SRui Paulo 	}
2617f05cddf9SRui Paulo 
2618f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2619f05cddf9SRui Paulo }
2620f05cddf9SRui Paulo 
26215b9c547cSRui Paulo 
wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl * ctrl,int argc,char * argv[])26225b9c547cSRui Paulo static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
26235b9c547cSRui Paulo 					 char *argv[])
26245b9c547cSRui Paulo {
26255b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
26265b9c547cSRui Paulo }
26275b9c547cSRui Paulo 
262885732ac8SCy Schubert #endif /* CONFIG_P2P */
262985732ac8SCy Schubert 
2630780fb4a2SCy Schubert 
wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2631780fb4a2SCy Schubert static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
2632780fb4a2SCy Schubert 				       char *argv[])
2633780fb4a2SCy Schubert {
2634780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
2635780fb4a2SCy Schubert }
2636780fb4a2SCy Schubert 
2637780fb4a2SCy Schubert 
wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2638780fb4a2SCy Schubert static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
2639780fb4a2SCy Schubert 				       char *argv[])
2640780fb4a2SCy Schubert {
2641780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
2642780fb4a2SCy Schubert }
2643780fb4a2SCy Schubert 
2644780fb4a2SCy Schubert 
wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2645780fb4a2SCy Schubert static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
2646780fb4a2SCy Schubert 					  char *argv[])
2647780fb4a2SCy Schubert {
2648780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
2649780fb4a2SCy Schubert }
2650780fb4a2SCy Schubert 
2651f05cddf9SRui Paulo 
2652f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
2653f05cddf9SRui Paulo 
wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl * ctrl,int argc,char * argv[])2654f05cddf9SRui Paulo static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2655f05cddf9SRui Paulo 				       char *argv[])
2656f05cddf9SRui Paulo {
2657f05cddf9SRui Paulo 	char cmd[100];
2658f05cddf9SRui Paulo 	int res;
2659f05cddf9SRui Paulo 
2660f05cddf9SRui Paulo 	if (argc != 1 && argc != 2) {
2661f05cddf9SRui Paulo 		printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2662f05cddf9SRui Paulo 		       "arguments (subelem, hexdump)\n");
2663f05cddf9SRui Paulo 		return -1;
2664f05cddf9SRui Paulo 	}
2665f05cddf9SRui Paulo 
2666f05cddf9SRui Paulo 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2667f05cddf9SRui Paulo 			  argv[0], argc > 1 ? argv[1] : "");
26685b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res))
2669f05cddf9SRui Paulo 		return -1;
2670f05cddf9SRui Paulo 	cmd[sizeof(cmd) - 1] = '\0';
2671f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2672f05cddf9SRui Paulo }
2673f05cddf9SRui Paulo 
2674f05cddf9SRui Paulo 
wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2675f05cddf9SRui Paulo static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2676f05cddf9SRui Paulo 				       char *argv[])
2677f05cddf9SRui Paulo {
2678f05cddf9SRui Paulo 	char cmd[100];
2679e28a4053SRui Paulo 	int res;
2680e28a4053SRui Paulo 
2681e28a4053SRui Paulo 	if (argc != 1) {
2682f05cddf9SRui Paulo 		printf("Invalid WFD_SUBELEM_GET command: needs one "
2683f05cddf9SRui Paulo 		       "argument (subelem)\n");
2684e28a4053SRui Paulo 		return -1;
2685e28a4053SRui Paulo 	}
2686e28a4053SRui Paulo 
2687f05cddf9SRui Paulo 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2688f05cddf9SRui Paulo 			  argv[0]);
26895b9c547cSRui Paulo 	if (os_snprintf_error(sizeof(cmd), res))
2690f05cddf9SRui Paulo 		return -1;
2691f05cddf9SRui Paulo 	cmd[sizeof(cmd) - 1] = '\0';
2692f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2693f05cddf9SRui Paulo }
2694f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
2695f05cddf9SRui Paulo 
2696f05cddf9SRui Paulo 
2697f05cddf9SRui Paulo #ifdef CONFIG_INTERWORKING
wpa_cli_cmd_fetch_anqp(struct wpa_ctrl * ctrl,int argc,char * argv[])2698f05cddf9SRui Paulo static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2699f05cddf9SRui Paulo 				  char *argv[])
2700f05cddf9SRui Paulo {
2701f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2702f05cddf9SRui Paulo }
2703f05cddf9SRui Paulo 
2704f05cddf9SRui Paulo 
wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl * ctrl,int argc,char * argv[])2705f05cddf9SRui Paulo static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2706f05cddf9SRui Paulo 				       char *argv[])
2707f05cddf9SRui Paulo {
2708f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2709f05cddf9SRui Paulo }
2710f05cddf9SRui Paulo 
2711f05cddf9SRui Paulo 
wpa_cli_cmd_interworking_select(struct wpa_ctrl * ctrl,int argc,char * argv[])2712f05cddf9SRui Paulo static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2713f05cddf9SRui Paulo 					   char *argv[])
2714f05cddf9SRui Paulo {
2715f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2716f05cddf9SRui Paulo }
2717f05cddf9SRui Paulo 
2718f05cddf9SRui Paulo 
wpa_cli_cmd_interworking_connect(struct wpa_ctrl * ctrl,int argc,char * argv[])2719f05cddf9SRui Paulo static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2720f05cddf9SRui Paulo 					    char *argv[])
2721f05cddf9SRui Paulo {
2722f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2723f05cddf9SRui Paulo }
2724f05cddf9SRui Paulo 
2725f05cddf9SRui Paulo 
wpa_cli_cmd_interworking_add_network(struct wpa_ctrl * ctrl,int argc,char * argv[])27265b9c547cSRui Paulo static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
27275b9c547cSRui Paulo 						char *argv[])
27285b9c547cSRui Paulo {
27295b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
27305b9c547cSRui Paulo }
27315b9c547cSRui Paulo 
27325b9c547cSRui Paulo 
wpa_cli_cmd_anqp_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2733f05cddf9SRui Paulo static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2734f05cddf9SRui Paulo {
2735f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2736f05cddf9SRui Paulo }
2737f05cddf9SRui Paulo 
2738f05cddf9SRui Paulo 
wpa_cli_cmd_gas_request(struct wpa_ctrl * ctrl,int argc,char * argv[])2739f05cddf9SRui Paulo static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2740f05cddf9SRui Paulo 				   char *argv[])
2741f05cddf9SRui Paulo {
2742f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2743f05cddf9SRui Paulo }
2744f05cddf9SRui Paulo 
2745f05cddf9SRui Paulo 
wpa_cli_cmd_gas_response_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2746f05cddf9SRui Paulo static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2747f05cddf9SRui Paulo 					char *argv[])
2748f05cddf9SRui Paulo {
2749f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2750f05cddf9SRui Paulo }
2751f05cddf9SRui Paulo #endif /* CONFIG_INTERWORKING */
2752f05cddf9SRui Paulo 
2753f05cddf9SRui Paulo 
2754f05cddf9SRui Paulo #ifdef CONFIG_HS20
2755f05cddf9SRui Paulo 
wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2756f05cddf9SRui Paulo static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2757f05cddf9SRui Paulo 				     char *argv[])
2758f05cddf9SRui Paulo {
2759f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2760f05cddf9SRui Paulo }
2761f05cddf9SRui Paulo 
2762f05cddf9SRui Paulo 
wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl * ctrl,int argc,char * argv[])2763f05cddf9SRui Paulo static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2764f05cddf9SRui Paulo 					       char *argv[])
2765f05cddf9SRui Paulo {
2766f05cddf9SRui Paulo 	char cmd[512];
2767f05cddf9SRui Paulo 
2768f05cddf9SRui Paulo 	if (argc == 0) {
2769f05cddf9SRui Paulo 		printf("Command needs one or two arguments (dst mac addr and "
2770f05cddf9SRui Paulo 		       "optional home realm)\n");
2771e28a4053SRui Paulo 		return -1;
2772e28a4053SRui Paulo 	}
2773f05cddf9SRui Paulo 
2774f05cddf9SRui Paulo 	if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2775f05cddf9SRui Paulo 		      argc, argv) < 0)
2776f05cddf9SRui Paulo 		return -1;
2777f05cddf9SRui Paulo 
2778e28a4053SRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
2779e28a4053SRui Paulo }
2780e28a4053SRui Paulo 
27815b9c547cSRui Paulo 
wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl * ctrl,int argc,char * argv[])27825b9c547cSRui Paulo static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
27835b9c547cSRui Paulo 					 char *argv[])
27845b9c547cSRui Paulo {
27855b9c547cSRui Paulo 	char cmd[512];
27865b9c547cSRui Paulo 
27875b9c547cSRui Paulo 	if (argc < 2) {
27885b9c547cSRui Paulo 		printf("Command needs two arguments (dst mac addr and "
27895b9c547cSRui Paulo 		       "icon name)\n");
27905b9c547cSRui Paulo 		return -1;
27915b9c547cSRui Paulo 	}
27925b9c547cSRui Paulo 
27935b9c547cSRui Paulo 	if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
27945b9c547cSRui Paulo 		return -1;
27955b9c547cSRui Paulo 
27965b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, cmd);
27975b9c547cSRui Paulo }
27985b9c547cSRui Paulo 
27995b9c547cSRui Paulo 
wpa_cli_cmd_fetch_osu(struct wpa_ctrl * ctrl,int argc,char * argv[])28005b9c547cSRui Paulo static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
28015b9c547cSRui Paulo {
28025b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "FETCH_OSU");
28035b9c547cSRui Paulo }
28045b9c547cSRui Paulo 
28055b9c547cSRui Paulo 
wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl * ctrl,int argc,char * argv[])28065b9c547cSRui Paulo static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
28075b9c547cSRui Paulo 					char *argv[])
28085b9c547cSRui Paulo {
28095b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
28105b9c547cSRui Paulo }
28115b9c547cSRui Paulo 
2812f05cddf9SRui Paulo #endif /* CONFIG_HS20 */
2813f05cddf9SRui Paulo 
2814f05cddf9SRui Paulo 
wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])2815f05cddf9SRui Paulo static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2816f05cddf9SRui Paulo 				       char *argv[])
2817f05cddf9SRui Paulo {
2818f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2819f05cddf9SRui Paulo }
2820f05cddf9SRui Paulo 
2821f05cddf9SRui Paulo 
wpa_cli_cmd_tdls_discover(struct wpa_ctrl * ctrl,int argc,char * argv[])2822f05cddf9SRui Paulo static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2823f05cddf9SRui Paulo 				     char *argv[])
2824f05cddf9SRui Paulo {
2825f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2826f05cddf9SRui Paulo }
2827f05cddf9SRui Paulo 
2828f05cddf9SRui Paulo 
wpa_cli_cmd_tdls_setup(struct wpa_ctrl * ctrl,int argc,char * argv[])2829f05cddf9SRui Paulo static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2830f05cddf9SRui Paulo 				  char *argv[])
2831f05cddf9SRui Paulo {
2832f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2833f05cddf9SRui Paulo }
2834f05cddf9SRui Paulo 
2835f05cddf9SRui Paulo 
wpa_cli_cmd_tdls_teardown(struct wpa_ctrl * ctrl,int argc,char * argv[])2836f05cddf9SRui Paulo static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2837f05cddf9SRui Paulo 				     char *argv[])
2838f05cddf9SRui Paulo {
2839f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2840f05cddf9SRui Paulo }
2841f05cddf9SRui Paulo 
2842f05cddf9SRui Paulo 
wpa_cli_cmd_tdls_link_status(struct wpa_ctrl * ctrl,int argc,char * argv[])2843325151a3SRui Paulo static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
2844325151a3SRui Paulo 					char *argv[])
2845325151a3SRui Paulo {
2846325151a3SRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
2847325151a3SRui Paulo }
2848325151a3SRui Paulo 
2849325151a3SRui Paulo 
2850*a90b9d01SCy Schubert #ifndef CONFIG_NO_WMM_AC
2851*a90b9d01SCy Schubert 
wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl * ctrl,int argc,char * argv[])28525b9c547cSRui Paulo static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
28535b9c547cSRui Paulo 				    char *argv[])
28545b9c547cSRui Paulo {
28555b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
28565b9c547cSRui Paulo }
28575b9c547cSRui Paulo 
28585b9c547cSRui Paulo 
wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl * ctrl,int argc,char * argv[])28595b9c547cSRui Paulo static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
28605b9c547cSRui Paulo 				    char *argv[])
28615b9c547cSRui Paulo {
28625b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
28635b9c547cSRui Paulo }
28645b9c547cSRui Paulo 
28655b9c547cSRui Paulo 
wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl * ctrl,int argc,char * argv[])28665b9c547cSRui Paulo static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
28675b9c547cSRui Paulo 				    char *argv[])
28685b9c547cSRui Paulo {
28695b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
28705b9c547cSRui Paulo }
28715b9c547cSRui Paulo 
2872*a90b9d01SCy Schubert #endif /* CONFIG_NO_WMM_AC */
2873*a90b9d01SCy Schubert 
28745b9c547cSRui Paulo 
wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl * ctrl,int argc,char * argv[])28755b9c547cSRui Paulo static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
28765b9c547cSRui Paulo 					char *argv[])
28775b9c547cSRui Paulo {
28785b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
28795b9c547cSRui Paulo }
28805b9c547cSRui Paulo 
28815b9c547cSRui Paulo 
wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl * ctrl,int argc,char * argv[])28825b9c547cSRui Paulo static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
28835b9c547cSRui Paulo 					       char *argv[])
28845b9c547cSRui Paulo {
28855b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
28865b9c547cSRui Paulo }
28875b9c547cSRui Paulo 
28885b9c547cSRui Paulo 
wpa_cli_cmd_signal_poll(struct wpa_ctrl * ctrl,int argc,char * argv[])2889f05cddf9SRui Paulo static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2890f05cddf9SRui Paulo 				   char *argv[])
2891f05cddf9SRui Paulo {
2892f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2893f05cddf9SRui Paulo }
2894f05cddf9SRui Paulo 
2895f05cddf9SRui Paulo 
wpa_cli_cmd_signal_monitor(struct wpa_ctrl * ctrl,int argc,char * argv[])2896780fb4a2SCy Schubert static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
2897780fb4a2SCy Schubert 				   char *argv[])
2898780fb4a2SCy Schubert {
2899780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
2900780fb4a2SCy Schubert }
2901780fb4a2SCy Schubert 
2902780fb4a2SCy Schubert 
wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl * ctrl,int argc,char * argv[])2903f05cddf9SRui Paulo static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2904f05cddf9SRui Paulo 				   char *argv[])
2905f05cddf9SRui Paulo {
2906f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2907f05cddf9SRui Paulo }
2908f05cddf9SRui Paulo 
2909f05cddf9SRui Paulo 
wpa_cli_cmd_reauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])2910f05cddf9SRui Paulo static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2911f05cddf9SRui Paulo 				      char *argv[])
2912f05cddf9SRui Paulo {
2913f05cddf9SRui Paulo 	return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2914f05cddf9SRui Paulo }
2915f05cddf9SRui Paulo 
2916f05cddf9SRui Paulo 
2917f05cddf9SRui Paulo #ifdef CONFIG_AUTOSCAN
2918f05cddf9SRui Paulo 
wpa_cli_cmd_autoscan(struct wpa_ctrl * ctrl,int argc,char * argv[])2919f05cddf9SRui Paulo static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2920f05cddf9SRui Paulo {
2921f05cddf9SRui Paulo 	if (argc == 0)
2922f05cddf9SRui Paulo 		return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2923f05cddf9SRui Paulo 
2924f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2925f05cddf9SRui Paulo }
2926f05cddf9SRui Paulo 
2927f05cddf9SRui Paulo #endif /* CONFIG_AUTOSCAN */
2928f05cddf9SRui Paulo 
2929f05cddf9SRui Paulo 
2930f05cddf9SRui Paulo #ifdef CONFIG_WNM
2931f05cddf9SRui Paulo 
wpa_cli_cmd_wnm_sleep(struct wpa_ctrl * ctrl,int argc,char * argv[])2932f05cddf9SRui Paulo static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2933f05cddf9SRui Paulo {
2934f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2935f05cddf9SRui Paulo }
2936f05cddf9SRui Paulo 
29375b9c547cSRui Paulo 
wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl * ctrl,int argc,char * argv[])29385b9c547cSRui Paulo static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
29395b9c547cSRui Paulo {
29405b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
29415b9c547cSRui Paulo }
29425b9c547cSRui Paulo 
2943f05cddf9SRui Paulo #endif /* CONFIG_WNM */
2944f05cddf9SRui Paulo 
2945f05cddf9SRui Paulo 
2946*a90b9d01SCy Schubert #ifdef CONFIG_WNM_AP
2947*a90b9d01SCy Schubert 
wpa_cli_cmd_disassoc_imminent(struct wpa_ctrl * ctrl,int argc,char * argv[])2948*a90b9d01SCy Schubert static int wpa_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
2949*a90b9d01SCy Schubert 					 char *argv[])
2950*a90b9d01SCy Schubert {
2951*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "DISASSOC_IMMINENT", 2, argc, argv);
2952*a90b9d01SCy Schubert }
2953*a90b9d01SCy Schubert 
2954*a90b9d01SCy Schubert 
wpa_cli_cmd_ess_disassoc(struct wpa_ctrl * ctrl,int argc,char * argv[])2955*a90b9d01SCy Schubert static int wpa_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
2956*a90b9d01SCy Schubert 				    char *argv[])
2957*a90b9d01SCy Schubert {
2958*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "ESS_DISASSOC", 3, argc, argv);
2959*a90b9d01SCy Schubert }
2960*a90b9d01SCy Schubert 
2961*a90b9d01SCy Schubert 
wpa_cli_cmd_bss_tm_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2962*a90b9d01SCy Schubert static int wpa_cli_cmd_bss_tm_req(struct wpa_ctrl *ctrl, int argc,
2963*a90b9d01SCy Schubert 				  char *argv[])
2964*a90b9d01SCy Schubert {
2965*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "BSS_TM_REQ", 1, argc, argv);
2966*a90b9d01SCy Schubert }
2967*a90b9d01SCy Schubert 
2968*a90b9d01SCy Schubert #endif /* CONFIG_WNM_AP */
2969*a90b9d01SCy Schubert 
2970*a90b9d01SCy Schubert 
wpa_cli_cmd_raw(struct wpa_ctrl * ctrl,int argc,char * argv[])2971f05cddf9SRui Paulo static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2972f05cddf9SRui Paulo {
2973f05cddf9SRui Paulo 	if (argc == 0)
2974f05cddf9SRui Paulo 		return -1;
2975f05cddf9SRui Paulo 	return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2976f05cddf9SRui Paulo }
2977f05cddf9SRui Paulo 
2978e28a4053SRui Paulo 
29795b9c547cSRui Paulo #ifdef ANDROID
wpa_cli_cmd_driver(struct wpa_ctrl * ctrl,int argc,char * argv[])29805b9c547cSRui Paulo static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
29815b9c547cSRui Paulo {
29825b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
29835b9c547cSRui Paulo }
29845b9c547cSRui Paulo #endif /* ANDROID */
29855b9c547cSRui Paulo 
29865b9c547cSRui Paulo 
wpa_cli_cmd_vendor(struct wpa_ctrl * ctrl,int argc,char * argv[])29875b9c547cSRui Paulo static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
29885b9c547cSRui Paulo {
29895b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
29905b9c547cSRui Paulo }
29915b9c547cSRui Paulo 
29925b9c547cSRui Paulo 
wpa_cli_cmd_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])29935b9c547cSRui Paulo static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
29945b9c547cSRui Paulo {
29955b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "FLUSH");
29965b9c547cSRui Paulo }
29975b9c547cSRui Paulo 
29985b9c547cSRui Paulo 
wpa_cli_cmd_radio_work(struct wpa_ctrl * ctrl,int argc,char * argv[])29995b9c547cSRui Paulo static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
30005b9c547cSRui Paulo {
30015b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
30025b9c547cSRui Paulo }
30035b9c547cSRui Paulo 
30045b9c547cSRui Paulo 
wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl * ctrl,int argc,char * argv[])30055b9c547cSRui Paulo static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
30065b9c547cSRui Paulo 					    char *argv[])
30075b9c547cSRui Paulo {
30085b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
30095b9c547cSRui Paulo }
30105b9c547cSRui Paulo 
30115b9c547cSRui Paulo 
wpa_cli_cmd_twt_setup(struct wpa_ctrl * ctrl,int argc,char * argv[])3012c1d255d3SCy Schubert static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc,
3013c1d255d3SCy Schubert 				 char *argv[])
3014c1d255d3SCy Schubert {
3015c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv);
3016c1d255d3SCy Schubert }
3017c1d255d3SCy Schubert 
3018c1d255d3SCy Schubert 
wpa_cli_cmd_twt_teardown(struct wpa_ctrl * ctrl,int argc,char * argv[])3019c1d255d3SCy Schubert static int wpa_cli_cmd_twt_teardown(struct wpa_ctrl *ctrl, int argc,
3020c1d255d3SCy Schubert 				    char *argv[])
3021c1d255d3SCy Schubert {
3022c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "TWT_TEARDOWN", 0, argc, argv);
3023c1d255d3SCy Schubert }
3024c1d255d3SCy Schubert 
3025c1d255d3SCy Schubert 
wpa_cli_cmd_erp_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])30265b9c547cSRui Paulo static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
30275b9c547cSRui Paulo {
30285b9c547cSRui Paulo 	return wpa_ctrl_command(ctrl, "ERP_FLUSH");
30295b9c547cSRui Paulo }
30305b9c547cSRui Paulo 
30315b9c547cSRui Paulo 
wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])30325b9c547cSRui Paulo static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
30335b9c547cSRui Paulo 				     char *argv[])
30345b9c547cSRui Paulo {
30355b9c547cSRui Paulo 	return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
30365b9c547cSRui Paulo }
30375b9c547cSRui Paulo 
30385b9c547cSRui Paulo 
wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl * ctrl,int argc,char * argv[])3039325151a3SRui Paulo static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
3040325151a3SRui Paulo 					  char *argv[])
3041325151a3SRui Paulo {
3042325151a3SRui Paulo 	return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
3043325151a3SRui Paulo }
3044325151a3SRui Paulo 
3045325151a3SRui Paulo 
wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl * ctrl,int argc,char * argv[])3046780fb4a2SCy Schubert static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc,
3047780fb4a2SCy Schubert 				    char *argv[])
3048780fb4a2SCy Schubert {
3049780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv);
3050780fb4a2SCy Schubert }
3051780fb4a2SCy Schubert 
3052780fb4a2SCy Schubert 
wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])3053780fb4a2SCy Schubert static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc,
3054780fb4a2SCy Schubert 				   char *argv[])
3055780fb4a2SCy Schubert {
3056780fb4a2SCy Schubert 	return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv);
3057780fb4a2SCy Schubert }
3058780fb4a2SCy Schubert 
3059780fb4a2SCy Schubert 
306085732ac8SCy Schubert #ifdef CONFIG_DPP
306185732ac8SCy Schubert 
wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl * ctrl,int argc,char * argv[])306285732ac8SCy Schubert static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
306385732ac8SCy Schubert 				   char *argv[])
306485732ac8SCy Schubert {
306585732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv);
306685732ac8SCy Schubert }
306785732ac8SCy Schubert 
306885732ac8SCy Schubert 
wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl * ctrl,int argc,char * argv[])306985732ac8SCy Schubert static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc,
307085732ac8SCy Schubert 					 char *argv[])
307185732ac8SCy Schubert {
307285732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv);
307385732ac8SCy Schubert }
307485732ac8SCy Schubert 
307585732ac8SCy Schubert 
wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])307685732ac8SCy Schubert static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc,
307785732ac8SCy Schubert 					    char *argv[])
307885732ac8SCy Schubert {
307985732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv);
308085732ac8SCy Schubert }
308185732ac8SCy Schubert 
308285732ac8SCy Schubert 
wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl * ctrl,int argc,char * argv[])308385732ac8SCy Schubert static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc,
308485732ac8SCy Schubert 					     char *argv[])
308585732ac8SCy Schubert {
308685732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv);
308785732ac8SCy Schubert }
308885732ac8SCy Schubert 
308985732ac8SCy Schubert 
wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl * ctrl,int argc,char * argv[])309085732ac8SCy Schubert static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc,
309185732ac8SCy Schubert 					  char *argv[])
309285732ac8SCy Schubert {
309385732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv);
309485732ac8SCy Schubert }
309585732ac8SCy Schubert 
309685732ac8SCy Schubert 
wpa_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl * ctrl,int argc,char * argv[])3097c1d255d3SCy Schubert static int wpa_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl *ctrl, int argc,
3098c1d255d3SCy Schubert 					 char *argv[])
3099c1d255d3SCy Schubert {
3100c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_SET", 1, argc, argv);
3101c1d255d3SCy Schubert }
3102c1d255d3SCy Schubert 
3103c1d255d3SCy Schubert 
wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl * ctrl,int argc,char * argv[])310485732ac8SCy Schubert static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc,
310585732ac8SCy Schubert 				     char *argv[])
310685732ac8SCy Schubert {
310785732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv);
310885732ac8SCy Schubert }
310985732ac8SCy Schubert 
311085732ac8SCy Schubert 
wpa_cli_cmd_dpp_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])311185732ac8SCy Schubert static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc,
311285732ac8SCy Schubert 				  char *argv[])
311385732ac8SCy Schubert {
311485732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv);
311585732ac8SCy Schubert }
311685732ac8SCy Schubert 
311785732ac8SCy Schubert 
wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])311885732ac8SCy Schubert static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc,
311985732ac8SCy Schubert 				       char *argv[])
312085732ac8SCy Schubert {
312185732ac8SCy Schubert 	return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN");
312285732ac8SCy Schubert }
312385732ac8SCy Schubert 
312485732ac8SCy Schubert 
wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl * ctrl,int argc,char * argv[])312585732ac8SCy Schubert static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc,
312685732ac8SCy Schubert 					    char *argv[])
312785732ac8SCy Schubert {
312885732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv);
312985732ac8SCy Schubert }
313085732ac8SCy Schubert 
313185732ac8SCy Schubert 
wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])313285732ac8SCy Schubert static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc,
313385732ac8SCy Schubert 					       char *argv[])
313485732ac8SCy Schubert {
313585732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv);
313685732ac8SCy Schubert }
313785732ac8SCy Schubert 
313885732ac8SCy Schubert 
wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl * ctrl,int argc,char * argv[])313985732ac8SCy Schubert static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc,
314085732ac8SCy Schubert 						char *argv[])
314185732ac8SCy Schubert {
314285732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv);
314385732ac8SCy Schubert }
314485732ac8SCy Schubert 
314585732ac8SCy Schubert 
wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl * ctrl,int argc,char * argv[])31464bc52338SCy Schubert static int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc,
31474bc52338SCy Schubert 					     char *argv[])
31484bc52338SCy Schubert {
31494bc52338SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv);
31504bc52338SCy Schubert }
31514bc52338SCy Schubert 
31524bc52338SCy Schubert 
wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl * ctrl,int argc,char * argv[])315385732ac8SCy Schubert static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc,
315485732ac8SCy Schubert 				    char *argv[])
315585732ac8SCy Schubert {
315685732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv);
315785732ac8SCy Schubert }
315885732ac8SCy Schubert 
315985732ac8SCy Schubert 
wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])316085732ac8SCy Schubert static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc,
316185732ac8SCy Schubert 				       char *argv[])
316285732ac8SCy Schubert {
316385732ac8SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv);
316485732ac8SCy Schubert }
316585732ac8SCy Schubert 
3166c1d255d3SCy Schubert 
3167c1d255d3SCy Schubert #ifdef CONFIG_DPP2
3168c1d255d3SCy Schubert 
wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl * ctrl,int argc,char * argv[])3169c1d255d3SCy Schubert static int wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
3170c1d255d3SCy Schubert 					    char *argv[])
3171c1d255d3SCy Schubert {
3172*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CONTROLLER_START", 0, argc, argv);
3173c1d255d3SCy Schubert }
3174c1d255d3SCy Schubert 
3175c1d255d3SCy Schubert 
wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])3176c1d255d3SCy Schubert static int wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc,
3177c1d255d3SCy Schubert 					    char *argv[])
3178c1d255d3SCy Schubert {
3179c1d255d3SCy Schubert 	return wpa_ctrl_command(ctrl, "DPP_CONTROLLER_STOP");
3180c1d255d3SCy Schubert }
3181c1d255d3SCy Schubert 
3182c1d255d3SCy Schubert 
wpa_cli_cmd_dpp_chirp(struct wpa_ctrl * ctrl,int argc,char * argv[])3183c1d255d3SCy Schubert static int wpa_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc,
3184c1d255d3SCy Schubert 				 char *argv[])
3185c1d255d3SCy Schubert {
3186c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_CHIRP", 1, argc, argv);
3187c1d255d3SCy Schubert }
3188c1d255d3SCy Schubert 
3189c1d255d3SCy Schubert 
wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl * ctrl,int argc,char * argv[])3190c1d255d3SCy Schubert static int wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
3191c1d255d3SCy Schubert 				      char *argv[])
3192c1d255d3SCy Schubert {
3193c1d255d3SCy Schubert 	return wpa_ctrl_command(ctrl, "DPP_STOP_CHIRP");
3194c1d255d3SCy Schubert }
3195c1d255d3SCy Schubert 
3196c1d255d3SCy Schubert #endif /* CONFIG_DPP2 */
3197*a90b9d01SCy Schubert 
3198*a90b9d01SCy Schubert 
3199*a90b9d01SCy Schubert #ifdef CONFIG_DPP3
wpa_cli_cmd_dpp_push_button(struct wpa_ctrl * ctrl,int argc,char * argv[])3200*a90b9d01SCy Schubert static int wpa_cli_cmd_dpp_push_button(struct wpa_ctrl *ctrl, int argc,
3201*a90b9d01SCy Schubert 				       char *argv[])
3202*a90b9d01SCy Schubert {
3203*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "DPP_PUSH_BUTTON", 0, argc, argv);
3204*a90b9d01SCy Schubert }
3205*a90b9d01SCy Schubert #endif /* CONFIG_DPP3 */
320685732ac8SCy Schubert #endif /* CONFIG_DPP */
320785732ac8SCy Schubert 
320885732ac8SCy Schubert 
wpa_ctrl_command_bss(struct wpa_ctrl * ctrl,const char * cmd)3209c1d255d3SCy Schubert static int wpa_ctrl_command_bss(struct wpa_ctrl *ctrl, const char *cmd)
3210c1d255d3SCy Schubert {
3211c1d255d3SCy Schubert 	char buf[512], *pos, *bssid = NULL, *freq = NULL, *level = NULL,
3212c1d255d3SCy Schubert 		*flags = NULL, *ssid = NULL;
3213c1d255d3SCy Schubert 	size_t len;
3214c1d255d3SCy Schubert 	int ret, id = -1;
3215c1d255d3SCy Schubert 
3216c1d255d3SCy Schubert 	if (!ctrl_conn)
3217c1d255d3SCy Schubert 		return -1;
3218c1d255d3SCy Schubert 	len = sizeof(buf) - 1;
3219c1d255d3SCy Schubert 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
3220c1d255d3SCy Schubert 			       wpa_cli_msg_cb);
3221c1d255d3SCy Schubert 	if (ret == -2) {
3222c1d255d3SCy Schubert 		printf("'%s' command timed out.\n", cmd);
3223c1d255d3SCy Schubert 		return -2;
3224c1d255d3SCy Schubert 	} else if (ret < 0) {
3225c1d255d3SCy Schubert 		printf("'%s' command failed.\n", cmd);
3226c1d255d3SCy Schubert 		return -1;
3227c1d255d3SCy Schubert 	}
3228c1d255d3SCy Schubert 
3229c1d255d3SCy Schubert 	buf[len] = '\0';
3230c1d255d3SCy Schubert 	if (os_memcmp(buf, "FAIL", 4) == 0)
3231c1d255d3SCy Schubert 		return -1;
3232c1d255d3SCy Schubert 
3233c1d255d3SCy Schubert 	pos = buf;
3234c1d255d3SCy Schubert 	while (*pos != '\0') {
3235c1d255d3SCy Schubert 		if (str_starts(pos, "id="))
3236c1d255d3SCy Schubert 			id = atoi(pos + 3);
3237c1d255d3SCy Schubert 		if (str_starts(pos, "bssid="))
3238c1d255d3SCy Schubert 			bssid = pos + 6;
3239c1d255d3SCy Schubert 		if (str_starts(pos, "freq="))
3240c1d255d3SCy Schubert 			freq = pos + 5;
3241c1d255d3SCy Schubert 		if (str_starts(pos, "level="))
3242c1d255d3SCy Schubert 			level = pos + 6;
3243c1d255d3SCy Schubert 		if (str_starts(pos, "flags="))
3244c1d255d3SCy Schubert 			flags = pos + 6;
3245c1d255d3SCy Schubert 		if (str_starts(pos, "ssid="))
3246c1d255d3SCy Schubert 			ssid = pos + 5;
3247c1d255d3SCy Schubert 
3248c1d255d3SCy Schubert 		while (*pos != '\0' && *pos != '\n')
3249c1d255d3SCy Schubert 			pos++;
3250c1d255d3SCy Schubert 		*pos++ = '\0';
3251c1d255d3SCy Schubert 	}
3252c1d255d3SCy Schubert 	if (id != -1)
3253c1d255d3SCy Schubert 		printf("%s\t%s\t%s\t%s\t%s\n", bssid ? bssid : "N/A",
3254c1d255d3SCy Schubert 		       freq ? freq : "N/A", level ? level : "N/A",
3255c1d255d3SCy Schubert 		       flags ? flags : "N/A", ssid ? ssid : "N/A");
3256c1d255d3SCy Schubert 	return id;
3257c1d255d3SCy Schubert }
3258c1d255d3SCy Schubert 
3259c1d255d3SCy Schubert 
wpa_cli_cmd_all_bss(struct wpa_ctrl * ctrl,int argc,char * argv[])3260c1d255d3SCy Schubert static int wpa_cli_cmd_all_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
3261c1d255d3SCy Schubert {
3262c1d255d3SCy Schubert 	char cmd[64];
3263c1d255d3SCy Schubert 	int id = -1;
3264c1d255d3SCy Schubert 	unsigned int mask;
3265c1d255d3SCy Schubert 
3266c1d255d3SCy Schubert 	printf("bssid / frequency / signal level / flags / ssid\n");
3267c1d255d3SCy Schubert 
3268c1d255d3SCy Schubert 	mask = WPA_BSS_MASK_ID | WPA_BSS_MASK_BSSID | WPA_BSS_MASK_FREQ |
3269c1d255d3SCy Schubert 		WPA_BSS_MASK_LEVEL | WPA_BSS_MASK_FLAGS | WPA_BSS_MASK_SSID;
3270c1d255d3SCy Schubert 	do {
3271c1d255d3SCy Schubert 		if (id < 0)
3272c1d255d3SCy Schubert 			os_snprintf(cmd, sizeof(cmd), "BSS FIRST MASK=0x%x",
3273c1d255d3SCy Schubert 				    mask);
3274c1d255d3SCy Schubert 		else
3275c1d255d3SCy Schubert 			os_snprintf(cmd, sizeof(cmd), "BSS NEXT-%d MASK=0x%x",
3276c1d255d3SCy Schubert 				    id, mask);
3277c1d255d3SCy Schubert 		id = wpa_ctrl_command_bss(ctrl, cmd);
3278c1d255d3SCy Schubert 	} while (id >= 0);
3279c1d255d3SCy Schubert 
3280c1d255d3SCy Schubert 	return 0;
3281c1d255d3SCy Schubert }
3282c1d255d3SCy Schubert 
3283c1d255d3SCy Schubert 
3284c1d255d3SCy Schubert #ifdef CONFIG_PASN
3285c1d255d3SCy Schubert 
wpa_cli_cmd_pasn_start(struct wpa_ctrl * ctrl,int argc,char * argv[])3286*a90b9d01SCy Schubert static int wpa_cli_cmd_pasn_start(struct wpa_ctrl *ctrl, int argc, char *argv[])
3287c1d255d3SCy Schubert {
3288*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "PASN_START", 4, argc, argv);
3289c1d255d3SCy Schubert }
3290c1d255d3SCy Schubert 
3291c1d255d3SCy Schubert 
wpa_cli_cmd_pasn_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])3292*a90b9d01SCy Schubert static int wpa_cli_cmd_pasn_stop(struct wpa_ctrl *ctrl, int argc, char *argv[])
3293c1d255d3SCy Schubert {
3294*a90b9d01SCy Schubert 	return wpa_cli_cmd(ctrl, "PASN_STOP", 0, argc, argv);
3295c1d255d3SCy Schubert }
3296c1d255d3SCy Schubert 
3297*a90b9d01SCy Schubert 
wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl * ctrl,int argc,char * argv[])3298c1d255d3SCy Schubert static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
3299c1d255d3SCy Schubert 					char *argv[])
3300c1d255d3SCy Schubert {
3301c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
3302c1d255d3SCy Schubert }
3303c1d255d3SCy Schubert 
3304c1d255d3SCy Schubert 
wpa_cli_cmd_pasn_deauth(struct wpa_ctrl * ctrl,int argc,char * argv[])3305c1d255d3SCy Schubert static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
3306c1d255d3SCy Schubert 				   char *argv[])
3307c1d255d3SCy Schubert {
3308c1d255d3SCy Schubert 	return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
3309c1d255d3SCy Schubert }
3310c1d255d3SCy Schubert 
3311c1d255d3SCy Schubert #endif /* CONFIG_PASN */
3312c1d255d3SCy Schubert 
3313c1d255d3SCy Schubert 
wpa_cli_cmd_mscs(struct wpa_ctrl * ctrl,int argc,char * argv[])33144b72b91aSCy Schubert static int wpa_cli_cmd_mscs(struct wpa_ctrl *ctrl, int argc, char *argv[])
33154b72b91aSCy Schubert {
33164b72b91aSCy Schubert 	return wpa_cli_cmd(ctrl, "MSCS", 1, argc, argv);
33174b72b91aSCy Schubert }
33184b72b91aSCy Schubert 
33194b72b91aSCy Schubert 
wpa_cli_cmd_scs(struct wpa_ctrl * ctrl,int argc,char * argv[])33204b72b91aSCy Schubert static int wpa_cli_cmd_scs(struct wpa_ctrl *ctrl, int argc, char *argv[])
33214b72b91aSCy Schubert {
33224b72b91aSCy Schubert 	return wpa_cli_cmd(ctrl, "SCS", 2, argc, argv);
33234b72b91aSCy Schubert }
33244b72b91aSCy Schubert 
33254b72b91aSCy Schubert 
wpa_cli_cmd_dscp_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])33264b72b91aSCy Schubert static int wpa_cli_cmd_dscp_resp(struct wpa_ctrl *ctrl, int argc, char *argv[])
33274b72b91aSCy Schubert {
33284b72b91aSCy Schubert 	return wpa_cli_cmd(ctrl, "DSCP_RESP", 1, argc, argv);
33294b72b91aSCy Schubert }
33304b72b91aSCy Schubert 
33314b72b91aSCy Schubert 
wpa_cli_cmd_dscp_query(struct wpa_ctrl * ctrl,int argc,char * argv[])33324b72b91aSCy Schubert static int wpa_cli_cmd_dscp_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
33334b72b91aSCy Schubert {
33344b72b91aSCy Schubert 	return wpa_cli_cmd(ctrl, "DSCP_QUERY", 1, argc, argv);
33354b72b91aSCy Schubert }
33364b72b91aSCy Schubert 
33374b72b91aSCy Schubert 
333839beb93cSSam Leffler enum wpa_cli_cmd_flags {
333939beb93cSSam Leffler 	cli_cmd_flag_none		= 0x00,
334039beb93cSSam Leffler 	cli_cmd_flag_sensitive		= 0x01
334139beb93cSSam Leffler };
334239beb93cSSam Leffler 
334339beb93cSSam Leffler struct wpa_cli_cmd {
334439beb93cSSam Leffler 	const char *cmd;
334539beb93cSSam Leffler 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
3346f05cddf9SRui Paulo 	char ** (*completion)(const char *str, int pos);
334739beb93cSSam Leffler 	enum wpa_cli_cmd_flags flags;
334839beb93cSSam Leffler 	const char *usage;
334939beb93cSSam Leffler };
335039beb93cSSam Leffler 
3351325151a3SRui Paulo static const struct wpa_cli_cmd wpa_cli_commands[] = {
3352f05cddf9SRui Paulo 	{ "status", wpa_cli_cmd_status, NULL,
335339beb93cSSam Leffler 	  cli_cmd_flag_none,
335439beb93cSSam Leffler 	  "[verbose] = get current WPA/EAPOL/EAP status" },
3355f05cddf9SRui Paulo 	{ "ifname", wpa_cli_cmd_ifname, NULL,
3356f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3357f05cddf9SRui Paulo 	  "= get current interface name" },
3358f05cddf9SRui Paulo 	{ "ping", wpa_cli_cmd_ping, NULL,
335939beb93cSSam Leffler 	  cli_cmd_flag_none,
336039beb93cSSam Leffler 	  "= pings wpa_supplicant" },
3361f05cddf9SRui Paulo 	{ "relog", wpa_cli_cmd_relog, NULL,
3362f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3363f05cddf9SRui Paulo 	  "= re-open log-file (allow rolling logs)" },
3364f05cddf9SRui Paulo 	{ "note", wpa_cli_cmd_note, NULL,
3365f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3366f05cddf9SRui Paulo 	  "<text> = add a note to wpa_supplicant debug log" },
3367f05cddf9SRui Paulo 	{ "mib", wpa_cli_cmd_mib, NULL,
336839beb93cSSam Leffler 	  cli_cmd_flag_none,
336939beb93cSSam Leffler 	  "= get MIB variables (dot1x, dot11)" },
3370f05cddf9SRui Paulo 	{ "help", wpa_cli_cmd_help, wpa_cli_complete_help,
337139beb93cSSam Leffler 	  cli_cmd_flag_none,
3372f05cddf9SRui Paulo 	  "[command] = show usage help" },
3373f05cddf9SRui Paulo 	{ "interface", wpa_cli_cmd_interface, NULL,
337439beb93cSSam Leffler 	  cli_cmd_flag_none,
337539beb93cSSam Leffler 	  "[ifname] = show interfaces/select interface" },
3376f05cddf9SRui Paulo 	{ "level", wpa_cli_cmd_level, NULL,
337739beb93cSSam Leffler 	  cli_cmd_flag_none,
337839beb93cSSam Leffler 	  "<debug level> = change debug level" },
3379f05cddf9SRui Paulo 	{ "license", wpa_cli_cmd_license, NULL,
338039beb93cSSam Leffler 	  cli_cmd_flag_none,
338139beb93cSSam Leffler 	  "= show full wpa_cli license" },
3382f05cddf9SRui Paulo 	{ "quit", wpa_cli_cmd_quit, NULL,
338339beb93cSSam Leffler 	  cli_cmd_flag_none,
338439beb93cSSam Leffler 	  "= exit wpa_cli" },
33855b9c547cSRui Paulo 	{ "set", wpa_cli_cmd_set, wpa_cli_complete_set,
338639beb93cSSam Leffler 	  cli_cmd_flag_none,
338739beb93cSSam Leffler 	  "= set variables (shows list of variables when run without "
338839beb93cSSam Leffler 	  "arguments)" },
33895b9c547cSRui Paulo 	{ "dump", wpa_cli_cmd_dump, NULL,
33905b9c547cSRui Paulo 	  cli_cmd_flag_none,
33915b9c547cSRui Paulo 	  "= dump config variables" },
3392325151a3SRui Paulo 	{ "get", wpa_cli_cmd_get, wpa_cli_complete_get,
3393f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3394f05cddf9SRui Paulo 	  "<name> = get information" },
3395780fb4a2SCy Schubert 	{ "driver_flags", wpa_cli_cmd_driver_flags, NULL,
3396780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3397780fb4a2SCy Schubert 	  "= list driver flags" },
3398*a90b9d01SCy Schubert 	{ "driver_flags2", wpa_cli_cmd_driver_flags2, NULL,
3399*a90b9d01SCy Schubert 	  cli_cmd_flag_none,
3400*a90b9d01SCy Schubert 	  "= list driver flags2" },
3401f05cddf9SRui Paulo 	{ "logon", wpa_cli_cmd_logon, NULL,
340239beb93cSSam Leffler 	  cli_cmd_flag_none,
340339beb93cSSam Leffler 	  "= IEEE 802.1X EAPOL state machine logon" },
3404f05cddf9SRui Paulo 	{ "logoff", wpa_cli_cmd_logoff, NULL,
340539beb93cSSam Leffler 	  cli_cmd_flag_none,
340639beb93cSSam Leffler 	  "= IEEE 802.1X EAPOL state machine logoff" },
3407f05cddf9SRui Paulo 	{ "pmksa", wpa_cli_cmd_pmksa, NULL,
340839beb93cSSam Leffler 	  cli_cmd_flag_none,
340939beb93cSSam Leffler 	  "= show PMKSA cache" },
34105b9c547cSRui Paulo 	{ "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
34115b9c547cSRui Paulo 	  cli_cmd_flag_none,
34125b9c547cSRui Paulo 	  "= flush PMKSA cache entries" },
341385732ac8SCy Schubert #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
341485732ac8SCy Schubert 	{ "pmksa_get", wpa_cli_cmd_pmksa_get, NULL,
341585732ac8SCy Schubert 	  cli_cmd_flag_none,
341685732ac8SCy Schubert 	  "<network_id> = fetch all stored PMKSA cache entries" },
341785732ac8SCy Schubert 	{ "pmksa_add", wpa_cli_cmd_pmksa_add, NULL,
341885732ac8SCy Schubert 	  cli_cmd_flag_sensitive,
341985732ac8SCy Schubert 	  "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" },
342085732ac8SCy Schubert #ifdef CONFIG_MESH
342185732ac8SCy Schubert 	{ "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL,
342285732ac8SCy Schubert 	  cli_cmd_flag_none,
342385732ac8SCy Schubert 	  "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" },
342485732ac8SCy Schubert 	{ "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL,
342585732ac8SCy Schubert 	  cli_cmd_flag_sensitive,
342685732ac8SCy Schubert 	  "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" },
342785732ac8SCy Schubert #endif /* CONFIG_MESH */
342885732ac8SCy Schubert #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
3429f05cddf9SRui Paulo 	{ "reassociate", wpa_cli_cmd_reassociate, NULL,
343039beb93cSSam Leffler 	  cli_cmd_flag_none,
343139beb93cSSam Leffler 	  "= force reassociation" },
34325b9c547cSRui Paulo 	{ "reattach", wpa_cli_cmd_reattach, NULL,
34335b9c547cSRui Paulo 	  cli_cmd_flag_none,
34345b9c547cSRui Paulo 	  "= force reassociation back to the same BSS" },
3435f05cddf9SRui Paulo 	{ "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
343639beb93cSSam Leffler 	  cli_cmd_flag_none,
343739beb93cSSam Leffler 	  "<BSSID> = force preauthentication" },
343885732ac8SCy Schubert 	{ "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id,
343939beb93cSSam Leffler 	  cli_cmd_flag_none,
344039beb93cSSam Leffler 	  "<network id> <identity> = configure identity for an SSID" },
344185732ac8SCy Schubert 	{ "password", wpa_cli_cmd_password, wpa_cli_complete_network_id,
344239beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
344339beb93cSSam Leffler 	  "<network id> <password> = configure password for an SSID" },
344485732ac8SCy Schubert 	{ "new_password", wpa_cli_cmd_new_password,
344585732ac8SCy Schubert 	  wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
344639beb93cSSam Leffler 	  "<network id> <password> = change password for an SSID" },
344785732ac8SCy Schubert 	{ "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id,
344839beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
344939beb93cSSam Leffler 	  "<network id> <pin> = configure pin for an SSID" },
345085732ac8SCy Schubert 	{ "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id,
345139beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
345239beb93cSSam Leffler 	  "<network id> <password> = configure one-time-password for an SSID"
345339beb93cSSam Leffler 	},
34544bc52338SCy Schubert 	{ "psk_passphrase", wpa_cli_cmd_psk_passphrase,
34554bc52338SCy Schubert 	  wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
34564bc52338SCy Schubert 	  "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" },
345785732ac8SCy Schubert 	{ "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id,
345839beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
345939beb93cSSam Leffler 	  "<network id> <passphrase> = configure private key passphrase\n"
346039beb93cSSam Leffler 	  "  for an SSID" },
346185732ac8SCy Schubert 	{ "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id,
34625b9c547cSRui Paulo 	  cli_cmd_flag_sensitive,
34635b9c547cSRui Paulo 	  "<network id> <pin> = report SIM operation result" },
346485732ac8SCy Schubert 	{ "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id,
346539beb93cSSam Leffler 	  cli_cmd_flag_none,
346639beb93cSSam Leffler 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
3467c1d255d3SCy Schubert 	{ "bssid_ignore", wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
3468f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3469c1d255d3SCy Schubert 	  "<BSSID> = add a BSSID to the list of temporarily ignored BSSs\n"
3470c1d255d3SCy Schubert 	  "bssid_ignore clear = clear the list of temporarily ignored BSSIDs\n"
3471c1d255d3SCy Schubert 	  "bssid_ignore = display the list of temporarily ignored BSSIDs" },
3472c1d255d3SCy Schubert 	{ "blacklist", /* deprecated alias for bssid_ignore */
3473c1d255d3SCy Schubert 	  wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
3474c1d255d3SCy Schubert 	  cli_cmd_flag_none,
3475c1d255d3SCy Schubert 	  "= deprecated alias for bssid_ignore" },
3476f05cddf9SRui Paulo 	{ "log_level", wpa_cli_cmd_log_level, NULL,
3477f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3478f05cddf9SRui Paulo 	  "<level> [<timestamp>] = update the log level/timestamp\n"
3479f05cddf9SRui Paulo 	  "log_level = display the current log level and log options" },
3480f05cddf9SRui Paulo 	{ "list_networks", wpa_cli_cmd_list_networks, NULL,
348139beb93cSSam Leffler 	  cli_cmd_flag_none,
348239beb93cSSam Leffler 	  "= list configured networks" },
3483325151a3SRui Paulo 	{ "select_network", wpa_cli_cmd_select_network,
3484325151a3SRui Paulo 	  wpa_cli_complete_network_id,
348539beb93cSSam Leffler 	  cli_cmd_flag_none,
348639beb93cSSam Leffler 	  "<network id> = select a network (disable others)" },
3487325151a3SRui Paulo 	{ "enable_network", wpa_cli_cmd_enable_network,
3488325151a3SRui Paulo 	  wpa_cli_complete_network_id,
348939beb93cSSam Leffler 	  cli_cmd_flag_none,
349039beb93cSSam Leffler 	  "<network id> = enable a network" },
3491325151a3SRui Paulo 	{ "disable_network", wpa_cli_cmd_disable_network,
3492325151a3SRui Paulo 	  wpa_cli_complete_network_id,
349339beb93cSSam Leffler 	  cli_cmd_flag_none,
349439beb93cSSam Leffler 	  "<network id> = disable a network" },
3495f05cddf9SRui Paulo 	{ "add_network", wpa_cli_cmd_add_network, NULL,
349639beb93cSSam Leffler 	  cli_cmd_flag_none,
349739beb93cSSam Leffler 	  "= add a network" },
3498325151a3SRui Paulo 	{ "remove_network", wpa_cli_cmd_remove_network,
3499325151a3SRui Paulo 	  wpa_cli_complete_network_id,
350039beb93cSSam Leffler 	  cli_cmd_flag_none,
350139beb93cSSam Leffler 	  "<network id> = remove a network" },
3502325151a3SRui Paulo 	{ "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
350339beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
350439beb93cSSam Leffler 	  "<network id> <variable> <value> = set network variables (shows\n"
350539beb93cSSam Leffler 	  "  list of variables when run without arguments)" },
3506325151a3SRui Paulo 	{ "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
350739beb93cSSam Leffler 	  cli_cmd_flag_none,
350839beb93cSSam Leffler 	  "<network id> <variable> = get network variables" },
3509325151a3SRui Paulo 	{ "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
35105b9c547cSRui Paulo 	  cli_cmd_flag_none,
35115b9c547cSRui Paulo 	  "<src network id> <dst network id> <variable> = duplicate network variables"
35125b9c547cSRui Paulo 	},
3513f05cddf9SRui Paulo 	{ "list_creds", wpa_cli_cmd_list_creds, NULL,
3514f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3515f05cddf9SRui Paulo 	  "= list configured credentials" },
3516f05cddf9SRui Paulo 	{ "add_cred", wpa_cli_cmd_add_cred, NULL,
3517f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3518f05cddf9SRui Paulo 	  "= add a credential" },
3519f05cddf9SRui Paulo 	{ "remove_cred", wpa_cli_cmd_remove_cred, NULL,
3520f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3521f05cddf9SRui Paulo 	  "<cred id> = remove a credential" },
352285732ac8SCy Schubert 	{ "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred,
3523f05cddf9SRui Paulo 	  cli_cmd_flag_sensitive,
3524f05cddf9SRui Paulo 	  "<cred id> <variable> <value> = set credential variables" },
352585732ac8SCy Schubert 	{ "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred,
35265b9c547cSRui Paulo 	  cli_cmd_flag_none,
35275b9c547cSRui Paulo 	  "<cred id> <variable> = get credential variables" },
3528f05cddf9SRui Paulo 	{ "save_config", wpa_cli_cmd_save_config, NULL,
352939beb93cSSam Leffler 	  cli_cmd_flag_none,
353039beb93cSSam Leffler 	  "= save the current configuration" },
3531f05cddf9SRui Paulo 	{ "disconnect", wpa_cli_cmd_disconnect, NULL,
353239beb93cSSam Leffler 	  cli_cmd_flag_none,
353339beb93cSSam Leffler 	  "= disconnect and wait for reassociate/reconnect command before\n"
353439beb93cSSam Leffler 	  "  connecting" },
3535f05cddf9SRui Paulo 	{ "reconnect", wpa_cli_cmd_reconnect, NULL,
353639beb93cSSam Leffler 	  cli_cmd_flag_none,
353739beb93cSSam Leffler 	  "= like reassociate, but only takes effect if already disconnected"
353839beb93cSSam Leffler 	},
3539f05cddf9SRui Paulo 	{ "scan", wpa_cli_cmd_scan, NULL,
354039beb93cSSam Leffler 	  cli_cmd_flag_none,
354139beb93cSSam Leffler 	  "= request new BSS scan" },
3542f05cddf9SRui Paulo 	{ "scan_results", wpa_cli_cmd_scan_results, NULL,
354339beb93cSSam Leffler 	  cli_cmd_flag_none,
354439beb93cSSam Leffler 	  "= get latest scan results" },
3545780fb4a2SCy Schubert 	{ "abort_scan", wpa_cli_cmd_abort_scan, NULL,
3546780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3547780fb4a2SCy Schubert 	  "= request ongoing scan to be aborted" },
3548f05cddf9SRui Paulo 	{ "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
354939beb93cSSam Leffler 	  cli_cmd_flag_none,
355039beb93cSSam Leffler 	  "<<idx> | <bssid>> = get detailed scan result info" },
3551780fb4a2SCy Schubert 	{ "get_capability", wpa_cli_cmd_get_capability,
3552780fb4a2SCy Schubert 	  wpa_cli_complete_get_capability, cli_cmd_flag_none,
35535b9c547cSRui Paulo 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
3554325151a3SRui Paulo 	  "= get capabilities" },
3555f05cddf9SRui Paulo 	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
355639beb93cSSam Leffler 	  cli_cmd_flag_none,
355739beb93cSSam Leffler 	  "= force wpa_supplicant to re-read its configuration file" },
3558f05cddf9SRui Paulo 	{ "terminate", wpa_cli_cmd_terminate, NULL,
355939beb93cSSam Leffler 	  cli_cmd_flag_none,
356039beb93cSSam Leffler 	  "= terminate wpa_supplicant" },
3561f05cddf9SRui Paulo 	{ "interface_add", wpa_cli_cmd_interface_add, NULL,
356239beb93cSSam Leffler 	  cli_cmd_flag_none,
356339beb93cSSam Leffler 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3564780fb4a2SCy Schubert 	  "  <bridge_name> <create> <type> = adds new interface, all "
3565780fb4a2SCy Schubert 	  "parameters but\n"
3566780fb4a2SCy Schubert 	  "  <ifname> are optional. Supported types are station ('sta') and "
3567780fb4a2SCy Schubert 	  "AP ('ap')" },
3568f05cddf9SRui Paulo 	{ "interface_remove", wpa_cli_cmd_interface_remove, NULL,
356939beb93cSSam Leffler 	  cli_cmd_flag_none,
357039beb93cSSam Leffler 	  "<ifname> = removes the interface" },
3571f05cddf9SRui Paulo 	{ "interface_list", wpa_cli_cmd_interface_list, NULL,
357239beb93cSSam Leffler 	  cli_cmd_flag_none,
357339beb93cSSam Leffler 	  "= list available interfaces" },
3574f05cddf9SRui Paulo 	{ "ap_scan", wpa_cli_cmd_ap_scan, NULL,
357539beb93cSSam Leffler 	  cli_cmd_flag_none,
357639beb93cSSam Leffler 	  "<value> = set ap_scan parameter" },
3577f05cddf9SRui Paulo 	{ "scan_interval", wpa_cli_cmd_scan_interval, NULL,
3578f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3579f05cddf9SRui Paulo 	  "<value> = set scan_interval parameter (in seconds)" },
3580f05cddf9SRui Paulo 	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
3581f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3582f05cddf9SRui Paulo 	  "<value> = set BSS expiration age parameter" },
3583f05cddf9SRui Paulo 	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
3584f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3585f05cddf9SRui Paulo 	  "<value> = set BSS expiration scan count parameter" },
3586f05cddf9SRui Paulo 	{ "bss_flush", wpa_cli_cmd_bss_flush, NULL,
3587f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3588f05cddf9SRui Paulo 	  "<value> = set BSS flush age (0 by default)" },
3589f05cddf9SRui Paulo 	{ "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
359039beb93cSSam Leffler 	  cli_cmd_flag_none,
359139beb93cSSam Leffler 	  "<addr> = request over-the-DS FT with <addr>" },
3592f05cddf9SRui Paulo 	{ "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
359339beb93cSSam Leffler 	  cli_cmd_flag_none,
359439beb93cSSam Leffler 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3595f05cddf9SRui Paulo 	{ "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
359639beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
359739beb93cSSam Leffler 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
359839beb93cSSam Leffler 	  "hardcoded)" },
3599f05cddf9SRui Paulo 	{ "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
3600e28a4053SRui Paulo 	  cli_cmd_flag_sensitive,
3601f05cddf9SRui Paulo 	  "<PIN> = verify PIN checksum" },
3602f05cddf9SRui Paulo 	{ "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
3603f05cddf9SRui Paulo 	  "Cancels the pending WPS operation" },
3604f05cddf9SRui Paulo #ifdef CONFIG_WPS_NFC
3605f05cddf9SRui Paulo 	{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
3606f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3607f05cddf9SRui Paulo 	  "[BSSID] = start Wi-Fi Protected Setup: NFC" },
36085b9c547cSRui Paulo 	{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
36095b9c547cSRui Paulo 	  cli_cmd_flag_none,
36105b9c547cSRui Paulo 	  "<WPS|NDEF> = build configuration token" },
3611f05cddf9SRui Paulo 	{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3612f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3613f05cddf9SRui Paulo 	  "<WPS|NDEF> = create password token" },
3614f05cddf9SRui Paulo 	{ "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3615f05cddf9SRui Paulo 	  cli_cmd_flag_sensitive,
3616f05cddf9SRui Paulo 	  "<hexdump of payload> = report read NFC tag with WPS data" },
3617f05cddf9SRui Paulo 	{ "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3618f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3619f05cddf9SRui Paulo 	  "<NDEF> <WPS> = create NFC handover request" },
3620f05cddf9SRui Paulo 	{ "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3621f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3622f05cddf9SRui Paulo 	  "<NDEF> <WPS> = create NFC handover select" },
36235b9c547cSRui Paulo 	{ "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3624f05cddf9SRui Paulo 	  cli_cmd_flag_none,
36255b9c547cSRui Paulo 	  "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
36265b9c547cSRui Paulo 	  "NFC handover" },
3627f05cddf9SRui Paulo #endif /* CONFIG_WPS_NFC */
3628f05cddf9SRui Paulo 	{ "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
362939beb93cSSam Leffler 	  cli_cmd_flag_sensitive,
363039beb93cSSam Leffler 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3631f05cddf9SRui Paulo 	{ "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3632f05cddf9SRui Paulo 	  cli_cmd_flag_sensitive,
3633f05cddf9SRui Paulo 	  "[params..] = enable/disable AP PIN" },
3634f05cddf9SRui Paulo 	{ "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3635e28a4053SRui Paulo 	  cli_cmd_flag_none,
3636f05cddf9SRui Paulo 	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3637f05cddf9SRui Paulo 	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3638e28a4053SRui Paulo 	  cli_cmd_flag_none,
3639e28a4053SRui Paulo 	  "= stop Wi-Fi Protected Setup External Registrar" },
3640f05cddf9SRui Paulo 	{ "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3641e28a4053SRui Paulo 	  cli_cmd_flag_sensitive,
3642e28a4053SRui Paulo 	  "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3643f05cddf9SRui Paulo 	{ "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3644e28a4053SRui Paulo 	  cli_cmd_flag_none,
3645e28a4053SRui Paulo 	  "<UUID> = accept an Enrollee PBC using External Registrar" },
3646f05cddf9SRui Paulo 	{ "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3647e28a4053SRui Paulo 	  cli_cmd_flag_sensitive,
3648e28a4053SRui Paulo 	  "<UUID> <PIN> = learn AP configuration" },
3649f05cddf9SRui Paulo 	{ "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3650f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3651f05cddf9SRui Paulo 	  "<UUID> <network id> = set AP configuration for enrolling" },
3652f05cddf9SRui Paulo 	{ "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3653f05cddf9SRui Paulo 	  cli_cmd_flag_sensitive,
3654f05cddf9SRui Paulo 	  "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3655f05cddf9SRui Paulo #ifdef CONFIG_WPS_NFC
3656f05cddf9SRui Paulo 	{ "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3657f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3658f05cddf9SRui Paulo 	  "<WPS/NDEF> <UUID> = build NFC configuration token" },
3659f05cddf9SRui Paulo #endif /* CONFIG_WPS_NFC */
3660f05cddf9SRui Paulo 	{ "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3661e28a4053SRui Paulo 	  cli_cmd_flag_none,
3662e28a4053SRui Paulo 	  "<addr> = request RSN authentication with <addr> in IBSS" },
3663e28a4053SRui Paulo #ifdef CONFIG_AP
366485732ac8SCy Schubert 	{ "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta,
3665e28a4053SRui Paulo 	  cli_cmd_flag_none,
3666e28a4053SRui Paulo 	  "<addr> = get information about an associated station (AP)" },
3667f05cddf9SRui Paulo 	{ "all_sta", wpa_cli_cmd_all_sta, NULL,
3668e28a4053SRui Paulo 	  cli_cmd_flag_none,
3669e28a4053SRui Paulo 	  "= get information about all associated stations (AP)" },
367085732ac8SCy Schubert 	{ "list_sta", wpa_cli_cmd_list_sta, NULL,
3671f05cddf9SRui Paulo 	  cli_cmd_flag_none,
367285732ac8SCy Schubert 	  "= list all stations (AP)" },
367385732ac8SCy Schubert 	{ "deauthenticate", wpa_cli_cmd_deauthenticate,
367485732ac8SCy Schubert 	  wpa_cli_complete_deauthenticate, cli_cmd_flag_none,
3675f05cddf9SRui Paulo 	  "<addr> = deauthenticate a station" },
367685732ac8SCy Schubert 	{ "disassociate", wpa_cli_cmd_disassociate,
367785732ac8SCy Schubert 	  wpa_cli_complete_disassociate, cli_cmd_flag_none,
3678f05cddf9SRui Paulo 	  "<addr> = disassociate a station" },
36795b9c547cSRui Paulo 	{ "chan_switch", wpa_cli_cmd_chanswitch, NULL,
36805b9c547cSRui Paulo 	  cli_cmd_flag_none,
36815b9c547cSRui Paulo 	  "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
36825b9c547cSRui Paulo 	  " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
36835b9c547cSRui Paulo 	  " = CSA parameters" },
36844b72b91aSCy Schubert 	{ "update_beacon", wpa_cli_cmd_update_beacon, NULL,
36854b72b91aSCy Schubert 	  cli_cmd_flag_none,
36864b72b91aSCy Schubert 	  "= update Beacon frame contents"},
3687*a90b9d01SCy Schubert 	{ "accept_acl", wpa_cli_cmd_accept_macacl, NULL, cli_cmd_flag_none,
3688*a90b9d01SCy Schubert 	  "=Add/Delete/Show/Clear allow MAC ACL" },
3689*a90b9d01SCy Schubert 	{ "deny_acl", wpa_cli_cmd_deny_macacl, NULL, cli_cmd_flag_none,
3690*a90b9d01SCy Schubert 	  "=Add/Delete/Show/Clear deny MAC ACL" },
3691e28a4053SRui Paulo #endif /* CONFIG_AP */
3692f05cddf9SRui Paulo 	{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3693e28a4053SRui Paulo 	  "= notification of suspend/hibernate" },
3694f05cddf9SRui Paulo 	{ "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3695e28a4053SRui Paulo 	  "= notification of resume/thaw" },
36965b9c547cSRui Paulo #ifdef CONFIG_TESTING_OPTIONS
3697f05cddf9SRui Paulo 	{ "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3698e28a4053SRui Paulo 	  "= drop SA without deauth/disassoc (test command)" },
3699*a90b9d01SCy Schubert 	{ "ml_probe_req", wpa_cli_cmd_ml_probe_req, NULL, cli_cmd_flag_none,
3700*a90b9d01SCy Schubert 	  "= send Multi-Link Probe request <bssid=addr> <mld_id=id> [link_id=id] (test command)" },
37015b9c547cSRui Paulo #endif /* CONFIG_TESTING_OPTIONS */
3702f05cddf9SRui Paulo 	{ "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3703e28a4053SRui Paulo 	  cli_cmd_flag_none,
3704e28a4053SRui Paulo 	  "<addr> = roam to the specified BSS" },
37055b9c547cSRui Paulo #ifdef CONFIG_MESH
37065b9c547cSRui Paulo 	{ "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
37075b9c547cSRui Paulo 	  cli_cmd_flag_none,
37085b9c547cSRui Paulo 	  "[ifname] = Create a new mesh interface" },
37095b9c547cSRui Paulo 	{ "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
37105b9c547cSRui Paulo 	  cli_cmd_flag_none,
37115b9c547cSRui Paulo 	  "<network id> = join a mesh network (disable others)" },
37125b9c547cSRui Paulo 	{ "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
37135b9c547cSRui Paulo 	  cli_cmd_flag_none,
37145b9c547cSRui Paulo 	  "<ifname> = Remove mesh group interface" },
3715780fb4a2SCy Schubert 	{ "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
3716780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3717780fb4a2SCy Schubert 	  "<addr> = Remove a mesh peer" },
3718780fb4a2SCy Schubert 	{ "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
3719780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3720780fb4a2SCy Schubert 	  "<addr> [duration=<seconds>] = Add a mesh peer" },
3721206b73d0SCy Schubert 	{ "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL,
3722206b73d0SCy Schubert 	  cli_cmd_flag_none,
3723206b73d0SCy Schubert 	  "<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." },
37245b9c547cSRui Paulo #endif /* CONFIG_MESH */
3725f05cddf9SRui Paulo #ifdef CONFIG_P2P
3726f05cddf9SRui Paulo 	{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3727f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3728f05cddf9SRui Paulo 	  "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3729f05cddf9SRui Paulo 	{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3730f05cddf9SRui Paulo 	  "= stop P2P Devices search" },
37315b9c547cSRui Paulo 	{ "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
37325b9c547cSRui Paulo 	  cli_cmd_flag_none,
37335b9c547cSRui Paulo 	  "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
37345b9c547cSRui Paulo 	{ "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
37355b9c547cSRui Paulo 	  cli_cmd_flag_none,
37365b9c547cSRui Paulo 	  "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3737f05cddf9SRui Paulo 	{ "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3738f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3739f05cddf9SRui Paulo 	  "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3740f05cddf9SRui Paulo 	{ "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3741f05cddf9SRui Paulo 	  "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3742f05cddf9SRui Paulo 	{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3743f05cddf9SRui Paulo 	  wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3744f05cddf9SRui Paulo 	  "<ifname> = remove P2P group interface (terminate group if GO)" },
3745f05cddf9SRui Paulo 	{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3746f05cddf9SRui Paulo 	  "[ht40] = add a new P2P group (local end as GO)" },
3747780fb4a2SCy Schubert 	{ "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
3748780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3749780fb4a2SCy Schubert 	  "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
3750f05cddf9SRui Paulo 	{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3751f05cddf9SRui Paulo 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3752f05cddf9SRui Paulo 	  "<addr> <method> = request provisioning discovery" },
3753f05cddf9SRui Paulo 	{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3754f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3755f05cddf9SRui Paulo 	  "= get the passphrase for a group (GO only)" },
3756f05cddf9SRui Paulo 	{ "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3757f05cddf9SRui Paulo 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3758f05cddf9SRui Paulo 	  "<addr> <TLVs> = schedule service discovery request" },
3759f05cddf9SRui Paulo 	{ "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3760f05cddf9SRui Paulo 	  NULL, cli_cmd_flag_none,
3761f05cddf9SRui Paulo 	  "<id> = cancel pending service discovery request" },
3762f05cddf9SRui Paulo 	{ "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3763f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3764f05cddf9SRui Paulo 	  "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3765f05cddf9SRui Paulo 	{ "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3766f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3767f05cddf9SRui Paulo 	  "= indicate change in local services" },
3768f05cddf9SRui Paulo 	{ "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3769f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3770f05cddf9SRui Paulo 	  "<external> = set external processing of service discovery" },
3771f05cddf9SRui Paulo 	{ "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3772f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3773f05cddf9SRui Paulo 	  "= remove all stored service entries" },
3774f05cddf9SRui Paulo 	{ "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3775f05cddf9SRui Paulo 	  cli_cmd_flag_none,
37765b9c547cSRui Paulo 	  "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3777f05cddf9SRui Paulo 	  "service" },
37785b9c547cSRui Paulo 	{ "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
37795b9c547cSRui Paulo 	  cli_cmd_flag_none,
37805b9c547cSRui Paulo 	  "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
37815b9c547cSRui Paulo 	  "local ASP service" },
3782f05cddf9SRui Paulo 	{ "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3783f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3784f05cddf9SRui Paulo 	  "<bonjour|upnp> <query|version> [|service] = remove a local "
3785f05cddf9SRui Paulo 	  "service" },
3786f05cddf9SRui Paulo 	{ "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3787f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3788f05cddf9SRui Paulo 	  "<addr> = reject connection attempts from a specific peer" },
3789f05cddf9SRui Paulo 	{ "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3790f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3791f05cddf9SRui Paulo 	  "<cmd> [peer=addr] = invite peer" },
3792f05cddf9SRui Paulo 	{ "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3793f05cddf9SRui Paulo 	  "[discovered] = list known (optionally, only fully discovered) P2P "
3794f05cddf9SRui Paulo 	  "peers" },
3795f05cddf9SRui Paulo 	{ "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3796f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3797f05cddf9SRui Paulo 	  "<address> = show information about known P2P peer" },
37985b9c547cSRui Paulo 	{ "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
37995b9c547cSRui Paulo 	  cli_cmd_flag_none,
3800f05cddf9SRui Paulo 	  "<field> <value> = set a P2P parameter" },
3801f05cddf9SRui Paulo 	{ "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3802f05cddf9SRui Paulo 	  "= flush P2P state" },
3803f05cddf9SRui Paulo 	{ "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3804f05cddf9SRui Paulo 	  "= cancel P2P group formation" },
3805f05cddf9SRui Paulo 	{ "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3806f05cddf9SRui Paulo 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3807f05cddf9SRui Paulo 	  "<address> = unauthorize a peer" },
3808f05cddf9SRui Paulo 	{ "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3809f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3810f05cddf9SRui Paulo 	  "[<duration> <interval>] [<duration> <interval>] = request GO "
3811f05cddf9SRui Paulo 	  "presence" },
3812f05cddf9SRui Paulo 	{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3813f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3814f05cddf9SRui Paulo 	  "[<period> <interval>] = set extended listen timing" },
38155b9c547cSRui Paulo 	{ "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
38165b9c547cSRui Paulo 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
38175b9c547cSRui Paulo 	  "<address|iface=address> = remove a peer from all groups" },
381885732ac8SCy Schubert #endif /* CONFIG_P2P */
3819780fb4a2SCy Schubert 	{ "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
3820780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3821780fb4a2SCy Schubert 	  "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
3822780fb4a2SCy Schubert 	  VENDOR_ELEM_FRAME_ID },
3823780fb4a2SCy Schubert 	{ "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
3824780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3825780fb4a2SCy Schubert 	  "<frame id> = get vendor specific IE(s) to frame(s)\n"
3826780fb4a2SCy Schubert 	  VENDOR_ELEM_FRAME_ID },
3827780fb4a2SCy Schubert 	{ "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
3828780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3829780fb4a2SCy Schubert 	  "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
3830780fb4a2SCy Schubert 	  VENDOR_ELEM_FRAME_ID },
3831f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
3832f05cddf9SRui Paulo 	{ "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3833f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3834f05cddf9SRui Paulo 	  "<subelem> [contents] = set Wi-Fi Display subelement" },
3835f05cddf9SRui Paulo 	{ "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3836f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3837f05cddf9SRui Paulo 	  "<subelem> = get Wi-Fi Display subelement" },
3838f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
3839f05cddf9SRui Paulo #ifdef CONFIG_INTERWORKING
3840f05cddf9SRui Paulo 	{ "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3841f05cddf9SRui Paulo 	  "= fetch ANQP information for all APs" },
3842f05cddf9SRui Paulo 	{ "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3843f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3844f05cddf9SRui Paulo 	  "= stop fetch_anqp operation" },
3845f05cddf9SRui Paulo 	{ "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3846f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3847f05cddf9SRui Paulo 	  "[auto] = perform Interworking network selection" },
3848f05cddf9SRui Paulo 	{ "interworking_connect", wpa_cli_cmd_interworking_connect,
3849f05cddf9SRui Paulo 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3850f05cddf9SRui Paulo 	  "<BSSID> = connect using Interworking credentials" },
38515b9c547cSRui Paulo 	{ "interworking_add_network", wpa_cli_cmd_interworking_add_network,
38525b9c547cSRui Paulo 	  wpa_cli_complete_bss, cli_cmd_flag_none,
38535b9c547cSRui Paulo 	  "<BSSID> = connect using Interworking credentials" },
3854f05cddf9SRui Paulo 	{ "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3855f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3856f05cddf9SRui Paulo 	  "<addr> <info id>[,<info id>]... = request ANQP information" },
3857f05cddf9SRui Paulo 	{ "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3858f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3859f05cddf9SRui Paulo 	  "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3860f05cddf9SRui Paulo 	{ "gas_response_get", wpa_cli_cmd_gas_response_get,
3861f05cddf9SRui Paulo 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3862f05cddf9SRui Paulo 	  "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3863f05cddf9SRui Paulo #endif /* CONFIG_INTERWORKING */
3864f05cddf9SRui Paulo #ifdef CONFIG_HS20
3865f05cddf9SRui Paulo 	{ "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3866f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3867f05cddf9SRui Paulo 	  "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3868f05cddf9SRui Paulo 	},
3869f05cddf9SRui Paulo 	{ "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3870f05cddf9SRui Paulo 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3871f05cddf9SRui Paulo 	  "<addr> <home realm> = get HS20 nai home realm list" },
38725b9c547cSRui Paulo 	{ "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
38735b9c547cSRui Paulo 	  wpa_cli_complete_bss, cli_cmd_flag_none,
38745b9c547cSRui Paulo 	  "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
38755b9c547cSRui Paulo 	{ "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
38765b9c547cSRui Paulo 	  "= fetch OSU provider information from all APs" },
38775b9c547cSRui Paulo 	{ "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
38785b9c547cSRui Paulo 	  cli_cmd_flag_none,
38795b9c547cSRui Paulo 	  "= cancel fetch_osu command" },
3880f05cddf9SRui Paulo #endif /* CONFIG_HS20 */
3881f05cddf9SRui Paulo 	{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3882f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3883f05cddf9SRui Paulo 	  "<0/1> = disable/enable automatic reconnection" },
3884f05cddf9SRui Paulo 	{ "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3885f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3886f05cddf9SRui Paulo 	  "<addr> = request TDLS discovery with <addr>" },
3887f05cddf9SRui Paulo 	{ "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3888f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3889f05cddf9SRui Paulo 	  "<addr> = request TDLS setup with <addr>" },
3890f05cddf9SRui Paulo 	{ "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3891f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3892f05cddf9SRui Paulo 	  "<addr> = tear down TDLS with <addr>" },
3893325151a3SRui Paulo 	{ "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
3894325151a3SRui Paulo 	  cli_cmd_flag_none,
3895325151a3SRui Paulo 	  "<addr> = TDLS link status with <addr>" },
3896*a90b9d01SCy Schubert #ifndef CONFIG_NO_WMM_AC
38975b9c547cSRui Paulo 	{ "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
38985b9c547cSRui Paulo 	  cli_cmd_flag_none,
38995b9c547cSRui Paulo 	  "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
39005b9c547cSRui Paulo 	  "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
39015b9c547cSRui Paulo 	  "= add WMM-AC traffic stream" },
39025b9c547cSRui Paulo 	{ "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
39035b9c547cSRui Paulo 	  cli_cmd_flag_none,
39045b9c547cSRui Paulo 	  "<tsid> = delete WMM-AC traffic stream" },
39055b9c547cSRui Paulo 	{ "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
39065b9c547cSRui Paulo 	  cli_cmd_flag_none,
39075b9c547cSRui Paulo 	  "= show status for Wireless Multi-Media Admission-Control" },
3908*a90b9d01SCy Schubert #endif /* CONFIG_NO_WMM_AC */
39095b9c547cSRui Paulo 	{ "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
39105b9c547cSRui Paulo 	  cli_cmd_flag_none,
39115b9c547cSRui Paulo 	  "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
39125b9c547cSRui Paulo 	  "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
39135b9c547cSRui Paulo 	  "with TDLS peer" },
39145b9c547cSRui Paulo 	{ "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
39155b9c547cSRui Paulo 	  cli_cmd_flag_none,
39165b9c547cSRui Paulo 	  "<addr> = disable channel switching with TDLS peer <addr>" },
3917f05cddf9SRui Paulo 	{ "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3918f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3919f05cddf9SRui Paulo 	  "= get signal parameters" },
3920780fb4a2SCy Schubert 	{ "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
3921780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3922780fb4a2SCy Schubert 	  "= set signal monitor parameters" },
3923f05cddf9SRui Paulo 	{ "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3924f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3925f05cddf9SRui Paulo 	  "= get TX/RX packet counters" },
3926f05cddf9SRui Paulo 	{ "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3927f05cddf9SRui Paulo 	  cli_cmd_flag_none,
3928f05cddf9SRui Paulo 	  "= trigger IEEE 802.1X/EAPOL reauthentication" },
3929f05cddf9SRui Paulo #ifdef CONFIG_AUTOSCAN
3930f05cddf9SRui Paulo 	{ "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3931f05cddf9SRui Paulo 	  "[params] = Set or unset (if none) autoscan parameters" },
3932f05cddf9SRui Paulo #endif /* CONFIG_AUTOSCAN */
3933f05cddf9SRui Paulo #ifdef CONFIG_WNM
3934f05cddf9SRui Paulo 	{ "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3935f05cddf9SRui Paulo 	  "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
39365b9c547cSRui Paulo 	{ "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
393785732ac8SCy Schubert 	  "<query reason> [list]"
393885732ac8SCy Schubert 	  " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]"
393985732ac8SCy Schubert 	  " = Send BSS Transition Management Query" },
3940f05cddf9SRui Paulo #endif /* CONFIG_WNM */
3941*a90b9d01SCy Schubert #ifdef CONFIG_WNM_AP
3942*a90b9d01SCy Schubert 	{ "disassoc_imminent", wpa_cli_cmd_disassoc_imminent, NULL, cli_cmd_flag_none,
3943*a90b9d01SCy Schubert 	  "= send Disassociation Imminent notification" },
3944*a90b9d01SCy Schubert 	{ "ess_disassoc", wpa_cli_cmd_ess_disassoc, NULL, cli_cmd_flag_none,
3945*a90b9d01SCy Schubert 	  "= send ESS Dissassociation Imminent notification" },
3946*a90b9d01SCy Schubert 	{ "bss_tm_req", wpa_cli_cmd_bss_tm_req, NULL, cli_cmd_flag_none,
3947*a90b9d01SCy Schubert 	  "= send BSS Transition Management Request" },
3948*a90b9d01SCy Schubert #endif /* CONFIG_WNM_AP */
3949f05cddf9SRui Paulo 	{ "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3950f05cddf9SRui Paulo 	  "<params..> = Sent unprocessed command" },
39515b9c547cSRui Paulo 	{ "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
39525b9c547cSRui Paulo 	  "= flush wpa_supplicant state" },
39535b9c547cSRui Paulo #ifdef ANDROID
39545b9c547cSRui Paulo 	{ "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
39555b9c547cSRui Paulo 	  "<command> = driver private commands" },
39565b9c547cSRui Paulo #endif /* ANDROID */
39575b9c547cSRui Paulo 	{ "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
39585b9c547cSRui Paulo 	  "= radio_work <show/add/done>" },
39595b9c547cSRui Paulo 	{ "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
39605b9c547cSRui Paulo 	  "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
39615b9c547cSRui Paulo 	},
39625b9c547cSRui Paulo 	{ "neighbor_rep_request",
39635b9c547cSRui Paulo 	  wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3964780fb4a2SCy Schubert 	  "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
39655b9c547cSRui Paulo 	},
3966c1d255d3SCy Schubert 	{ "twt_setup",
3967c1d255d3SCy Schubert 	  wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
3968c1d255d3SCy Schubert 	  "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>] [min_twt=<Min TWT>] [setup_cmd=<setup-cmd>] [twt=<u64>] [requestor=0|1] [trigger=0|1] [implicit=0|1] [flow_type=0|1] [flow_id=<3-bit-id>] [protection=0|1] [twt_channel=<twt chanel id>] [control=<control-u8>] = Send TWT Setup frame"
3969c1d255d3SCy Schubert 	},
3970c1d255d3SCy Schubert 	{ "twt_teardown",
3971c1d255d3SCy Schubert 	  wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
3972c1d255d3SCy Schubert 	  "[flags=<value>] = Send TWT Teardown frame"
3973c1d255d3SCy Schubert 	},
39745b9c547cSRui Paulo 	{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
39755b9c547cSRui Paulo 	  "= flush ERP keys" },
39765b9c547cSRui Paulo 	{ "mac_rand_scan",
39775b9c547cSRui Paulo 	  wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
39785b9c547cSRui Paulo 	  "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
39795b9c547cSRui Paulo 	  "mask=mac-address-mask] = scan MAC randomization"
39805b9c547cSRui Paulo 	},
3981325151a3SRui Paulo 	{ "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
3982325151a3SRui Paulo 	  cli_cmd_flag_none,
3983325151a3SRui Paulo 	  "<interface type> = retrieve preferred freq list for the specified interface type" },
3984780fb4a2SCy Schubert 	{ "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL,
3985780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3986780fb4a2SCy Schubert 	  "<freq> <period> <interval> <count> = start P2P listen offload" },
3987780fb4a2SCy Schubert 	{ "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL,
3988780fb4a2SCy Schubert 	  cli_cmd_flag_none,
3989780fb4a2SCy Schubert 	  "= stop P2P listen offload" },
399085732ac8SCy Schubert #ifdef CONFIG_DPP
399185732ac8SCy Schubert 	{ "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none,
399285732ac8SCy Schubert 	  "report a scanned DPP URI from a QR Code" },
399385732ac8SCy Schubert 	{ "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL,
399485732ac8SCy Schubert 	  cli_cmd_flag_sensitive,
399585732ac8SCy Schubert 	  "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" },
399685732ac8SCy Schubert 	{ "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL,
399785732ac8SCy Schubert 	  cli_cmd_flag_none,
399885732ac8SCy Schubert 	  "*|<id> = remove DPP bootstrap information" },
399985732ac8SCy Schubert 	{ "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL,
400085732ac8SCy Schubert 	  cli_cmd_flag_none,
400185732ac8SCy Schubert 	  "<id> = get DPP bootstrap URI" },
400285732ac8SCy Schubert 	{ "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL,
400385732ac8SCy Schubert 	  cli_cmd_flag_none,
400485732ac8SCy Schubert 	  "<id> = show DPP bootstrap information" },
4005c1d255d3SCy Schubert 	{ "dpp_bootstrap_set", wpa_cli_cmd_dpp_bootstrap_set, NULL,
4006c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4007c1d255d3SCy Schubert 	  "<id> [conf=..] [ssid=<SSID>] [ssid_charset=#] [psk=<PSK>] [pass=<passphrase>] [configurator=<id>] [conn_status=#] [akm_use_selector=<0|1>] [group_id=..] [expiry=#] [csrattrs=..] = set DPP configurator parameters" },
400885732ac8SCy Schubert 	{ "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none,
400985732ac8SCy Schubert 	  "peer=<id> [own=<id>] = initiate DPP bootstrapping" },
401085732ac8SCy Schubert 	{ "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none,
401185732ac8SCy Schubert 	  "<freq in MHz> = start DPP listen" },
401285732ac8SCy Schubert 	{ "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL,
401385732ac8SCy Schubert 	  cli_cmd_flag_none,
401485732ac8SCy Schubert 	  "= stop DPP listen" },
401585732ac8SCy Schubert 	{ "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL,
401685732ac8SCy Schubert 	  cli_cmd_flag_sensitive,
401785732ac8SCy Schubert 	  "[curve=..] [key=..] = add DPP configurator" },
401885732ac8SCy Schubert 	{ "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL,
401985732ac8SCy Schubert 	  cli_cmd_flag_none,
402085732ac8SCy Schubert 	  "*|<id> = remove DPP configurator" },
402185732ac8SCy Schubert 	{ "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key,
402285732ac8SCy Schubert 	  NULL, cli_cmd_flag_none,
402385732ac8SCy Schubert 	  "<id> = Get DPP configurator's private key" },
40244bc52338SCy Schubert 	{ "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL,
40254bc52338SCy Schubert 	  cli_cmd_flag_none,
40264bc52338SCy Schubert 	  "conf=<role> configurator=<id> = generate self DPP configuration" },
402785732ac8SCy Schubert 	{ "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL,
402885732ac8SCy Schubert 	  cli_cmd_flag_sensitive,
402985732ac8SCy Schubert 	  "add PKEX code" },
403085732ac8SCy Schubert 	{ "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL,
403185732ac8SCy Schubert 	  cli_cmd_flag_none,
403285732ac8SCy Schubert 	  "*|<id> = remove DPP pkex information" },
4033c1d255d3SCy Schubert #ifdef CONFIG_DPP2
4034c1d255d3SCy Schubert 	{ "dpp_controller_start", wpa_cli_cmd_dpp_controller_start, NULL,
4035c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4036c1d255d3SCy Schubert 	  "[tcp_port=<port>] [role=..] = start DPP controller" },
4037c1d255d3SCy Schubert 	{ "dpp_controller_stop", wpa_cli_cmd_dpp_controller_stop, NULL,
4038c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4039c1d255d3SCy Schubert 	  "= stop DPP controller" },
4040c1d255d3SCy Schubert 	{ "dpp_chirp", wpa_cli_cmd_dpp_chirp, NULL,
4041c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4042c1d255d3SCy Schubert 	  "own=<BI ID> iter=<count> = start DPP chirp" },
4043c1d255d3SCy Schubert 	{ "dpp_stop_chirp", wpa_cli_cmd_dpp_stop_chirp, NULL,
4044c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4045c1d255d3SCy Schubert 	  "= stop DPP chirp" },
4046c1d255d3SCy Schubert #endif /* CONFIG_DPP2 */
4047*a90b9d01SCy Schubert #ifdef CONFIG_DPP3
4048*a90b9d01SCy Schubert 	{ "dpp_push_button", wpa_cli_cmd_dpp_push_button, NULL,
4049*a90b9d01SCy Schubert 	  cli_cmd_flag_none,
4050*a90b9d01SCy Schubert 	  "= press DPP push button" },
4051*a90b9d01SCy Schubert #endif /* CONFIG_DPP3 */
405285732ac8SCy Schubert #endif /* CONFIG_DPP */
4053c1d255d3SCy Schubert 	{ "all_bss", wpa_cli_cmd_all_bss, NULL, cli_cmd_flag_none,
4054c1d255d3SCy Schubert 	  "= list all BSS entries (scan results)" },
4055c1d255d3SCy Schubert #ifdef CONFIG_PASN
4056*a90b9d01SCy Schubert 	{ "pasn_start", wpa_cli_cmd_pasn_start, NULL,
4057c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4058c1d255d3SCy Schubert 	  "bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> nid=<network id> = Start PASN authentication" },
4059*a90b9d01SCy Schubert 	{ "pasn_stop", wpa_cli_cmd_pasn_stop, NULL,
4060c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4061c1d255d3SCy Schubert 	  "= Stop PASN authentication" },
4062c1d255d3SCy Schubert 	{ "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
4063c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4064c1d255d3SCy Schubert 	  "= Get the PTKSA Cache" },
4065c1d255d3SCy Schubert 	{ "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
4066c1d255d3SCy Schubert 	  cli_cmd_flag_none,
4067c1d255d3SCy Schubert 	  "bssid=<BSSID> = Remove PASN PTKSA state" },
4068c1d255d3SCy Schubert #endif /* CONFIG_PASN */
40694b72b91aSCy Schubert 	{ "mscs", wpa_cli_cmd_mscs, NULL,
40704b72b91aSCy Schubert 	  cli_cmd_flag_none,
40714b72b91aSCy Schubert 	  "<add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>] [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>] = Configure MSCS request" },
40724b72b91aSCy Schubert 	{ "scs", wpa_cli_cmd_scs, NULL,
40734b72b91aSCy Schubert 	  cli_cmd_flag_none,
40744b72b91aSCy Schubert 	  "[scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>] [classifier_type=<4|10>] [classifier params based on classifier type] [tclas_processing=<0|1>] [scs_id=<decimal number>] ... = Send SCS request" },
40754b72b91aSCy Schubert 	{ "dscp_resp", wpa_cli_cmd_dscp_resp, NULL,
40764b72b91aSCy Schubert 	  cli_cmd_flag_none,
40774b72b91aSCy Schubert 	  "<[reset]>/<[solicited] [policy_id=1 status=0...]> [more] = Send DSCP response" },
40784b72b91aSCy Schubert 	{ "dscp_query", wpa_cli_cmd_dscp_query, NULL,
40794b72b91aSCy Schubert 	  cli_cmd_flag_none,
40804b72b91aSCy Schubert 	  "wildcard/domain_name=<string> = Send DSCP Query" },
4081*a90b9d01SCy Schubert 	{ "mlo_status", wpa_cli_cmd_mlo_status, NULL,
4082*a90b9d01SCy Schubert 	  cli_cmd_flag_none,
4083*a90b9d01SCy Schubert 	  "= get MLO status" },
4084*a90b9d01SCy Schubert 	{ "mlo_signal_poll", wpa_cli_cmd_mlo_signal_poll, NULL,
4085*a90b9d01SCy Schubert 	  cli_cmd_flag_none,
4086*a90b9d01SCy Schubert 	  "= get mlo signal parameters" },
4087f05cddf9SRui Paulo 	{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
408839beb93cSSam Leffler };
408939beb93cSSam Leffler 
409039beb93cSSam Leffler 
409139beb93cSSam Leffler /*
409239beb93cSSam Leffler  * Prints command usage, lines are padded with the specified string.
409339beb93cSSam Leffler  */
print_cmd_help(const struct wpa_cli_cmd * cmd,const char * pad)4094325151a3SRui Paulo static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
409539beb93cSSam Leffler {
409639beb93cSSam Leffler 	char c;
409739beb93cSSam Leffler 	size_t n;
409839beb93cSSam Leffler 
409939beb93cSSam Leffler 	printf("%s%s ", pad, cmd->cmd);
410039beb93cSSam Leffler 	for (n = 0; (c = cmd->usage[n]); n++) {
410139beb93cSSam Leffler 		printf("%c", c);
410239beb93cSSam Leffler 		if (c == '\n')
410339beb93cSSam Leffler 			printf("%s", pad);
410439beb93cSSam Leffler 	}
410539beb93cSSam Leffler 	printf("\n");
410639beb93cSSam Leffler }
410739beb93cSSam Leffler 
410839beb93cSSam Leffler 
print_help(const char * cmd)4109f05cddf9SRui Paulo static void print_help(const char *cmd)
411039beb93cSSam Leffler {
411139beb93cSSam Leffler 	int n;
411239beb93cSSam Leffler 	printf("commands:\n");
4113f05cddf9SRui Paulo 	for (n = 0; wpa_cli_commands[n].cmd; n++) {
4114f05cddf9SRui Paulo 		if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
411539beb93cSSam Leffler 			print_cmd_help(&wpa_cli_commands[n], "  ");
411639beb93cSSam Leffler 	}
4117f05cddf9SRui Paulo }
411839beb93cSSam Leffler 
411939beb93cSSam Leffler 
wpa_cli_edit_filter_history_cb(void * ctx,const char * cmd)4120f05cddf9SRui Paulo static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
412139beb93cSSam Leffler {
412239beb93cSSam Leffler 	const char *c, *delim;
412339beb93cSSam Leffler 	int n;
412439beb93cSSam Leffler 	size_t len;
412539beb93cSSam Leffler 
412639beb93cSSam Leffler 	delim = os_strchr(cmd, ' ');
412739beb93cSSam Leffler 	if (delim)
412839beb93cSSam Leffler 		len = delim - cmd;
412939beb93cSSam Leffler 	else
413039beb93cSSam Leffler 		len = os_strlen(cmd);
413139beb93cSSam Leffler 
413239beb93cSSam Leffler 	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
413339beb93cSSam Leffler 		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
413439beb93cSSam Leffler 			return (wpa_cli_commands[n].flags &
413539beb93cSSam Leffler 				cli_cmd_flag_sensitive);
413639beb93cSSam Leffler 	}
413739beb93cSSam Leffler 	return 0;
413839beb93cSSam Leffler }
4139f05cddf9SRui Paulo 
4140f05cddf9SRui Paulo 
wpa_list_cmd_list(void)4141f05cddf9SRui Paulo static char ** wpa_list_cmd_list(void)
4142f05cddf9SRui Paulo {
4143f05cddf9SRui Paulo 	char **res;
4144f05cddf9SRui Paulo 	int i, count;
41455b9c547cSRui Paulo 	struct cli_txt_entry *e;
4146f05cddf9SRui Paulo 
41475b9c547cSRui Paulo 	count = ARRAY_SIZE(wpa_cli_commands);
41485b9c547cSRui Paulo 	count += dl_list_len(&p2p_groups);
41495b9c547cSRui Paulo 	count += dl_list_len(&ifnames);
41505b9c547cSRui Paulo 	res = os_calloc(count + 1, sizeof(char *));
4151f05cddf9SRui Paulo 	if (res == NULL)
4152f05cddf9SRui Paulo 		return NULL;
4153f05cddf9SRui Paulo 
4154f05cddf9SRui Paulo 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
4155f05cddf9SRui Paulo 		res[i] = os_strdup(wpa_cli_commands[i].cmd);
4156f05cddf9SRui Paulo 		if (res[i] == NULL)
4157f05cddf9SRui Paulo 			break;
4158f05cddf9SRui Paulo 	}
4159f05cddf9SRui Paulo 
41605b9c547cSRui Paulo 	dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
41615b9c547cSRui Paulo 		size_t len = 8 + os_strlen(e->txt);
41625b9c547cSRui Paulo 		res[i] = os_malloc(len);
41635b9c547cSRui Paulo 		if (res[i] == NULL)
41645b9c547cSRui Paulo 			break;
41655b9c547cSRui Paulo 		os_snprintf(res[i], len, "ifname=%s", e->txt);
41665b9c547cSRui Paulo 		i++;
41675b9c547cSRui Paulo 	}
41685b9c547cSRui Paulo 
41695b9c547cSRui Paulo 	dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
41705b9c547cSRui Paulo 		res[i] = os_strdup(e->txt);
41715b9c547cSRui Paulo 		if (res[i] == NULL)
41725b9c547cSRui Paulo 			break;
41735b9c547cSRui Paulo 		i++;
41745b9c547cSRui Paulo 	}
41755b9c547cSRui Paulo 
4176f05cddf9SRui Paulo 	return res;
4177f05cddf9SRui Paulo }
4178f05cddf9SRui Paulo 
4179f05cddf9SRui Paulo 
wpa_cli_cmd_completion(const char * cmd,const char * str,int pos)4180f05cddf9SRui Paulo static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
4181f05cddf9SRui Paulo 				      int pos)
4182f05cddf9SRui Paulo {
4183f05cddf9SRui Paulo 	int i;
4184f05cddf9SRui Paulo 
4185f05cddf9SRui Paulo 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
4186f05cddf9SRui Paulo 		if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
4187f05cddf9SRui Paulo 			if (wpa_cli_commands[i].completion)
4188f05cddf9SRui Paulo 				return wpa_cli_commands[i].completion(str,
4189f05cddf9SRui Paulo 								      pos);
4190f05cddf9SRui Paulo 			edit_clear_line();
4191f05cddf9SRui Paulo 			printf("\r%s\n", wpa_cli_commands[i].usage);
4192f05cddf9SRui Paulo 			edit_redraw();
4193f05cddf9SRui Paulo 			break;
4194f05cddf9SRui Paulo 		}
4195f05cddf9SRui Paulo 	}
4196f05cddf9SRui Paulo 
4197f05cddf9SRui Paulo 	return NULL;
4198f05cddf9SRui Paulo }
4199f05cddf9SRui Paulo 
4200f05cddf9SRui Paulo 
wpa_cli_edit_completion_cb(void * ctx,const char * str,int pos)4201f05cddf9SRui Paulo static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
4202f05cddf9SRui Paulo {
4203f05cddf9SRui Paulo 	char **res;
4204f05cddf9SRui Paulo 	const char *end;
4205f05cddf9SRui Paulo 	char *cmd;
4206f05cddf9SRui Paulo 
42075b9c547cSRui Paulo 	if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
42085b9c547cSRui Paulo 		end = os_strchr(str, ' ');
42095b9c547cSRui Paulo 		if (end && pos > end - str) {
42105b9c547cSRui Paulo 			pos -= end - str + 1;
42115b9c547cSRui Paulo 			str = end + 1;
42125b9c547cSRui Paulo 		}
42135b9c547cSRui Paulo 	}
42145b9c547cSRui Paulo 
4215f05cddf9SRui Paulo 	end = os_strchr(str, ' ');
4216f05cddf9SRui Paulo 	if (end == NULL || str + pos < end)
4217f05cddf9SRui Paulo 		return wpa_list_cmd_list();
4218f05cddf9SRui Paulo 
4219f05cddf9SRui Paulo 	cmd = os_malloc(pos + 1);
4220f05cddf9SRui Paulo 	if (cmd == NULL)
4221f05cddf9SRui Paulo 		return NULL;
4222f05cddf9SRui Paulo 	os_memcpy(cmd, str, pos);
4223f05cddf9SRui Paulo 	cmd[end - str] = '\0';
4224f05cddf9SRui Paulo 	res = wpa_cli_cmd_completion(cmd, str, pos);
4225f05cddf9SRui Paulo 	os_free(cmd);
4226f05cddf9SRui Paulo 	return res;
4227f05cddf9SRui Paulo }
422839beb93cSSam Leffler 
422939beb93cSSam Leffler 
wpa_request(struct wpa_ctrl * ctrl,int argc,char * argv[])423039beb93cSSam Leffler static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
423139beb93cSSam Leffler {
4232325151a3SRui Paulo 	const struct wpa_cli_cmd *cmd, *match = NULL;
423339beb93cSSam Leffler 	int count;
423439beb93cSSam Leffler 	int ret = 0;
423539beb93cSSam Leffler 
42365b9c547cSRui Paulo 	if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
42375b9c547cSRui Paulo 		ifname_prefix = argv[0] + 7;
42385b9c547cSRui Paulo 		argv = &argv[1];
42395b9c547cSRui Paulo 		argc--;
42405b9c547cSRui Paulo 	} else
42415b9c547cSRui Paulo 		ifname_prefix = NULL;
42425b9c547cSRui Paulo 
42435b9c547cSRui Paulo 	if (argc == 0)
42445b9c547cSRui Paulo 		return -1;
42455b9c547cSRui Paulo 
424639beb93cSSam Leffler 	count = 0;
424739beb93cSSam Leffler 	cmd = wpa_cli_commands;
424839beb93cSSam Leffler 	while (cmd->cmd) {
424939beb93cSSam Leffler 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
425039beb93cSSam Leffler 		{
425139beb93cSSam Leffler 			match = cmd;
425239beb93cSSam Leffler 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
425339beb93cSSam Leffler 				/* we have an exact match */
425439beb93cSSam Leffler 				count = 1;
425539beb93cSSam Leffler 				break;
425639beb93cSSam Leffler 			}
425739beb93cSSam Leffler 			count++;
425839beb93cSSam Leffler 		}
425939beb93cSSam Leffler 		cmd++;
426039beb93cSSam Leffler 	}
426139beb93cSSam Leffler 
426239beb93cSSam Leffler 	if (count > 1) {
426339beb93cSSam Leffler 		printf("Ambiguous command '%s'; possible commands:", argv[0]);
426439beb93cSSam Leffler 		cmd = wpa_cli_commands;
426539beb93cSSam Leffler 		while (cmd->cmd) {
426639beb93cSSam Leffler 			if (os_strncasecmp(cmd->cmd, argv[0],
426739beb93cSSam Leffler 					   os_strlen(argv[0])) == 0) {
426839beb93cSSam Leffler 				printf(" %s", cmd->cmd);
426939beb93cSSam Leffler 			}
427039beb93cSSam Leffler 			cmd++;
427139beb93cSSam Leffler 		}
427239beb93cSSam Leffler 		printf("\n");
427339beb93cSSam Leffler 		ret = 1;
427439beb93cSSam Leffler 	} else if (count == 0) {
427539beb93cSSam Leffler 		printf("Unknown command '%s'\n", argv[0]);
427639beb93cSSam Leffler 		ret = 1;
427739beb93cSSam Leffler 	} else {
427839beb93cSSam Leffler 		ret = match->handler(ctrl, argc - 1, &argv[1]);
427939beb93cSSam Leffler 	}
428039beb93cSSam Leffler 
428139beb93cSSam Leffler 	return ret;
428239beb93cSSam Leffler }
428339beb93cSSam Leffler 
428439beb93cSSam Leffler 
wpa_cli_exec(const char * program,const char * arg1,const char * arg2)428539beb93cSSam Leffler static int wpa_cli_exec(const char *program, const char *arg1,
428639beb93cSSam Leffler 			const char *arg2)
428739beb93cSSam Leffler {
42885b9c547cSRui Paulo 	char *arg;
428939beb93cSSam Leffler 	size_t len;
429039beb93cSSam Leffler 	int res;
429139beb93cSSam Leffler 
4292780fb4a2SCy Schubert 	/* If no interface is specified, set the global */
4293780fb4a2SCy Schubert 	if (!arg1)
4294780fb4a2SCy Schubert 		arg1 = "global";
4295780fb4a2SCy Schubert 
42965b9c547cSRui Paulo 	len = os_strlen(arg1) + os_strlen(arg2) + 2;
42975b9c547cSRui Paulo 	arg = os_malloc(len);
42985b9c547cSRui Paulo 	if (arg == NULL)
429939beb93cSSam Leffler 		return -1;
43005b9c547cSRui Paulo 	os_snprintf(arg, len, "%s %s", arg1, arg2);
43015b9c547cSRui Paulo 	res = os_exec(program, arg, 1);
43025b9c547cSRui Paulo 	os_free(arg);
430339beb93cSSam Leffler 
43045b9c547cSRui Paulo 	return res;
430539beb93cSSam Leffler }
430639beb93cSSam Leffler 
430739beb93cSSam Leffler 
wpa_cli_action_process(const char * msg)430839beb93cSSam Leffler static void wpa_cli_action_process(const char *msg)
430939beb93cSSam Leffler {
431039beb93cSSam Leffler 	const char *pos;
431139beb93cSSam Leffler 	char *copy = NULL, *id, *pos2;
43125b9c547cSRui Paulo 	const char *ifname = ctrl_ifname;
43135b9c547cSRui Paulo 	char ifname_buf[100];
431439beb93cSSam Leffler 
4315325151a3SRui Paulo 	if (eloop_terminated())
4316325151a3SRui Paulo 		return;
4317325151a3SRui Paulo 
431839beb93cSSam Leffler 	pos = msg;
43195b9c547cSRui Paulo 	if (os_strncmp(pos, "IFNAME=", 7) == 0) {
43205b9c547cSRui Paulo 		const char *end;
43215b9c547cSRui Paulo 		end = os_strchr(pos + 7, ' ');
43225b9c547cSRui Paulo 		if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
43235b9c547cSRui Paulo 			pos += 7;
43245b9c547cSRui Paulo 			os_memcpy(ifname_buf, pos, end - pos);
43255b9c547cSRui Paulo 			ifname_buf[end - pos] = '\0';
43265b9c547cSRui Paulo 			ifname = ifname_buf;
43275b9c547cSRui Paulo 			pos = end + 1;
43285b9c547cSRui Paulo 		}
43295b9c547cSRui Paulo 	}
433039beb93cSSam Leffler 	if (*pos == '<') {
43315b9c547cSRui Paulo 		const char *prev = pos;
433239beb93cSSam Leffler 		/* skip priority */
433339beb93cSSam Leffler 		pos = os_strchr(pos, '>');
433439beb93cSSam Leffler 		if (pos)
433539beb93cSSam Leffler 			pos++;
433639beb93cSSam Leffler 		else
43375b9c547cSRui Paulo 			pos = prev;
433839beb93cSSam Leffler 	}
433939beb93cSSam Leffler 
4340780fb4a2SCy Schubert 	if (str_starts(pos, WPA_EVENT_CONNECTED)) {
434139beb93cSSam Leffler 		int new_id = -1;
434239beb93cSSam Leffler 		os_unsetenv("WPA_ID");
434339beb93cSSam Leffler 		os_unsetenv("WPA_ID_STR");
434439beb93cSSam Leffler 		os_unsetenv("WPA_CTRL_DIR");
434539beb93cSSam Leffler 
434639beb93cSSam Leffler 		pos = os_strstr(pos, "[id=");
434739beb93cSSam Leffler 		if (pos)
434839beb93cSSam Leffler 			copy = os_strdup(pos + 4);
434939beb93cSSam Leffler 
435039beb93cSSam Leffler 		if (copy) {
435139beb93cSSam Leffler 			pos2 = id = copy;
435239beb93cSSam Leffler 			while (*pos2 && *pos2 != ' ')
435339beb93cSSam Leffler 				pos2++;
435439beb93cSSam Leffler 			*pos2++ = '\0';
435539beb93cSSam Leffler 			new_id = atoi(id);
435639beb93cSSam Leffler 			os_setenv("WPA_ID", id, 1);
435739beb93cSSam Leffler 			while (*pos2 && *pos2 != '=')
435839beb93cSSam Leffler 				pos2++;
435939beb93cSSam Leffler 			if (*pos2 == '=')
436039beb93cSSam Leffler 				pos2++;
436139beb93cSSam Leffler 			id = pos2;
436239beb93cSSam Leffler 			while (*pos2 && *pos2 != ']')
436339beb93cSSam Leffler 				pos2++;
436439beb93cSSam Leffler 			*pos2 = '\0';
436539beb93cSSam Leffler 			os_setenv("WPA_ID_STR", id, 1);
436639beb93cSSam Leffler 			os_free(copy);
436739beb93cSSam Leffler 		}
436839beb93cSSam Leffler 
436939beb93cSSam Leffler 		os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
437039beb93cSSam Leffler 
43715b9c547cSRui Paulo 		if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
437239beb93cSSam Leffler 			wpa_cli_connected = 1;
437339beb93cSSam Leffler 			wpa_cli_last_id = new_id;
43745b9c547cSRui Paulo 			wpa_cli_exec(action_file, ifname, "CONNECTED");
437539beb93cSSam Leffler 		}
4376780fb4a2SCy Schubert 	} else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) {
437739beb93cSSam Leffler 		if (wpa_cli_connected) {
437839beb93cSSam Leffler 			wpa_cli_connected = 0;
43795b9c547cSRui Paulo 			wpa_cli_exec(action_file, ifname, "DISCONNECTED");
438039beb93cSSam Leffler 		}
4381ce92f5a9SCy Schubert 	} else if (str_starts(pos, WPA_EVENT_TEMP_DISABLED)) {
4382ce92f5a9SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4383206b73d0SCy Schubert 	} else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH_STARTED)) {
4384206b73d0SCy Schubert 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4385*a90b9d01SCy Schubert 	} else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH)) {
4386*a90b9d01SCy Schubert 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4387780fb4a2SCy Schubert 	} else if (str_starts(pos, AP_EVENT_ENABLED)) {
43885b9c547cSRui Paulo 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4389780fb4a2SCy Schubert 	} else if (str_starts(pos, AP_EVENT_DISABLED)) {
43905b9c547cSRui Paulo 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4391780fb4a2SCy Schubert 	} else if (str_starts(pos, MESH_GROUP_STARTED)) {
43925b9c547cSRui Paulo 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4393780fb4a2SCy Schubert 	} else if (str_starts(pos, MESH_GROUP_REMOVED)) {
43945b9c547cSRui Paulo 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4395780fb4a2SCy Schubert 	} else if (str_starts(pos, MESH_PEER_CONNECTED)) {
4396780fb4a2SCy Schubert 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4397780fb4a2SCy Schubert 	} else if (str_starts(pos, MESH_PEER_DISCONNECTED)) {
4398780fb4a2SCy Schubert 		wpa_cli_exec(action_file, ctrl_ifname, pos);
4399780fb4a2SCy Schubert 	} else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) {
44005b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4401780fb4a2SCy Schubert 	} else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) {
44025b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4403780fb4a2SCy Schubert 	} else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
44045b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4405780fb4a2SCy Schubert 	} else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
44065b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4407780fb4a2SCy Schubert 	} else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) {
44085b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4409780fb4a2SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_SUCCESS)) {
44105b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
441185732ac8SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_ACTIVE)) {
441285732ac8SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4413c1d255d3SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_OVERLAP)) {
4414c1d255d3SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4415c1d255d3SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_PIN_ACTIVE)) {
4416c1d255d3SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4417c1d255d3SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_CANCEL)) {
4418c1d255d3SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
441985732ac8SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_TIMEOUT)) {
442085732ac8SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4421780fb4a2SCy Schubert 	} else if (str_starts(pos, WPS_EVENT_FAIL)) {
44225b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4423780fb4a2SCy Schubert 	} else if (str_starts(pos, AP_STA_CONNECTED)) {
44245b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4425780fb4a2SCy Schubert 	} else if (str_starts(pos, AP_STA_DISCONNECTED)) {
44265b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4427780fb4a2SCy Schubert 	} else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) {
44285b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4429780fb4a2SCy Schubert 	} else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
44305b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
4431780fb4a2SCy Schubert 	} else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
44325b9c547cSRui Paulo 		wpa_cli_exec(action_file, ifname, pos);
443385732ac8SCy Schubert 	} else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) {
443485732ac8SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4435206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONF_RECEIVED)) {
4436206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4437206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONFOBJ_AKM)) {
4438206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4439206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONFOBJ_SSID)) {
4440206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4441206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONNECTOR)) {
4442206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4443206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONFOBJ_PASS)) {
4444206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4445206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_CONFOBJ_PSK)) {
4446206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4447206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_C_SIGN_KEY)) {
4448206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4449206b73d0SCy Schubert 	} else if (str_starts(pos, DPP_EVENT_NET_ACCESS_KEY)) {
4450206b73d0SCy Schubert 		wpa_cli_exec(action_file, ifname, pos);
4451780fb4a2SCy Schubert 	} else if (str_starts(pos, WPA_EVENT_TERMINATING)) {
445239beb93cSSam Leffler 		printf("wpa_supplicant is terminating - stop monitoring\n");
4453c1d255d3SCy Schubert 		if (!reconnect)
445439beb93cSSam Leffler 			wpa_cli_quit = 1;
445539beb93cSSam Leffler 	}
445639beb93cSSam Leffler }
445739beb93cSSam Leffler 
445839beb93cSSam Leffler 
445939beb93cSSam Leffler #ifndef CONFIG_ANSI_C_EXTRA
wpa_cli_action_cb(char * msg,size_t len)446039beb93cSSam Leffler static void wpa_cli_action_cb(char *msg, size_t len)
446139beb93cSSam Leffler {
446239beb93cSSam Leffler 	wpa_cli_action_process(msg);
446339beb93cSSam Leffler }
446439beb93cSSam Leffler #endif /* CONFIG_ANSI_C_EXTRA */
446539beb93cSSam Leffler 
446639beb93cSSam Leffler 
wpa_cli_open_global_ctrl(void)44674bc52338SCy Schubert static int wpa_cli_open_global_ctrl(void)
44684bc52338SCy Schubert {
44694bc52338SCy Schubert #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
44704bc52338SCy Schubert 	ctrl_conn = wpa_ctrl_open(NULL);
44714bc52338SCy Schubert #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
44724bc52338SCy Schubert 	ctrl_conn = wpa_ctrl_open(global);
44734bc52338SCy Schubert #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
44744bc52338SCy Schubert 	if (!ctrl_conn) {
44754bc52338SCy Schubert 		fprintf(stderr,
44764bc52338SCy Schubert 			"Failed to connect to wpa_supplicant global interface: %s  error: %s\n",
44774bc52338SCy Schubert 			global, strerror(errno));
44784bc52338SCy Schubert 		return -1;
44794bc52338SCy Schubert 	}
44804bc52338SCy Schubert 
44814bc52338SCy Schubert 	if (interactive) {
44824bc52338SCy Schubert 		update_ifnames(ctrl_conn);
44834bc52338SCy Schubert 		mon_conn = wpa_ctrl_open(global);
44844bc52338SCy Schubert 		if (mon_conn) {
44854bc52338SCy Schubert 			if (wpa_ctrl_attach(mon_conn) == 0) {
44864bc52338SCy Schubert 				wpa_cli_attached = 1;
44874bc52338SCy Schubert 				eloop_register_read_sock(
44884bc52338SCy Schubert 					wpa_ctrl_get_fd(mon_conn),
44894bc52338SCy Schubert 					wpa_cli_mon_receive,
44904bc52338SCy Schubert 					NULL, NULL);
44914bc52338SCy Schubert 			} else {
44924bc52338SCy Schubert 				printf("Failed to open monitor connection through global control interface\n");
44934bc52338SCy Schubert 			}
44944bc52338SCy Schubert 		}
44954bc52338SCy Schubert 		update_stations(ctrl_conn);
44964bc52338SCy Schubert 	}
44974bc52338SCy Schubert 
44984bc52338SCy Schubert 	return 0;
44994bc52338SCy Schubert }
45004bc52338SCy Schubert 
45014bc52338SCy Schubert 
wpa_cli_reconnect(void)450239beb93cSSam Leffler static void wpa_cli_reconnect(void)
450339beb93cSSam Leffler {
450439beb93cSSam Leffler 	wpa_cli_close_connection();
45054bc52338SCy Schubert 	if ((global && wpa_cli_open_global_ctrl() < 0) ||
45064bc52338SCy Schubert 	    (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0))
4507f05cddf9SRui Paulo 		return;
4508f05cddf9SRui Paulo 
4509f05cddf9SRui Paulo 	if (interactive) {
4510f05cddf9SRui Paulo 		edit_clear_line();
4511f05cddf9SRui Paulo 		printf("\rConnection to wpa_supplicant re-established\n");
4512f05cddf9SRui Paulo 		edit_redraw();
451385732ac8SCy Schubert 		update_stations(ctrl_conn);
4514f05cddf9SRui Paulo 	}
451539beb93cSSam Leffler }
451639beb93cSSam Leffler 
451739beb93cSSam Leffler 
cli_event(const char * str)4518f05cddf9SRui Paulo static void cli_event(const char *str)
451939beb93cSSam Leffler {
4520f05cddf9SRui Paulo 	const char *start, *s;
4521f05cddf9SRui Paulo 
4522f05cddf9SRui Paulo 	start = os_strchr(str, '>');
4523f05cddf9SRui Paulo 	if (start == NULL)
4524f05cddf9SRui Paulo 		return;
4525f05cddf9SRui Paulo 
4526f05cddf9SRui Paulo 	start++;
4527f05cddf9SRui Paulo 
4528f05cddf9SRui Paulo 	if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
4529f05cddf9SRui Paulo 		s = os_strchr(start, ' ');
4530f05cddf9SRui Paulo 		if (s == NULL)
4531f05cddf9SRui Paulo 			return;
4532f05cddf9SRui Paulo 		s = os_strchr(s + 1, ' ');
4533f05cddf9SRui Paulo 		if (s == NULL)
4534f05cddf9SRui Paulo 			return;
4535f05cddf9SRui Paulo 		cli_txt_list_add(&bsses, s + 1);
4536f05cddf9SRui Paulo 		return;
4537f05cddf9SRui Paulo 	}
4538f05cddf9SRui Paulo 
4539f05cddf9SRui Paulo 	if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
4540f05cddf9SRui Paulo 		s = os_strchr(start, ' ');
4541f05cddf9SRui Paulo 		if (s == NULL)
4542f05cddf9SRui Paulo 			return;
4543f05cddf9SRui Paulo 		s = os_strchr(s + 1, ' ');
4544f05cddf9SRui Paulo 		if (s == NULL)
4545f05cddf9SRui Paulo 			return;
4546f05cddf9SRui Paulo 		cli_txt_list_del_addr(&bsses, s + 1);
4547f05cddf9SRui Paulo 		return;
4548f05cddf9SRui Paulo 	}
4549f05cddf9SRui Paulo 
4550f05cddf9SRui Paulo #ifdef CONFIG_P2P
4551f05cddf9SRui Paulo 	if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
4552f05cddf9SRui Paulo 		s = os_strstr(start, " p2p_dev_addr=");
4553f05cddf9SRui Paulo 		if (s == NULL)
4554f05cddf9SRui Paulo 			return;
4555f05cddf9SRui Paulo 		cli_txt_list_add_addr(&p2p_peers, s + 14);
4556f05cddf9SRui Paulo 		return;
4557f05cddf9SRui Paulo 	}
4558f05cddf9SRui Paulo 
4559f05cddf9SRui Paulo 	if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
4560f05cddf9SRui Paulo 		s = os_strstr(start, " p2p_dev_addr=");
4561f05cddf9SRui Paulo 		if (s == NULL)
4562f05cddf9SRui Paulo 			return;
4563f05cddf9SRui Paulo 		cli_txt_list_del_addr(&p2p_peers, s + 14);
4564f05cddf9SRui Paulo 		return;
4565f05cddf9SRui Paulo 	}
4566f05cddf9SRui Paulo 
4567f05cddf9SRui Paulo 	if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
4568f05cddf9SRui Paulo 		s = os_strchr(start, ' ');
4569f05cddf9SRui Paulo 		if (s == NULL)
4570f05cddf9SRui Paulo 			return;
4571325151a3SRui Paulo 		cli_txt_list_add_word(&p2p_groups, s + 1, ' ');
4572f05cddf9SRui Paulo 		return;
4573f05cddf9SRui Paulo 	}
4574f05cddf9SRui Paulo 
4575f05cddf9SRui Paulo 	if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
4576f05cddf9SRui Paulo 		s = os_strchr(start, ' ');
4577f05cddf9SRui Paulo 		if (s == NULL)
4578f05cddf9SRui Paulo 			return;
4579325151a3SRui Paulo 		cli_txt_list_del_word(&p2p_groups, s + 1, ' ');
4580f05cddf9SRui Paulo 		return;
4581f05cddf9SRui Paulo 	}
4582f05cddf9SRui Paulo #endif /* CONFIG_P2P */
4583f05cddf9SRui Paulo }
4584f05cddf9SRui Paulo 
4585f05cddf9SRui Paulo 
check_terminating(const char * msg)4586f05cddf9SRui Paulo static int check_terminating(const char *msg)
4587f05cddf9SRui Paulo {
4588f05cddf9SRui Paulo 	const char *pos = msg;
4589f05cddf9SRui Paulo 
4590f05cddf9SRui Paulo 	if (*pos == '<') {
4591f05cddf9SRui Paulo 		/* skip priority */
4592f05cddf9SRui Paulo 		pos = os_strchr(pos, '>');
4593f05cddf9SRui Paulo 		if (pos)
4594f05cddf9SRui Paulo 			pos++;
4595f05cddf9SRui Paulo 		else
4596f05cddf9SRui Paulo 			pos = msg;
4597f05cddf9SRui Paulo 	}
4598f05cddf9SRui Paulo 
4599780fb4a2SCy Schubert 	if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
4600f05cddf9SRui Paulo 		edit_clear_line();
4601f05cddf9SRui Paulo 		printf("\rConnection to wpa_supplicant lost - trying to "
4602f05cddf9SRui Paulo 		       "reconnect\n");
4603f05cddf9SRui Paulo 		edit_redraw();
4604f05cddf9SRui Paulo 		wpa_cli_attached = 0;
4605f05cddf9SRui Paulo 		wpa_cli_close_connection();
4606f05cddf9SRui Paulo 		return 1;
4607f05cddf9SRui Paulo 	}
4608f05cddf9SRui Paulo 
4609f05cddf9SRui Paulo 	return 0;
4610f05cddf9SRui Paulo }
4611f05cddf9SRui Paulo 
4612f05cddf9SRui Paulo 
wpa_cli_recv_pending(struct wpa_ctrl * ctrl,int action_monitor)4613f05cddf9SRui Paulo static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
4614f05cddf9SRui Paulo {
461539beb93cSSam Leffler 	if (ctrl_conn == NULL) {
461639beb93cSSam Leffler 		wpa_cli_reconnect();
461739beb93cSSam Leffler 		return;
461839beb93cSSam Leffler 	}
461939beb93cSSam Leffler 	while (wpa_ctrl_pending(ctrl) > 0) {
46205b9c547cSRui Paulo 		char buf[4096];
462139beb93cSSam Leffler 		size_t len = sizeof(buf) - 1;
462239beb93cSSam Leffler 		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
462339beb93cSSam Leffler 			buf[len] = '\0';
462439beb93cSSam Leffler 			if (action_monitor)
462539beb93cSSam Leffler 				wpa_cli_action_process(buf);
462639beb93cSSam Leffler 			else {
4627f05cddf9SRui Paulo 				cli_event(buf);
4628f05cddf9SRui Paulo 				if (wpa_cli_show_event(buf)) {
4629f05cddf9SRui Paulo 					edit_clear_line();
4630f05cddf9SRui Paulo 					printf("\r%s\n", buf);
4631f05cddf9SRui Paulo 					edit_redraw();
4632f05cddf9SRui Paulo 				}
4633f05cddf9SRui Paulo 
4634f05cddf9SRui Paulo 				if (interactive && check_terminating(buf) > 0)
4635f05cddf9SRui Paulo 					return;
463639beb93cSSam Leffler 			}
463739beb93cSSam Leffler 		} else {
463839beb93cSSam Leffler 			printf("Could not read pending message.\n");
463939beb93cSSam Leffler 			break;
464039beb93cSSam Leffler 		}
464139beb93cSSam Leffler 	}
464239beb93cSSam Leffler 
464339beb93cSSam Leffler 	if (wpa_ctrl_pending(ctrl) < 0) {
464439beb93cSSam Leffler 		printf("Connection to wpa_supplicant lost - trying to "
464539beb93cSSam Leffler 		       "reconnect\n");
4646c1d255d3SCy Schubert 		if (reconnect) {
4647c1d255d3SCy Schubert 			eloop_terminate();
4648c1d255d3SCy Schubert 			return;
4649c1d255d3SCy Schubert 		}
465039beb93cSSam Leffler 		wpa_cli_reconnect();
465139beb93cSSam Leffler 	}
465239beb93cSSam Leffler }
465339beb93cSSam Leffler 
4654f05cddf9SRui Paulo 
wpa_cli_ping(void * eloop_ctx,void * timeout_ctx)4655f05cddf9SRui Paulo static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
4656f05cddf9SRui Paulo {
46575b9c547cSRui Paulo 	if (ctrl_conn) {
46585b9c547cSRui Paulo 		int res;
46595b9c547cSRui Paulo 		char *prefix = ifname_prefix;
46605b9c547cSRui Paulo 
46615b9c547cSRui Paulo 		ifname_prefix = NULL;
46625b9c547cSRui Paulo 		res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
46635b9c547cSRui Paulo 		ifname_prefix = prefix;
46645b9c547cSRui Paulo 		if (res) {
4665f05cddf9SRui Paulo 			printf("Connection to wpa_supplicant lost - trying to "
4666f05cddf9SRui Paulo 			       "reconnect\n");
4667f05cddf9SRui Paulo 			wpa_cli_close_connection();
4668f05cddf9SRui Paulo 		}
46695b9c547cSRui Paulo 	}
4670f05cddf9SRui Paulo 	if (!ctrl_conn)
4671f05cddf9SRui Paulo 		wpa_cli_reconnect();
4672f05cddf9SRui Paulo 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
4673f05cddf9SRui Paulo }
4674f05cddf9SRui Paulo 
4675f05cddf9SRui Paulo 
wpa_cli_mon_receive(int sock,void * eloop_ctx,void * sock_ctx)4676f05cddf9SRui Paulo static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
4677f05cddf9SRui Paulo {
4678f05cddf9SRui Paulo 	wpa_cli_recv_pending(mon_conn, 0);
4679f05cddf9SRui Paulo }
4680f05cddf9SRui Paulo 
4681f05cddf9SRui Paulo 
wpa_cli_edit_cmd_cb(void * ctx,char * cmd)4682f05cddf9SRui Paulo static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
4683f05cddf9SRui Paulo {
4684f05cddf9SRui Paulo 	char *argv[max_args];
4685f05cddf9SRui Paulo 	int argc;
4686f05cddf9SRui Paulo 	argc = tokenize_cmd(cmd, argv);
468739beb93cSSam Leffler 	if (argc)
468839beb93cSSam Leffler 		wpa_request(ctrl_conn, argc, argv);
468939beb93cSSam Leffler }
4690f05cddf9SRui Paulo 
4691f05cddf9SRui Paulo 
wpa_cli_edit_eof_cb(void * ctx)4692f05cddf9SRui Paulo static void wpa_cli_edit_eof_cb(void *ctx)
4693f05cddf9SRui Paulo {
4694f05cddf9SRui Paulo 	eloop_terminate();
4695f05cddf9SRui Paulo }
4696f05cddf9SRui Paulo 
4697f05cddf9SRui Paulo 
4698f05cddf9SRui Paulo static int warning_displayed = 0;
4699f05cddf9SRui Paulo static char *hfile = NULL;
4700f05cddf9SRui Paulo static int edit_started = 0;
4701f05cddf9SRui Paulo 
start_edit(void)4702f05cddf9SRui Paulo static void start_edit(void)
4703f05cddf9SRui Paulo {
4704f05cddf9SRui Paulo 	char *home;
4705f05cddf9SRui Paulo 	char *ps = NULL;
4706f05cddf9SRui Paulo 
4707f05cddf9SRui Paulo #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
4708f05cddf9SRui Paulo 	ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
4709f05cddf9SRui Paulo #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
4710f05cddf9SRui Paulo 
4711325151a3SRui Paulo #ifdef CONFIG_WPA_CLI_HISTORY_DIR
4712325151a3SRui Paulo 	home = CONFIG_WPA_CLI_HISTORY_DIR;
4713325151a3SRui Paulo #else /* CONFIG_WPA_CLI_HISTORY_DIR */
4714f05cddf9SRui Paulo 	home = getenv("HOME");
4715325151a3SRui Paulo #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
4716f05cddf9SRui Paulo 	if (home) {
4717f05cddf9SRui Paulo 		const char *fname = ".wpa_cli_history";
4718f05cddf9SRui Paulo 		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
4719f05cddf9SRui Paulo 		hfile = os_malloc(hfile_len);
4720f05cddf9SRui Paulo 		if (hfile)
4721f05cddf9SRui Paulo 			os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
4722f05cddf9SRui Paulo 	}
4723f05cddf9SRui Paulo 
4724f05cddf9SRui Paulo 	if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
4725f05cddf9SRui Paulo 		      wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
4726f05cddf9SRui Paulo 		eloop_terminate();
4727f05cddf9SRui Paulo 		return;
4728f05cddf9SRui Paulo 	}
4729f05cddf9SRui Paulo 
4730f05cddf9SRui Paulo 	edit_started = 1;
4731f05cddf9SRui Paulo 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
4732f05cddf9SRui Paulo }
4733f05cddf9SRui Paulo 
4734f05cddf9SRui Paulo 
update_bssid_list(struct wpa_ctrl * ctrl)47355b9c547cSRui Paulo static void update_bssid_list(struct wpa_ctrl *ctrl)
47365b9c547cSRui Paulo {
47375b9c547cSRui Paulo 	char buf[4096];
47385b9c547cSRui Paulo 	size_t len = sizeof(buf);
47395b9c547cSRui Paulo 	int ret;
474085732ac8SCy Schubert 	const char *cmd = "BSS RANGE=ALL MASK=0x2";
47415b9c547cSRui Paulo 	char *pos, *end;
47425b9c547cSRui Paulo 
47435b9c547cSRui Paulo 	if (ctrl == NULL)
47445b9c547cSRui Paulo 		return;
47455b9c547cSRui Paulo 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
47465b9c547cSRui Paulo 	if (ret < 0)
47475b9c547cSRui Paulo 		return;
47485b9c547cSRui Paulo 	buf[len] = '\0';
47495b9c547cSRui Paulo 
47505b9c547cSRui Paulo 	pos = buf;
47515b9c547cSRui Paulo 	while (pos) {
47525b9c547cSRui Paulo 		pos = os_strstr(pos, "bssid=");
47535b9c547cSRui Paulo 		if (pos == NULL)
47545b9c547cSRui Paulo 			break;
47555b9c547cSRui Paulo 		pos += 6;
47565b9c547cSRui Paulo 		end = os_strchr(pos, '\n');
47575b9c547cSRui Paulo 		if (end == NULL)
47585b9c547cSRui Paulo 			break;
47595b9c547cSRui Paulo 		*end = '\0';
47605b9c547cSRui Paulo 		cli_txt_list_add(&bsses, pos);
47615b9c547cSRui Paulo 		pos = end + 1;
47625b9c547cSRui Paulo 	}
47635b9c547cSRui Paulo }
47645b9c547cSRui Paulo 
47655b9c547cSRui Paulo 
update_ifnames(struct wpa_ctrl * ctrl)47665b9c547cSRui Paulo static void update_ifnames(struct wpa_ctrl *ctrl)
47675b9c547cSRui Paulo {
47685b9c547cSRui Paulo 	char buf[4096];
47695b9c547cSRui Paulo 	size_t len = sizeof(buf);
47705b9c547cSRui Paulo 	int ret;
477185732ac8SCy Schubert 	const char *cmd = "INTERFACES";
47725b9c547cSRui Paulo 	char *pos, *end;
47735b9c547cSRui Paulo 	char txt[200];
47745b9c547cSRui Paulo 
47755b9c547cSRui Paulo 	cli_txt_list_flush(&ifnames);
47765b9c547cSRui Paulo 
47775b9c547cSRui Paulo 	if (ctrl == NULL)
47785b9c547cSRui Paulo 		return;
47795b9c547cSRui Paulo 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
47805b9c547cSRui Paulo 	if (ret < 0)
47815b9c547cSRui Paulo 		return;
47825b9c547cSRui Paulo 	buf[len] = '\0';
47835b9c547cSRui Paulo 
47845b9c547cSRui Paulo 	pos = buf;
47855b9c547cSRui Paulo 	while (pos) {
47865b9c547cSRui Paulo 		end = os_strchr(pos, '\n');
47875b9c547cSRui Paulo 		if (end == NULL)
47885b9c547cSRui Paulo 			break;
47895b9c547cSRui Paulo 		*end = '\0';
47905b9c547cSRui Paulo 		ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
47915b9c547cSRui Paulo 		if (!os_snprintf_error(sizeof(txt), ret))
47925b9c547cSRui Paulo 			cli_txt_list_add(&ifnames, txt);
47935b9c547cSRui Paulo 		pos = end + 1;
47945b9c547cSRui Paulo 	}
47955b9c547cSRui Paulo }
47965b9c547cSRui Paulo 
47975b9c547cSRui Paulo 
update_creds(struct wpa_ctrl * ctrl)479885732ac8SCy Schubert static void update_creds(struct wpa_ctrl *ctrl)
479985732ac8SCy Schubert {
480085732ac8SCy Schubert 	char buf[4096];
480185732ac8SCy Schubert 	size_t len = sizeof(buf);
480285732ac8SCy Schubert 	int ret;
480385732ac8SCy Schubert 	const char *cmd = "LIST_CREDS";
480485732ac8SCy Schubert 	char *pos, *end;
480585732ac8SCy Schubert 	int header = 1;
480685732ac8SCy Schubert 
480785732ac8SCy Schubert 	cli_txt_list_flush(&creds);
480885732ac8SCy Schubert 
480985732ac8SCy Schubert 	if (ctrl == NULL)
481085732ac8SCy Schubert 		return;
481185732ac8SCy Schubert 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
481285732ac8SCy Schubert 	if (ret < 0)
481385732ac8SCy Schubert 		return;
481485732ac8SCy Schubert 	buf[len] = '\0';
481585732ac8SCy Schubert 
481685732ac8SCy Schubert 	pos = buf;
481785732ac8SCy Schubert 	while (pos) {
481885732ac8SCy Schubert 		end = os_strchr(pos, '\n');
481985732ac8SCy Schubert 		if (end == NULL)
482085732ac8SCy Schubert 			break;
482185732ac8SCy Schubert 		*end = '\0';
482285732ac8SCy Schubert 		if (!header)
482385732ac8SCy Schubert 			cli_txt_list_add_word(&creds, pos, '\t');
482485732ac8SCy Schubert 		header = 0;
482585732ac8SCy Schubert 		pos = end + 1;
482685732ac8SCy Schubert 	}
482785732ac8SCy Schubert }
482885732ac8SCy Schubert 
482985732ac8SCy Schubert 
update_networks(struct wpa_ctrl * ctrl)4830325151a3SRui Paulo static void update_networks(struct wpa_ctrl *ctrl)
4831325151a3SRui Paulo {
4832325151a3SRui Paulo 	char buf[4096];
4833325151a3SRui Paulo 	size_t len = sizeof(buf);
4834325151a3SRui Paulo 	int ret;
483585732ac8SCy Schubert 	const char *cmd = "LIST_NETWORKS";
4836325151a3SRui Paulo 	char *pos, *end;
4837325151a3SRui Paulo 	int header = 1;
4838325151a3SRui Paulo 
4839325151a3SRui Paulo 	cli_txt_list_flush(&networks);
4840325151a3SRui Paulo 
4841325151a3SRui Paulo 	if (ctrl == NULL)
4842325151a3SRui Paulo 		return;
4843325151a3SRui Paulo 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4844325151a3SRui Paulo 	if (ret < 0)
4845325151a3SRui Paulo 		return;
4846325151a3SRui Paulo 	buf[len] = '\0';
4847325151a3SRui Paulo 
4848325151a3SRui Paulo 	pos = buf;
4849325151a3SRui Paulo 	while (pos) {
4850325151a3SRui Paulo 		end = os_strchr(pos, '\n');
4851325151a3SRui Paulo 		if (end == NULL)
4852325151a3SRui Paulo 			break;
4853325151a3SRui Paulo 		*end = '\0';
4854325151a3SRui Paulo 		if (!header)
4855325151a3SRui Paulo 			cli_txt_list_add_word(&networks, pos, '\t');
4856325151a3SRui Paulo 		header = 0;
4857325151a3SRui Paulo 		pos = end + 1;
4858325151a3SRui Paulo 	}
4859325151a3SRui Paulo }
4860325151a3SRui Paulo 
4861325151a3SRui Paulo 
update_stations(struct wpa_ctrl * ctrl)486285732ac8SCy Schubert static void update_stations(struct wpa_ctrl *ctrl)
486385732ac8SCy Schubert {
486485732ac8SCy Schubert #ifdef CONFIG_AP
486585732ac8SCy Schubert 	char addr[32], cmd[64];
486685732ac8SCy Schubert 
486785732ac8SCy Schubert 	if (!ctrl || !interactive)
486885732ac8SCy Schubert 		return;
486985732ac8SCy Schubert 
487085732ac8SCy Schubert 	cli_txt_list_flush(&stations);
487185732ac8SCy Schubert 
487285732ac8SCy Schubert 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0))
487385732ac8SCy Schubert 		return;
487485732ac8SCy Schubert 	do {
487585732ac8SCy Schubert 		if (os_strcmp(addr, "") != 0)
487685732ac8SCy Schubert 			cli_txt_list_add(&stations, addr);
487785732ac8SCy Schubert 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
487885732ac8SCy Schubert 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0);
487985732ac8SCy Schubert #endif /* CONFIG_AP */
488085732ac8SCy Schubert }
488185732ac8SCy Schubert 
488285732ac8SCy Schubert 
try_connection(void * eloop_ctx,void * timeout_ctx)4883f05cddf9SRui Paulo static void try_connection(void *eloop_ctx, void *timeout_ctx)
4884f05cddf9SRui Paulo {
48855b9c547cSRui Paulo 	if (ctrl_conn)
48865b9c547cSRui Paulo 		goto done;
48875b9c547cSRui Paulo 
4888f05cddf9SRui Paulo 	if (ctrl_ifname == NULL)
4889f05cddf9SRui Paulo 		ctrl_ifname = wpa_cli_get_default_ifname();
4890f05cddf9SRui Paulo 
4891780fb4a2SCy Schubert 	if (wpa_cli_open_connection(ctrl_ifname, 1)) {
4892f05cddf9SRui Paulo 		if (!warning_displayed) {
4893f05cddf9SRui Paulo 			printf("Could not connect to wpa_supplicant: "
48945b9c547cSRui Paulo 			       "%s - re-trying\n",
48955b9c547cSRui Paulo 			       ctrl_ifname ? ctrl_ifname : "(nil)");
4896f05cddf9SRui Paulo 			warning_displayed = 1;
4897f05cddf9SRui Paulo 		}
4898f05cddf9SRui Paulo 		eloop_register_timeout(1, 0, try_connection, NULL, NULL);
4899f05cddf9SRui Paulo 		return;
4900f05cddf9SRui Paulo 	}
4901f05cddf9SRui Paulo 
49025b9c547cSRui Paulo 	update_bssid_list(ctrl_conn);
490385732ac8SCy Schubert 	update_creds(ctrl_conn);
4904325151a3SRui Paulo 	update_networks(ctrl_conn);
490585732ac8SCy Schubert 	update_stations(ctrl_conn);
49065b9c547cSRui Paulo 
4907f05cddf9SRui Paulo 	if (warning_displayed)
4908f05cddf9SRui Paulo 		printf("Connection established.\n");
4909f05cddf9SRui Paulo 
49105b9c547cSRui Paulo done:
4911f05cddf9SRui Paulo 	start_edit();
4912f05cddf9SRui Paulo }
4913f05cddf9SRui Paulo 
4914f05cddf9SRui Paulo 
wpa_cli_interactive(void)4915f05cddf9SRui Paulo static void wpa_cli_interactive(void)
4916f05cddf9SRui Paulo {
4917f05cddf9SRui Paulo 	printf("\nInteractive mode\n\n");
4918f05cddf9SRui Paulo 
4919f05cddf9SRui Paulo 	eloop_register_timeout(0, 0, try_connection, NULL, NULL);
4920f05cddf9SRui Paulo 	eloop_run();
4921f05cddf9SRui Paulo 	eloop_cancel_timeout(try_connection, NULL, NULL);
4922f05cddf9SRui Paulo 
4923f05cddf9SRui Paulo 	cli_txt_list_flush(&p2p_peers);
4924f05cddf9SRui Paulo 	cli_txt_list_flush(&p2p_groups);
4925f05cddf9SRui Paulo 	cli_txt_list_flush(&bsses);
49265b9c547cSRui Paulo 	cli_txt_list_flush(&ifnames);
492785732ac8SCy Schubert 	cli_txt_list_flush(&creds);
4928325151a3SRui Paulo 	cli_txt_list_flush(&networks);
4929f05cddf9SRui Paulo 	if (edit_started)
4930f05cddf9SRui Paulo 		edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
493139beb93cSSam Leffler 	os_free(hfile);
4932f05cddf9SRui Paulo 	eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
4933f05cddf9SRui Paulo 	wpa_cli_close_connection();
493439beb93cSSam Leffler }
493539beb93cSSam Leffler 
493639beb93cSSam Leffler 
wpa_cli_action_ping(void * eloop_ctx,void * timeout_ctx)4937325151a3SRui Paulo static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
4938325151a3SRui Paulo {
4939325151a3SRui Paulo 	struct wpa_ctrl *ctrl = eloop_ctx;
4940325151a3SRui Paulo 	char buf[256];
4941325151a3SRui Paulo 	size_t len;
4942325151a3SRui Paulo 
4943325151a3SRui Paulo 	/* verify that connection is still working */
4944325151a3SRui Paulo 	len = sizeof(buf) - 1;
4945325151a3SRui Paulo 	if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4946325151a3SRui Paulo 			     wpa_cli_action_cb) < 0 ||
4947325151a3SRui Paulo 	    len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4948325151a3SRui Paulo 		printf("wpa_supplicant did not reply to PING command - exiting\n");
4949325151a3SRui Paulo 		eloop_terminate();
4950325151a3SRui Paulo 		return;
4951325151a3SRui Paulo 	}
4952325151a3SRui Paulo 	eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4953325151a3SRui Paulo 			       ctrl, NULL);
4954325151a3SRui Paulo }
4955325151a3SRui Paulo 
4956325151a3SRui Paulo 
wpa_cli_action_receive(int sock,void * eloop_ctx,void * sock_ctx)4957325151a3SRui Paulo static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
4958325151a3SRui Paulo {
4959325151a3SRui Paulo 	struct wpa_ctrl *ctrl = eloop_ctx;
4960325151a3SRui Paulo 
4961325151a3SRui Paulo 	wpa_cli_recv_pending(ctrl, 1);
4962325151a3SRui Paulo }
4963325151a3SRui Paulo 
4964325151a3SRui Paulo 
wpa_cli_action(struct wpa_ctrl * ctrl)496539beb93cSSam Leffler static void wpa_cli_action(struct wpa_ctrl *ctrl)
496639beb93cSSam Leffler {
496739beb93cSSam Leffler #ifdef CONFIG_ANSI_C_EXTRA
496839beb93cSSam Leffler 	/* TODO: ANSI C version(?) */
496939beb93cSSam Leffler 	printf("Action processing not supported in ANSI C build.\n");
497039beb93cSSam Leffler #else /* CONFIG_ANSI_C_EXTRA */
4971325151a3SRui Paulo 	int fd;
497239beb93cSSam Leffler 
497339beb93cSSam Leffler 	fd = wpa_ctrl_get_fd(ctrl);
4974325151a3SRui Paulo 	eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4975325151a3SRui Paulo 			       ctrl, NULL);
4976325151a3SRui Paulo 	eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
4977325151a3SRui Paulo 	eloop_run();
4978325151a3SRui Paulo 	eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
4979325151a3SRui Paulo 	eloop_unregister_read_sock(fd);
498039beb93cSSam Leffler #endif /* CONFIG_ANSI_C_EXTRA */
498139beb93cSSam Leffler }
498239beb93cSSam Leffler 
498339beb93cSSam Leffler 
wpa_cli_cleanup(void)498439beb93cSSam Leffler static void wpa_cli_cleanup(void)
498539beb93cSSam Leffler {
498639beb93cSSam Leffler 	wpa_cli_close_connection();
498739beb93cSSam Leffler 	if (pid_file)
498839beb93cSSam Leffler 		os_daemonize_terminate(pid_file);
498939beb93cSSam Leffler 
499039beb93cSSam Leffler 	os_program_deinit();
499139beb93cSSam Leffler }
499239beb93cSSam Leffler 
4993f05cddf9SRui Paulo 
wpa_cli_terminate(int sig,void * ctx)4994f05cddf9SRui Paulo static void wpa_cli_terminate(int sig, void *ctx)
499539beb93cSSam Leffler {
4996f05cddf9SRui Paulo 	eloop_terminate();
4997c1d255d3SCy Schubert 	if (reconnect)
4998c1d255d3SCy Schubert 		wpa_cli_quit = 1;
499939beb93cSSam Leffler }
500039beb93cSSam Leffler 
500139beb93cSSam Leffler 
wpa_cli_get_default_ifname(void)500239beb93cSSam Leffler static char * wpa_cli_get_default_ifname(void)
500339beb93cSSam Leffler {
500439beb93cSSam Leffler 	char *ifname = NULL;
500539beb93cSSam Leffler 
5006f05cddf9SRui Paulo #ifdef ANDROID
5007f05cddf9SRui Paulo 	char ifprop[PROPERTY_VALUE_MAX];
5008f05cddf9SRui Paulo 	if (property_get("wifi.interface", ifprop, NULL) != 0) {
5009f05cddf9SRui Paulo 		ifname = os_strdup(ifprop);
5010325151a3SRui Paulo 		printf("Using interface '%s'\n", ifname ? ifname : "N/A");
5011f05cddf9SRui Paulo 	}
5012325151a3SRui Paulo #else /* ANDROID */
5013325151a3SRui Paulo #ifdef CONFIG_CTRL_IFACE_UNIX
5014325151a3SRui Paulo 	struct dirent *dent;
5015325151a3SRui Paulo 	DIR *dir = opendir(ctrl_iface_dir);
5016325151a3SRui Paulo 	if (!dir) {
501739beb93cSSam Leffler 		return NULL;
5018f05cddf9SRui Paulo 	}
501939beb93cSSam Leffler 	while ((dent = readdir(dir))) {
502039beb93cSSam Leffler #ifdef _DIRENT_HAVE_D_TYPE
502139beb93cSSam Leffler 		/*
502239beb93cSSam Leffler 		 * Skip the file if it is not a socket. Also accept
502339beb93cSSam Leffler 		 * DT_UNKNOWN (0) in case the C library or underlying
502439beb93cSSam Leffler 		 * file system does not support d_type.
502539beb93cSSam Leffler 		 */
502639beb93cSSam Leffler 		if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
502739beb93cSSam Leffler 			continue;
502839beb93cSSam Leffler #endif /* _DIRENT_HAVE_D_TYPE */
5029c1d255d3SCy Schubert 		/* Skip current/previous directory and special P2P Device
5030c1d255d3SCy Schubert 		 * interfaces. */
503139beb93cSSam Leffler 		if (os_strcmp(dent->d_name, ".") == 0 ||
5032c1d255d3SCy Schubert 		    os_strcmp(dent->d_name, "..") == 0 ||
5033c1d255d3SCy Schubert 		    os_strncmp(dent->d_name, "p2p-dev-", 8) == 0)
503439beb93cSSam Leffler 			continue;
503539beb93cSSam Leffler 		printf("Selected interface '%s'\n", dent->d_name);
503639beb93cSSam Leffler 		ifname = os_strdup(dent->d_name);
503739beb93cSSam Leffler 		break;
503839beb93cSSam Leffler 	}
503939beb93cSSam Leffler 	closedir(dir);
504039beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE_UNIX */
504139beb93cSSam Leffler 
504239beb93cSSam Leffler #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
50435b9c547cSRui Paulo 	char buf[4096], *pos;
504439beb93cSSam Leffler 	size_t len;
504539beb93cSSam Leffler 	struct wpa_ctrl *ctrl;
504639beb93cSSam Leffler 	int ret;
504739beb93cSSam Leffler 
504839beb93cSSam Leffler 	ctrl = wpa_ctrl_open(NULL);
504939beb93cSSam Leffler 	if (ctrl == NULL)
505039beb93cSSam Leffler 		return NULL;
505139beb93cSSam Leffler 
505239beb93cSSam Leffler 	len = sizeof(buf) - 1;
505339beb93cSSam Leffler 	ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
505439beb93cSSam Leffler 	if (ret >= 0) {
505539beb93cSSam Leffler 		buf[len] = '\0';
505639beb93cSSam Leffler 		pos = os_strchr(buf, '\n');
505739beb93cSSam Leffler 		if (pos)
505839beb93cSSam Leffler 			*pos = '\0';
505939beb93cSSam Leffler 		ifname = os_strdup(buf);
506039beb93cSSam Leffler 	}
506139beb93cSSam Leffler 	wpa_ctrl_close(ctrl);
506239beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
5063325151a3SRui Paulo #endif /* ANDROID */
506439beb93cSSam Leffler 
506539beb93cSSam Leffler 	return ifname;
506639beb93cSSam Leffler }
506739beb93cSSam Leffler 
506839beb93cSSam Leffler 
main(int argc,char * argv[])506939beb93cSSam Leffler int main(int argc, char *argv[])
507039beb93cSSam Leffler {
507139beb93cSSam Leffler 	int c;
507239beb93cSSam Leffler 	int daemonize = 0;
507339beb93cSSam Leffler 	int ret = 0;
507439beb93cSSam Leffler 
507539beb93cSSam Leffler 	if (os_program_init())
507639beb93cSSam Leffler 		return -1;
507739beb93cSSam Leffler 
507839beb93cSSam Leffler 	for (;;) {
5079c1d255d3SCy Schubert 		c = getopt(argc, argv, "a:Bg:G:hi:p:P:rs:v");
508039beb93cSSam Leffler 		if (c < 0)
508139beb93cSSam Leffler 			break;
508239beb93cSSam Leffler 		switch (c) {
508339beb93cSSam Leffler 		case 'a':
508439beb93cSSam Leffler 			action_file = optarg;
508539beb93cSSam Leffler 			break;
508639beb93cSSam Leffler 		case 'B':
508739beb93cSSam Leffler 			daemonize = 1;
508839beb93cSSam Leffler 			break;
508939beb93cSSam Leffler 		case 'g':
509039beb93cSSam Leffler 			global = optarg;
509139beb93cSSam Leffler 			break;
509239beb93cSSam Leffler 		case 'G':
509339beb93cSSam Leffler 			ping_interval = atoi(optarg);
509439beb93cSSam Leffler 			break;
509539beb93cSSam Leffler 		case 'h':
509639beb93cSSam Leffler 			usage();
509739beb93cSSam Leffler 			return 0;
509839beb93cSSam Leffler 		case 'v':
509939beb93cSSam Leffler 			printf("%s\n", wpa_cli_version);
510039beb93cSSam Leffler 			return 0;
510139beb93cSSam Leffler 		case 'i':
510239beb93cSSam Leffler 			os_free(ctrl_ifname);
510339beb93cSSam Leffler 			ctrl_ifname = os_strdup(optarg);
510439beb93cSSam Leffler 			break;
510539beb93cSSam Leffler 		case 'p':
510639beb93cSSam Leffler 			ctrl_iface_dir = optarg;
510739beb93cSSam Leffler 			break;
510839beb93cSSam Leffler 		case 'P':
510939beb93cSSam Leffler 			pid_file = optarg;
511039beb93cSSam Leffler 			break;
5111c1d255d3SCy Schubert 		case 'r':
5112c1d255d3SCy Schubert 			reconnect = 1;
5113c1d255d3SCy Schubert 			break;
5114325151a3SRui Paulo 		case 's':
5115325151a3SRui Paulo 			client_socket_dir = optarg;
5116325151a3SRui Paulo 			break;
511739beb93cSSam Leffler 		default:
511839beb93cSSam Leffler 			usage();
511939beb93cSSam Leffler 			return -1;
512039beb93cSSam Leffler 		}
512139beb93cSSam Leffler 	}
512239beb93cSSam Leffler 
512339beb93cSSam Leffler 	interactive = (argc == optind) && (action_file == NULL);
512439beb93cSSam Leffler 
512539beb93cSSam Leffler 	if (interactive)
5126780fb4a2SCy Schubert 		printf("%s\n\n%s\n\n", wpa_cli_version, cli_license);
512739beb93cSSam Leffler 
5128f05cddf9SRui Paulo 	if (eloop_init())
5129f05cddf9SRui Paulo 		return -1;
5130f05cddf9SRui Paulo 
51314bc52338SCy Schubert 	if (global && wpa_cli_open_global_ctrl() < 0)
513239beb93cSSam Leffler 		return -1;
513339beb93cSSam Leffler 
5134f05cddf9SRui Paulo 	eloop_register_signal_terminate(wpa_cli_terminate, NULL);
5135e28a4053SRui Paulo 
5136*a90b9d01SCy Schubert 	if (!ctrl_ifname && !global)
513739beb93cSSam Leffler 		ctrl_ifname = wpa_cli_get_default_ifname();
5138e28a4053SRui Paulo 
5139c1d255d3SCy Schubert 	if (reconnect && action_file && ctrl_ifname) {
5140c1d255d3SCy Schubert 		while (!wpa_cli_quit) {
5141c1d255d3SCy Schubert 			if (ctrl_conn)
5142c1d255d3SCy Schubert 				wpa_cli_action(ctrl_conn);
5143c1d255d3SCy Schubert 			else
5144c1d255d3SCy Schubert 				os_sleep(1, 0);
5145c1d255d3SCy Schubert 			wpa_cli_close_connection();
5146c1d255d3SCy Schubert 			wpa_cli_open_connection(ctrl_ifname, 0);
5147c1d255d3SCy Schubert 			if (ctrl_conn) {
5148c1d255d3SCy Schubert 				if (wpa_ctrl_attach(ctrl_conn) != 0)
5149c1d255d3SCy Schubert 					wpa_cli_close_connection();
5150c1d255d3SCy Schubert 				else
5151c1d255d3SCy Schubert 					wpa_cli_attached = 1;
5152c1d255d3SCy Schubert 			}
5153c1d255d3SCy Schubert 		}
5154c1d255d3SCy Schubert 	} else if (interactive) {
5155f05cddf9SRui Paulo 		wpa_cli_interactive();
5156e28a4053SRui Paulo 	} else {
5157e28a4053SRui Paulo 		if (!global &&
5158e28a4053SRui Paulo 		    wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
5159f05cddf9SRui Paulo 			fprintf(stderr, "Failed to connect to non-global "
5160f05cddf9SRui Paulo 				"ctrl_ifname: %s  error: %s\n",
51615b9c547cSRui Paulo 				ctrl_ifname ? ctrl_ifname : "(nil)",
51625b9c547cSRui Paulo 				strerror(errno));
5163e28a4053SRui Paulo 			return -1;
5164e28a4053SRui Paulo 		}
516539beb93cSSam Leffler 
5166e28a4053SRui Paulo 		if (action_file) {
516739beb93cSSam Leffler 			if (wpa_ctrl_attach(ctrl_conn) == 0) {
516839beb93cSSam Leffler 				wpa_cli_attached = 1;
516939beb93cSSam Leffler 			} else {
517039beb93cSSam Leffler 				printf("Warning: Failed to attach to "
517139beb93cSSam Leffler 				       "wpa_supplicant.\n");
517239beb93cSSam Leffler 				return -1;
517339beb93cSSam Leffler 			}
517439beb93cSSam Leffler 		}
517539beb93cSSam Leffler 
5176780fb4a2SCy Schubert 		if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
517739beb93cSSam Leffler 			return -1;
517839beb93cSSam Leffler 
5179f05cddf9SRui Paulo 		if (action_file)
518039beb93cSSam Leffler 			wpa_cli_action(ctrl_conn);
518139beb93cSSam Leffler 		else
5182f05cddf9SRui Paulo 			ret = wpa_request(ctrl_conn, argc - optind,
5183f05cddf9SRui Paulo 					  &argv[optind]);
5184f05cddf9SRui Paulo 	}
518539beb93cSSam Leffler 
518639beb93cSSam Leffler 	os_free(ctrl_ifname);
5187f05cddf9SRui Paulo 	eloop_destroy();
518839beb93cSSam Leffler 	wpa_cli_cleanup();
518939beb93cSSam Leffler 
519039beb93cSSam Leffler 	return ret;
519139beb93cSSam Leffler }
519239beb93cSSam Leffler 
519339beb93cSSam Leffler #else /* CONFIG_CTRL_IFACE */
main(int argc,char * argv[])519439beb93cSSam Leffler int main(int argc, char *argv[])
519539beb93cSSam Leffler {
519639beb93cSSam Leffler 	printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
519739beb93cSSam Leffler 	return -1;
519839beb93cSSam Leffler }
519939beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE */
5200