2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = 0;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
84 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
85 static char* redirect_interface = NULL;
88 struct cli_txt_entry {
93 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
95 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
98 static void print_help(const char *cmd);
99 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
100 static void wpa_cli_close_connection(void);
101 static char * wpa_cli_get_default_ifname(void);
102 static char ** wpa_list_cmd_list(void);
105 static void usage(void)
107 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
108 "[-a<action file>] \\\n"
109 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
111 " -h = help (show this usage text)\n"
112 " -v = shown version information\n"
113 " -a = run in daemon mode executing the action file based on "
116 " -B = run a daemon in the background\n"
117 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
118 " default interface: first interface found in socket path\n");
123 static void cli_txt_list_free(struct cli_txt_entry *e)
125 dl_list_del(&e->list);
131 static void cli_txt_list_flush(struct dl_list *list)
133 struct cli_txt_entry *e;
134 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
135 cli_txt_list_free(e);
139 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
142 struct cli_txt_entry *e;
143 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
144 if (os_strcmp(e->txt, txt) == 0)
151 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
153 struct cli_txt_entry *e;
154 e = cli_txt_list_get(txt_list, txt);
156 cli_txt_list_free(e);
160 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
164 if (hwaddr_aton(txt, addr) < 0)
166 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
167 cli_txt_list_del(txt_list, buf);
172 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
176 end = os_strchr(txt, ' ');
178 end = txt + os_strlen(txt);
179 buf = os_malloc(end - txt + 1);
182 os_memcpy(buf, txt, end - txt);
183 buf[end - txt] = '\0';
184 cli_txt_list_del(txt_list, buf);
187 #endif /* CONFIG_P2P */
190 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
192 struct cli_txt_entry *e;
193 e = cli_txt_list_get(txt_list, txt);
196 e = os_zalloc(sizeof(*e));
199 e->txt = os_strdup(txt);
200 if (e->txt == NULL) {
204 dl_list_add(txt_list, &e->list);
210 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
214 if (hwaddr_aton(txt, addr) < 0)
216 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
217 return cli_txt_list_add(txt_list, buf);
221 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
226 end = os_strchr(txt, ' ');
228 end = txt + os_strlen(txt);
229 buf = os_malloc(end - txt + 1);
232 os_memcpy(buf, txt, end - txt);
233 buf[end - txt] = '\0';
234 ret = cli_txt_list_add(txt_list, buf);
238 #endif /* CONFIG_P2P */
241 static char ** cli_txt_list_array(struct dl_list *txt_list)
243 unsigned int i, count = dl_list_len(txt_list);
245 struct cli_txt_entry *e;
247 res = os_calloc(count + 1, sizeof(char *));
252 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
253 res[i] = os_strdup(e->txt);
263 static int get_cmd_arg_num(const char *str, int pos)
267 for (i = 0; i <= pos; i++) {
270 while (i <= pos && str[i] != ' ')
281 static int str_starts(const char *src, const char *match)
283 return os_strncmp(src, match, os_strlen(match)) == 0;
287 static int wpa_cli_show_event(const char *event)
291 start = os_strchr(event, '>');
297 * Skip BSS added/removed events since they can be relatively frequent
298 * and are likely of not much use for an interactive user.
300 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
301 str_starts(start, WPA_EVENT_BSS_REMOVED))
308 static int wpa_cli_open_connection(const char *ifname, int attach)
310 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
311 ctrl_conn = wpa_ctrl_open(ifname);
312 if (ctrl_conn == NULL)
315 if (attach && interactive)
316 mon_conn = wpa_ctrl_open(ifname);
319 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
327 if (access(ctrl_iface_dir, F_OK) < 0) {
328 cfile = os_strdup(ifname);
335 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
336 cfile = os_malloc(flen);
339 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
341 if (res < 0 || res >= flen) {
347 ctrl_conn = wpa_ctrl_open(cfile);
348 if (ctrl_conn == NULL) {
353 if (attach && interactive)
354 mon_conn = wpa_ctrl_open(cfile);
358 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
361 if (wpa_ctrl_attach(mon_conn) == 0) {
362 wpa_cli_attached = 1;
364 eloop_register_read_sock(
365 wpa_ctrl_get_fd(mon_conn),
366 wpa_cli_mon_receive, NULL, NULL);
368 printf("Warning: Failed to attach to "
369 "wpa_supplicant.\n");
370 wpa_cli_close_connection();
379 static void wpa_cli_close_connection(void)
381 if (ctrl_conn == NULL)
384 if (wpa_cli_attached) {
385 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
386 wpa_cli_attached = 0;
388 wpa_ctrl_close(ctrl_conn);
391 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
392 wpa_ctrl_close(mon_conn);
398 static void wpa_cli_msg_cb(char *msg, size_t len)
404 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
407 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
413 if (ctrl_conn == NULL) {
414 printf("Not connected to wpa_supplicant - command dropped.\n");
417 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
418 if (redirect_interface) {
420 arg = os_strchr(cmd, ' ');
423 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s %s", cmd, redirect_interface, arg);
426 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s", cmd, redirect_interface);
429 os_free(redirect_interface);
430 redirect_interface = NULL;
433 len = sizeof(buf) - 1;
434 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
437 printf("'%s' command timed out.\n", cmd);
439 } else if (ret < 0) {
440 printf("'%s' command failed.\n", cmd);
446 if (interactive && len > 0 && buf[len - 1] != '\n')
453 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
455 return _wpa_ctrl_command(ctrl, cmd, 1);
459 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
468 res = os_snprintf(pos, end - pos, "%s", cmd);
469 if (res < 0 || res >= end - pos)
473 for (i = 0; i < argc; i++) {
474 res = os_snprintf(pos, end - pos, " %s", argv[i]);
475 if (res < 0 || res >= end - pos)
480 buf[buflen - 1] = '\0';
484 printf("Too long command\n");
489 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
490 int argc, char *argv[])
493 if (argc < min_args) {
494 printf("Invalid %s command - at least %d argument%s "
495 "required.\n", cmd, min_args,
496 min_args > 1 ? "s are" : " is");
499 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
501 return wpa_ctrl_command(ctrl, buf);
505 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
507 return wpa_ctrl_command(ctrl, "IFNAME");
511 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
514 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
515 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
516 return wpa_ctrl_command(ctrl, "STATUS-WPS");
517 return wpa_ctrl_command(ctrl, "STATUS");
521 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
523 return wpa_ctrl_command(ctrl, "PING");
527 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
529 return wpa_ctrl_command(ctrl, "RELOG");
533 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
535 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
539 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
541 return wpa_ctrl_command(ctrl, "MIB");
545 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
547 return wpa_ctrl_command(ctrl, "PMKSA");
551 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
553 print_help(argc > 0 ? argv[0] : NULL);
558 static char ** wpa_cli_complete_help(const char *str, int pos)
560 int arg = get_cmd_arg_num(str, pos);
565 res = wpa_list_cmd_list();
573 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
575 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
580 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
589 static void wpa_cli_show_variables(void)
591 printf("set variables:\n"
592 " EAPOL::heldPeriod (EAPOL state machine held period, "
594 " EAPOL::authPeriod (EAPOL state machine authentication "
595 "period, in seconds)\n"
596 " EAPOL::startPeriod (EAPOL state machine start period, in "
598 " EAPOL::maxStart (EAPOL state machine maximum start "
600 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
602 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
603 " threshold\n\tpercentage)\n"
604 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
605 "security\n\tassociation in seconds)\n");
609 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
615 wpa_cli_show_variables();
619 if (argc != 1 && argc != 2) {
620 printf("Invalid SET command: needs two arguments (variable "
621 "name and value)\n");
626 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
628 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
630 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
631 printf("Too long SET command.\n");
634 return wpa_ctrl_command(ctrl, cmd);
638 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
640 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
644 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
646 return wpa_ctrl_command(ctrl, "LOGOFF");
650 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
652 return wpa_ctrl_command(ctrl, "LOGON");
656 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
659 return wpa_ctrl_command(ctrl, "REASSOCIATE");
663 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
666 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
670 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
672 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
676 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
679 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
683 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
686 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
690 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
693 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
697 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
703 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
705 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
706 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
707 printf("Too long BSS_FLUSH command.\n");
710 return wpa_ctrl_command(ctrl, cmd);
714 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
717 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
721 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
723 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
727 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
729 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
733 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
736 printf("Invalid WPS_PIN command: need one or two arguments:\n"
737 "- BSSID: use 'any' to select any\n"
738 "- PIN: optional, used only with devices that have no "
743 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
747 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
750 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
754 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
757 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
761 #ifdef CONFIG_WPS_NFC
763 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
765 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
769 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
772 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
776 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
779 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
783 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
791 printf("Invalid 'wps_nfc_tag_read' command - one argument "
796 buflen = 18 + os_strlen(argv[0]);
797 buf = os_malloc(buflen);
800 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
802 ret = wpa_ctrl_command(ctrl, buf);
809 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
812 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
816 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
819 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
823 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
831 printf("Invalid 'nfc_rx_handover_req' command - one argument "
836 buflen = 21 + os_strlen(argv[0]);
837 buf = os_malloc(buflen);
840 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
842 ret = wpa_ctrl_command(ctrl, buf);
849 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
857 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
862 buflen = 21 + os_strlen(argv[0]);
863 buf = os_malloc(buflen);
866 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
868 ret = wpa_ctrl_command(ctrl, buf);
875 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
878 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
881 #endif /* CONFIG_WPS_NFC */
884 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
890 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
892 else if (argc == 5 || argc == 6) {
893 char ssid_hex[2 * 32 + 1];
894 char key_hex[2 * 64 + 1];
898 for (i = 0; i < 32; i++) {
899 if (argv[2][i] == '\0')
901 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
906 for (i = 0; i < 64; i++) {
907 if (argv[5][i] == '\0')
909 os_snprintf(&key_hex[i * 2], 3, "%02x",
914 res = os_snprintf(cmd, sizeof(cmd),
915 "WPS_REG %s %s %s %s %s %s",
916 argv[0], argv[1], ssid_hex, argv[3], argv[4],
919 printf("Invalid WPS_REG command: need two arguments:\n"
920 "- BSSID of the target AP\n"
922 printf("Alternatively, six arguments can be used to "
923 "reconfigure the AP:\n"
924 "- BSSID of the target AP\n"
927 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
928 "- new encr (NONE, WEP, TKIP, CCMP)\n"
933 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
934 printf("Too long WPS_REG command.\n");
937 return wpa_ctrl_command(ctrl, cmd);
941 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
944 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
948 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
951 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
955 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
958 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
963 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
967 printf("Invalid WPS_ER_PIN command: need at least two "
969 "- UUID: use 'any' to select any\n"
970 "- PIN: Enrollee PIN\n"
971 "optional: - Enrollee MAC address\n");
975 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
979 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
982 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
986 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
990 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
991 "- UUID: specify which AP to use\n"
996 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1000 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1004 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1006 "- UUID: specify which AP to use\n"
1007 "- Network configuration id\n");
1011 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1015 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1021 if (argc == 5 || argc == 6) {
1022 char ssid_hex[2 * 32 + 1];
1023 char key_hex[2 * 64 + 1];
1027 for (i = 0; i < 32; i++) {
1028 if (argv[2][i] == '\0')
1030 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1035 for (i = 0; i < 64; i++) {
1036 if (argv[5][i] == '\0')
1038 os_snprintf(&key_hex[i * 2], 3, "%02x",
1043 res = os_snprintf(cmd, sizeof(cmd),
1044 "WPS_ER_CONFIG %s %s %s %s %s %s",
1045 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1048 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1052 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1053 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1058 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1059 printf("Too long WPS_ER_CONFIG command.\n");
1062 return wpa_ctrl_command(ctrl, cmd);
1066 #ifdef CONFIG_WPS_NFC
1067 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1071 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1073 "- WPS/NDEF: token format\n"
1074 "- UUID: specify which AP to use\n");
1078 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1080 #endif /* CONFIG_WPS_NFC */
1083 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1085 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1089 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1091 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1095 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1097 char cmd[256], *pos, *end;
1101 printf("Invalid IDENTITY command: needs two arguments "
1102 "(network id and identity)\n");
1106 end = cmd + sizeof(cmd);
1108 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1110 if (ret < 0 || ret >= end - pos) {
1111 printf("Too long IDENTITY command.\n");
1115 for (i = 2; i < argc; i++) {
1116 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1117 if (ret < 0 || ret >= end - pos) {
1118 printf("Too long IDENTITY command.\n");
1124 return wpa_ctrl_command(ctrl, cmd);
1128 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1130 char cmd[256], *pos, *end;
1134 printf("Invalid PASSWORD command: needs two arguments "
1135 "(network id and password)\n");
1139 end = cmd + sizeof(cmd);
1141 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1143 if (ret < 0 || ret >= end - pos) {
1144 printf("Too long PASSWORD command.\n");
1148 for (i = 2; i < argc; i++) {
1149 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1150 if (ret < 0 || ret >= end - pos) {
1151 printf("Too long PASSWORD command.\n");
1157 return wpa_ctrl_command(ctrl, cmd);
1161 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1164 char cmd[256], *pos, *end;
1168 printf("Invalid NEW_PASSWORD command: needs two arguments "
1169 "(network id and password)\n");
1173 end = cmd + sizeof(cmd);
1175 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1177 if (ret < 0 || ret >= end - pos) {
1178 printf("Too long NEW_PASSWORD command.\n");
1182 for (i = 2; i < argc; i++) {
1183 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1184 if (ret < 0 || ret >= end - pos) {
1185 printf("Too long NEW_PASSWORD command.\n");
1191 return wpa_ctrl_command(ctrl, cmd);
1195 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1197 char cmd[256], *pos, *end;
1201 printf("Invalid PIN command: needs two arguments "
1202 "(network id and pin)\n");
1206 end = cmd + sizeof(cmd);
1208 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1210 if (ret < 0 || ret >= end - pos) {
1211 printf("Too long PIN command.\n");
1215 for (i = 2; i < argc; i++) {
1216 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1217 if (ret < 0 || ret >= end - pos) {
1218 printf("Too long PIN command.\n");
1223 return wpa_ctrl_command(ctrl, cmd);
1227 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1229 char cmd[256], *pos, *end;
1233 printf("Invalid OTP command: needs two arguments (network "
1234 "id and password)\n");
1238 end = cmd + sizeof(cmd);
1240 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1242 if (ret < 0 || ret >= end - pos) {
1243 printf("Too long OTP command.\n");
1247 for (i = 2; i < argc; i++) {
1248 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1249 if (ret < 0 || ret >= end - pos) {
1250 printf("Too long OTP command.\n");
1256 return wpa_ctrl_command(ctrl, cmd);
1260 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1263 char cmd[256], *pos, *end;
1267 printf("Invalid PASSPHRASE command: needs two arguments "
1268 "(network id and passphrase)\n");
1272 end = cmd + sizeof(cmd);
1274 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1276 if (ret < 0 || ret >= end - pos) {
1277 printf("Too long PASSPHRASE command.\n");
1281 for (i = 2; i < argc; i++) {
1282 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1283 if (ret < 0 || ret >= end - pos) {
1284 printf("Too long PASSPHRASE command.\n");
1290 return wpa_ctrl_command(ctrl, cmd);
1294 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1297 printf("Invalid BSSID command: needs two arguments (network "
1302 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1306 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1308 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1312 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1314 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1318 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1321 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1325 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1328 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1332 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1335 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1339 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1342 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1346 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1349 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1353 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1356 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1360 static void wpa_cli_show_network_variables(void)
1362 printf("set_network variables:\n"
1363 " ssid (network name, SSID)\n"
1364 " psk (WPA passphrase or pre-shared key)\n"
1365 " key_mgmt (key management protocol)\n"
1366 " identity (EAP identity)\n"
1367 " password (EAP password)\n"
1370 "Note: Values are entered in the same format as the "
1371 "configuration file is using,\n"
1372 "i.e., strings values need to be inside double quotation "
1374 "For example: set_network 1 ssid \"network name\"\n"
1376 "Please see wpa_supplicant.conf documentation for full list "
1377 "of\navailable variables.\n");
1381 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1385 wpa_cli_show_network_variables();
1390 printf("Invalid SET_NETWORK command: needs three arguments\n"
1391 "(network id, variable name, and value)\n");
1395 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1399 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1403 wpa_cli_show_network_variables();
1408 printf("Invalid GET_NETWORK command: needs two arguments\n"
1409 "(network id and variable name)\n");
1413 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1417 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1420 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1424 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426 return wpa_ctrl_command(ctrl, "ADD_CRED");
1430 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1433 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1437 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1440 printf("Invalid SET_CRED command: needs three arguments\n"
1441 "(cred id, variable name, and value)\n");
1445 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1449 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1452 return wpa_ctrl_command(ctrl, "DISCONNECT");
1456 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1459 return wpa_ctrl_command(ctrl, "RECONNECT");
1463 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1466 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1470 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1472 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1476 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1479 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1483 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1485 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1489 static char ** wpa_cli_complete_bss(const char *str, int pos)
1491 int arg = get_cmd_arg_num(str, pos);
1496 res = cli_txt_list_array(&bsses);
1504 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1507 if (argc < 1 || argc > 2) {
1508 printf("Invalid GET_CAPABILITY command: need either one or "
1513 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1514 printf("Invalid GET_CAPABILITY command: second argument, "
1515 "if any, must be 'strict'\n");
1519 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1523 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1525 printf("Available interfaces:\n");
1526 return wpa_ctrl_command(ctrl, "INTERFACES");
1530 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1533 wpa_cli_list_interfaces(ctrl);
1537 wpa_cli_close_connection();
1538 os_free(ctrl_ifname);
1539 ctrl_ifname = os_strdup(argv[0]);
1541 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1542 printf("Connected to interface '%s.\n", ctrl_ifname);
1544 printf("Could not connect to interface '%s' - re-trying\n",
1551 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1554 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1558 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1561 return wpa_ctrl_command(ctrl, "TERMINATE");
1565 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1572 printf("Invalid INTERFACE_ADD command: needs at least one "
1573 "argument (interface name)\n"
1574 "All arguments: ifname confname driver ctrl_interface "
1575 "driver_param bridge_name\n");
1580 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1581 * <driver_param>TAB<bridge_name>
1583 res = os_snprintf(cmd, sizeof(cmd),
1584 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1586 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1587 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1588 argc > 5 ? argv[5] : "");
1589 if (res < 0 || (size_t) res >= sizeof(cmd))
1591 cmd[sizeof(cmd) - 1] = '\0';
1592 return wpa_ctrl_command(ctrl, cmd);
1596 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1599 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1603 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1606 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1611 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1613 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1617 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1618 char *addr, size_t addr_len)
1620 char buf[4096], *pos;
1624 if (ctrl_conn == NULL) {
1625 printf("Not connected to hostapd - command dropped.\n");
1628 len = sizeof(buf) - 1;
1629 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1632 printf("'%s' command timed out.\n", cmd);
1634 } else if (ret < 0) {
1635 printf("'%s' command failed.\n", cmd);
1640 if (os_memcmp(buf, "FAIL", 4) == 0)
1645 while (*pos != '\0' && *pos != '\n')
1648 os_strlcpy(addr, buf, addr_len);
1653 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1655 char addr[32], cmd[64];
1657 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1660 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1661 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1667 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1670 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1674 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1677 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1679 #endif /* CONFIG_AP */
1682 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1684 return wpa_ctrl_command(ctrl, "SUSPEND");
1688 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1690 return wpa_ctrl_command(ctrl, "RESUME");
1694 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1696 return wpa_ctrl_command(ctrl, "DROP_SA");
1700 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1702 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1708 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1710 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1714 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1717 int arg = get_cmd_arg_num(str, pos);
1719 res = os_calloc(6, sizeof(char *));
1722 res[0] = os_strdup("type=social");
1723 if (res[0] == NULL) {
1727 res[1] = os_strdup("type=progressive");
1730 res[2] = os_strdup("delay=");
1733 res[3] = os_strdup("dev_id=");
1737 res[4] = os_strdup("[timeout]");
1743 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1746 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1750 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1753 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1757 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1759 int arg = get_cmd_arg_num(str, pos);
1764 res = cli_txt_list_array(&p2p_peers);
1772 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1775 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1779 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1782 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1786 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1788 int arg = get_cmd_arg_num(str, pos);
1793 res = cli_txt_list_array(&p2p_groups);
1801 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1804 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1808 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1811 if (argc != 2 && argc != 3) {
1812 printf("Invalid P2P_PROV_DISC command: needs at least "
1813 "two arguments, address and config method\n"
1814 "(display, keypad, or pbc) and an optional join\n");
1818 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1822 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1825 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1829 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1834 if (argc != 2 && argc != 4) {
1835 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1836 "arguments (address and TLVs) or four arguments "
1837 "(address, \"upnp\", version, search target "
1842 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1844 return wpa_ctrl_command(ctrl, cmd);
1848 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1849 int argc, char *argv[])
1851 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1855 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1862 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1863 "arguments (freq, address, dialog token, and TLVs)\n");
1867 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1868 argv[0], argv[1], argv[2], argv[3]);
1869 if (res < 0 || (size_t) res >= sizeof(cmd))
1871 cmd[sizeof(cmd) - 1] = '\0';
1872 return wpa_ctrl_command(ctrl, cmd);
1876 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1879 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1883 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1884 int argc, char *argv[])
1886 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1890 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1893 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1897 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1903 if (argc != 3 && argc != 4) {
1904 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1910 res = os_snprintf(cmd, sizeof(cmd),
1911 "P2P_SERVICE_ADD %s %s %s %s",
1912 argv[0], argv[1], argv[2], argv[3]);
1914 res = os_snprintf(cmd, sizeof(cmd),
1915 "P2P_SERVICE_ADD %s %s %s",
1916 argv[0], argv[1], argv[2]);
1917 if (res < 0 || (size_t) res >= sizeof(cmd))
1919 cmd[sizeof(cmd) - 1] = '\0';
1920 return wpa_ctrl_command(ctrl, cmd);
1924 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1930 if (argc != 2 && argc != 3) {
1931 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1937 res = os_snprintf(cmd, sizeof(cmd),
1938 "P2P_SERVICE_DEL %s %s %s",
1939 argv[0], argv[1], argv[2]);
1941 res = os_snprintf(cmd, sizeof(cmd),
1942 "P2P_SERVICE_DEL %s %s",
1944 if (res < 0 || (size_t) res >= sizeof(cmd))
1946 cmd[sizeof(cmd) - 1] = '\0';
1947 return wpa_ctrl_command(ctrl, cmd);
1951 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1952 int argc, char *argv[])
1954 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
1958 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1959 int argc, char *argv[])
1961 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
1965 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1967 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
1971 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
1973 int arg = get_cmd_arg_num(str, pos);
1978 res = cli_txt_list_array(&p2p_peers);
1986 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1987 char *addr, size_t addr_len,
1990 char buf[4096], *pos;
1994 if (ctrl_conn == NULL)
1996 len = sizeof(buf) - 1;
1997 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2000 printf("'%s' command timed out.\n", cmd);
2002 } else if (ret < 0) {
2003 printf("'%s' command failed.\n", cmd);
2008 if (os_memcmp(buf, "FAIL", 4) == 0)
2012 while (*pos != '\0' && *pos != '\n')
2015 os_strlcpy(addr, buf, addr_len);
2016 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2017 printf("%s\n", addr);
2022 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2024 char addr[32], cmd[64];
2027 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2029 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2030 addr, sizeof(addr), discovered))
2033 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2034 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2041 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2043 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2047 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2049 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2053 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2056 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2060 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2063 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2067 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2070 if (argc != 0 && argc != 2 && argc != 4) {
2071 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2072 "(preferred duration, interval; in microsecods).\n"
2073 "Optional second pair can be used to provide "
2074 "acceptable values.\n");
2078 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2082 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2085 if (argc != 0 && argc != 2) {
2086 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2087 "(availability period, availability interval; in "
2089 "Extended Listen Timing can be cancelled with this "
2090 "command when used without parameters.\n");
2094 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2097 #endif /* CONFIG_P2P */
2099 #ifdef CONFIG_WIFI_DISPLAY
2101 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2107 if (argc != 1 && argc != 2) {
2108 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2109 "arguments (subelem, hexdump)\n");
2113 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2114 argv[0], argc > 1 ? argv[1] : "");
2115 if (res < 0 || (size_t) res >= sizeof(cmd))
2117 cmd[sizeof(cmd) - 1] = '\0';
2118 return wpa_ctrl_command(ctrl, cmd);
2122 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2129 printf("Invalid WFD_SUBELEM_GET command: needs one "
2130 "argument (subelem)\n");
2134 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2136 if (res < 0 || (size_t) res >= sizeof(cmd))
2138 cmd[sizeof(cmd) - 1] = '\0';
2139 return wpa_ctrl_command(ctrl, cmd);
2141 #endif /* CONFIG_WIFI_DISPLAY */
2144 #ifdef CONFIG_INTERWORKING
2145 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2148 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2152 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2155 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2159 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2162 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2166 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2169 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2173 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2175 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2179 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2182 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2186 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2189 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2191 #endif /* CONFIG_INTERWORKING */
2196 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2199 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2203 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2209 printf("Command needs one or two arguments (dst mac addr and "
2210 "optional home realm)\n");
2214 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2218 return wpa_ctrl_command(ctrl, cmd);
2221 #endif /* CONFIG_HS20 */
2224 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2227 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2231 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2234 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2238 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2241 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2245 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2248 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2252 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2255 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2259 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2262 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2266 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2269 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2273 #ifdef CONFIG_AUTOSCAN
2275 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2278 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2280 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2283 #endif /* CONFIG_AUTOSCAN */
2288 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2290 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2293 #endif /* CONFIG_WNM */
2296 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2300 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2305 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2312 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2316 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2317 for (i=1; i < argc; i++)
2318 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2319 cmd[sizeof(cmd) - 1] = '\0';
2320 printf("%s: %s\n", __func__, cmd);
2321 return wpa_ctrl_command(ctrl, cmd);
2326 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2328 return wpa_ctrl_command(ctrl, "FLUSH");
2332 enum wpa_cli_cmd_flags {
2333 cli_cmd_flag_none = 0x00,
2334 cli_cmd_flag_sensitive = 0x01
2337 struct wpa_cli_cmd {
2339 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2340 char ** (*completion)(const char *str, int pos);
2341 enum wpa_cli_cmd_flags flags;
2345 static struct wpa_cli_cmd wpa_cli_commands[] = {
2346 { "status", wpa_cli_cmd_status, NULL,
2348 "[verbose] = get current WPA/EAPOL/EAP status" },
2349 { "ifname", wpa_cli_cmd_ifname, NULL,
2351 "= get current interface name" },
2352 { "ping", wpa_cli_cmd_ping, NULL,
2354 "= pings wpa_supplicant" },
2355 { "relog", wpa_cli_cmd_relog, NULL,
2357 "= re-open log-file (allow rolling logs)" },
2358 { "note", wpa_cli_cmd_note, NULL,
2360 "<text> = add a note to wpa_supplicant debug log" },
2361 { "mib", wpa_cli_cmd_mib, NULL,
2363 "= get MIB variables (dot1x, dot11)" },
2364 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2366 "[command] = show usage help" },
2367 { "interface", wpa_cli_cmd_interface, NULL,
2369 "[ifname] = show interfaces/select interface" },
2370 { "level", wpa_cli_cmd_level, NULL,
2372 "<debug level> = change debug level" },
2373 { "license", wpa_cli_cmd_license, NULL,
2375 "= show full wpa_cli license" },
2376 { "quit", wpa_cli_cmd_quit, NULL,
2379 { "set", wpa_cli_cmd_set, NULL,
2381 "= set variables (shows list of variables when run without "
2383 { "get", wpa_cli_cmd_get, NULL,
2385 "<name> = get information" },
2386 { "logon", wpa_cli_cmd_logon, NULL,
2388 "= IEEE 802.1X EAPOL state machine logon" },
2389 { "logoff", wpa_cli_cmd_logoff, NULL,
2391 "= IEEE 802.1X EAPOL state machine logoff" },
2392 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2394 "= show PMKSA cache" },
2395 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2397 "= force reassociation" },
2398 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2400 "<BSSID> = force preauthentication" },
2401 { "identity", wpa_cli_cmd_identity, NULL,
2403 "<network id> <identity> = configure identity for an SSID" },
2404 { "password", wpa_cli_cmd_password, NULL,
2405 cli_cmd_flag_sensitive,
2406 "<network id> <password> = configure password for an SSID" },
2407 { "new_password", wpa_cli_cmd_new_password, NULL,
2408 cli_cmd_flag_sensitive,
2409 "<network id> <password> = change password for an SSID" },
2410 { "pin", wpa_cli_cmd_pin, NULL,
2411 cli_cmd_flag_sensitive,
2412 "<network id> <pin> = configure pin for an SSID" },
2413 { "otp", wpa_cli_cmd_otp, NULL,
2414 cli_cmd_flag_sensitive,
2415 "<network id> <password> = configure one-time-password for an SSID"
2417 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2418 cli_cmd_flag_sensitive,
2419 "<network id> <passphrase> = configure private key passphrase\n"
2421 { "bssid", wpa_cli_cmd_bssid, NULL,
2423 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2424 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2426 "<BSSID> = add a BSSID to the blacklist\n"
2427 "blacklist clear = clear the blacklist\n"
2428 "blacklist = display the blacklist" },
2429 { "log_level", wpa_cli_cmd_log_level, NULL,
2431 "<level> [<timestamp>] = update the log level/timestamp\n"
2432 "log_level = display the current log level and log options" },
2433 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2435 "= list configured networks" },
2436 { "select_network", wpa_cli_cmd_select_network, NULL,
2438 "<network id> = select a network (disable others)" },
2439 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2441 "<network id> = enable a network" },
2442 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2444 "<network id> = disable a network" },
2445 { "add_network", wpa_cli_cmd_add_network, NULL,
2447 "= add a network" },
2448 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2450 "<network id> = remove a network" },
2451 { "set_network", wpa_cli_cmd_set_network, NULL,
2452 cli_cmd_flag_sensitive,
2453 "<network id> <variable> <value> = set network variables (shows\n"
2454 " list of variables when run without arguments)" },
2455 { "get_network", wpa_cli_cmd_get_network, NULL,
2457 "<network id> <variable> = get network variables" },
2458 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2460 "= list configured credentials" },
2461 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2463 "= add a credential" },
2464 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2466 "<cred id> = remove a credential" },
2467 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2468 cli_cmd_flag_sensitive,
2469 "<cred id> <variable> <value> = set credential variables" },
2470 { "save_config", wpa_cli_cmd_save_config, NULL,
2472 "= save the current configuration" },
2473 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2475 "= disconnect and wait for reassociate/reconnect command before\n"
2477 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2479 "= like reassociate, but only takes effect if already disconnected"
2481 { "scan", wpa_cli_cmd_scan, NULL,
2483 "= request new BSS scan" },
2484 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2486 "= get latest scan results" },
2487 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2489 "<<idx> | <bssid>> = get detailed scan result info" },
2490 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2492 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/modes> "
2493 "= get capabilies" },
2494 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2496 "= force wpa_supplicant to re-read its configuration file" },
2497 { "terminate", wpa_cli_cmd_terminate, NULL,
2499 "= terminate wpa_supplicant" },
2500 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2502 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2503 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2505 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2507 "<ifname> = removes the interface" },
2508 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2510 "= list available interfaces" },
2511 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2513 "<value> = set ap_scan parameter" },
2514 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2516 "<value> = set scan_interval parameter (in seconds)" },
2517 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2519 "<value> = set BSS expiration age parameter" },
2520 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2522 "<value> = set BSS expiration scan count parameter" },
2523 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2525 "<value> = set BSS flush age (0 by default)" },
2526 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2528 "<addr> = request STK negotiation with <addr>" },
2529 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2531 "<addr> = request over-the-DS FT with <addr>" },
2532 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2534 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2535 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2536 cli_cmd_flag_sensitive,
2537 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2539 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2540 cli_cmd_flag_sensitive,
2541 "<PIN> = verify PIN checksum" },
2542 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2543 "Cancels the pending WPS operation" },
2544 #ifdef CONFIG_WPS_NFC
2545 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2547 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2548 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2550 "<WPS|NDEF> = build configuration token" },
2551 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2553 "<WPS|NDEF> = create password token" },
2554 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2555 cli_cmd_flag_sensitive,
2556 "<hexdump of payload> = report read NFC tag with WPS data" },
2557 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2559 "<NDEF> <WPS> = create NFC handover request" },
2560 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2562 "<NDEF> <WPS> = create NFC handover select" },
2563 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2565 "<hexdump of payload> = report received NFC handover request" },
2566 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2568 "<hexdump of payload> = report received NFC handover select" },
2569 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2571 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2573 #endif /* CONFIG_WPS_NFC */
2574 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2575 cli_cmd_flag_sensitive,
2576 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2577 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2578 cli_cmd_flag_sensitive,
2579 "[params..] = enable/disable AP PIN" },
2580 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2582 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2583 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2585 "= stop Wi-Fi Protected Setup External Registrar" },
2586 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2587 cli_cmd_flag_sensitive,
2588 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2589 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2591 "<UUID> = accept an Enrollee PBC using External Registrar" },
2592 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2593 cli_cmd_flag_sensitive,
2594 "<UUID> <PIN> = learn AP configuration" },
2595 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2597 "<UUID> <network id> = set AP configuration for enrolling" },
2598 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2599 cli_cmd_flag_sensitive,
2600 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2601 #ifdef CONFIG_WPS_NFC
2602 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2604 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2605 #endif /* CONFIG_WPS_NFC */
2606 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2608 "<addr> = request RSN authentication with <addr> in IBSS" },
2610 { "sta", wpa_cli_cmd_sta, NULL,
2612 "<addr> = get information about an associated station (AP)" },
2613 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2615 "= get information about all associated stations (AP)" },
2616 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2618 "<addr> = deauthenticate a station" },
2619 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2621 "<addr> = disassociate a station" },
2622 #endif /* CONFIG_AP */
2623 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2624 "= notification of suspend/hibernate" },
2625 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2626 "= notification of resume/thaw" },
2627 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2628 "= drop SA without deauth/disassoc (test command)" },
2629 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2631 "<addr> = roam to the specified BSS" },
2633 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2635 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2636 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2637 "= stop P2P Devices search" },
2638 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2640 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2641 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2642 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2643 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2644 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2645 "<ifname> = remove P2P group interface (terminate group if GO)" },
2646 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2647 "[ht40] = add a new P2P group (local end as GO)" },
2648 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2649 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2650 "<addr> <method> = request provisioning discovery" },
2651 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2653 "= get the passphrase for a group (GO only)" },
2654 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2655 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2656 "<addr> <TLVs> = schedule service discovery request" },
2657 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2658 NULL, cli_cmd_flag_none,
2659 "<id> = cancel pending service discovery request" },
2660 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2662 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2663 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2665 "= indicate change in local services" },
2666 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2668 "<external> = set external processing of service discovery" },
2669 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2671 "= remove all stored service entries" },
2672 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2674 "<bonjour|upnp> <query|version> <response|service> = add a local "
2676 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2678 "<bonjour|upnp> <query|version> [|service] = remove a local "
2680 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2682 "<addr> = reject connection attempts from a specific peer" },
2683 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2685 "<cmd> [peer=addr] = invite peer" },
2686 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2687 "[discovered] = list known (optionally, only fully discovered) P2P "
2689 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2691 "<address> = show information about known P2P peer" },
2692 { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none,
2693 "<field> <value> = set a P2P parameter" },
2694 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2695 "= flush P2P state" },
2696 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2697 "= cancel P2P group formation" },
2698 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2699 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2700 "<address> = unauthorize a peer" },
2701 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2703 "[<duration> <interval>] [<duration> <interval>] = request GO "
2705 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2707 "[<period> <interval>] = set extended listen timing" },
2708 #endif /* CONFIG_P2P */
2709 #ifdef CONFIG_WIFI_DISPLAY
2710 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2712 "<subelem> [contents] = set Wi-Fi Display subelement" },
2713 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2715 "<subelem> = get Wi-Fi Display subelement" },
2716 #endif /* CONFIG_WIFI_DISPLAY */
2717 #ifdef CONFIG_INTERWORKING
2718 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2719 "= fetch ANQP information for all APs" },
2720 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2722 "= stop fetch_anqp operation" },
2723 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2725 "[auto] = perform Interworking network selection" },
2726 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2727 wpa_cli_complete_bss, cli_cmd_flag_none,
2728 "<BSSID> = connect using Interworking credentials" },
2729 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2731 "<addr> <info id>[,<info id>]... = request ANQP information" },
2732 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2734 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2735 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2736 wpa_cli_complete_bss, cli_cmd_flag_none,
2737 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2738 #endif /* CONFIG_INTERWORKING */
2740 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2742 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2744 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2745 wpa_cli_complete_bss, cli_cmd_flag_none,
2746 "<addr> <home realm> = get HS20 nai home realm list" },
2747 #endif /* CONFIG_HS20 */
2748 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2750 "<0/1> = disable/enable automatic reconnection" },
2751 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2753 "<addr> = request TDLS discovery with <addr>" },
2754 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2756 "<addr> = request TDLS setup with <addr>" },
2757 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2759 "<addr> = tear down TDLS with <addr>" },
2760 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2762 "= get signal parameters" },
2763 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2765 "= get TX/RX packet counters" },
2766 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2768 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2769 #ifdef CONFIG_AUTOSCAN
2770 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2771 "[params] = Set or unset (if none) autoscan parameters" },
2772 #endif /* CONFIG_AUTOSCAN */
2774 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2775 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2776 #endif /* CONFIG_WNM */
2777 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2778 "<params..> = Sent unprocessed command" },
2779 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2780 "= flush wpa_supplicant state" },
2782 { "driver", wpa_cli_cmd_driver, NULL,
2784 "<command> = driver private commands" },
2786 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2791 * Prints command usage, lines are padded with the specified string.
2793 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2798 printf("%s%s ", pad, cmd->cmd);
2799 for (n = 0; (c = cmd->usage[n]); n++) {
2808 static void print_help(const char *cmd)
2811 printf("commands:\n");
2812 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2813 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2814 print_cmd_help(&wpa_cli_commands[n], " ");
2819 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2821 const char *c, *delim;
2825 delim = os_strchr(cmd, ' ');
2829 len = os_strlen(cmd);
2831 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2832 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2833 return (wpa_cli_commands[n].flags &
2834 cli_cmd_flag_sensitive);
2840 static char ** wpa_list_cmd_list(void)
2845 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2846 res = os_calloc(count, sizeof(char *));
2850 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2851 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2860 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2865 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2866 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2867 if (wpa_cli_commands[i].completion)
2868 return wpa_cli_commands[i].completion(str,
2871 printf("\r%s\n", wpa_cli_commands[i].usage);
2881 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2887 end = os_strchr(str, ' ');
2888 if (end == NULL || str + pos < end)
2889 return wpa_list_cmd_list();
2891 cmd = os_malloc(pos + 1);
2894 os_memcpy(cmd, str, pos);
2895 cmd[end - str] = '\0';
2896 res = wpa_cli_cmd_completion(cmd, str, pos);
2902 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2904 struct wpa_cli_cmd *cmd, *match = NULL;
2909 cmd = wpa_cli_commands;
2911 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2914 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2915 /* we have an exact match */
2925 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2926 cmd = wpa_cli_commands;
2928 if (os_strncasecmp(cmd->cmd, argv[0],
2929 os_strlen(argv[0])) == 0) {
2930 printf(" %s", cmd->cmd);
2936 } else if (count == 0) {
2937 printf("Unknown command '%s'\n", argv[0]);
2940 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
2941 if ( (argc >= 2) && (os_strncmp(argv[1], "interface=", 10) == 0)) {
2942 redirect_interface = os_strdup(argv[1]);
2943 ret = match->handler(ctrl, argc - 2, &argv[2]);
2947 ret = match->handler(ctrl, argc - 1, &argv[1]);
2954 static int str_match(const char *a, const char *b)
2956 return os_strncmp(a, b, os_strlen(b)) == 0;
2960 static int wpa_cli_exec(const char *program, const char *arg1,
2968 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2969 cmd = os_malloc(len);
2972 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2973 if (res < 0 || (size_t) res >= len) {
2977 cmd[len - 1] = '\0';
2979 if (system(cmd) < 0)
2981 #endif /* _WIN32_WCE */
2988 static void wpa_cli_action_process(const char *msg)
2991 char *copy = NULL, *id, *pos2;
2996 pos = os_strchr(pos, '>');
3003 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3005 os_unsetenv("WPA_ID");
3006 os_unsetenv("WPA_ID_STR");
3007 os_unsetenv("WPA_CTRL_DIR");
3009 pos = os_strstr(pos, "[id=");
3011 copy = os_strdup(pos + 4);
3015 while (*pos2 && *pos2 != ' ')
3019 os_setenv("WPA_ID", id, 1);
3020 while (*pos2 && *pos2 != '=')
3025 while (*pos2 && *pos2 != ']')
3028 os_setenv("WPA_ID_STR", id, 1);
3032 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3034 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3035 wpa_cli_connected = 1;
3036 wpa_cli_last_id = new_id;
3037 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3039 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3040 if (wpa_cli_connected) {
3041 wpa_cli_connected = 0;
3042 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3044 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3045 wpa_cli_exec(action_file, ctrl_ifname, pos);
3046 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3047 wpa_cli_exec(action_file, ctrl_ifname, pos);
3048 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3049 wpa_cli_exec(action_file, ctrl_ifname, pos);
3050 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3051 wpa_cli_exec(action_file, ctrl_ifname, pos);
3052 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3053 wpa_cli_exec(action_file, ctrl_ifname, pos);
3054 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3055 wpa_cli_exec(action_file, ctrl_ifname, pos);
3056 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3057 wpa_cli_exec(action_file, ctrl_ifname, pos);
3058 } else if (str_match(pos, AP_STA_CONNECTED)) {
3059 wpa_cli_exec(action_file, ctrl_ifname, pos);
3060 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3061 wpa_cli_exec(action_file, ctrl_ifname, pos);
3062 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3063 printf("wpa_supplicant is terminating - stop monitoring\n");
3069 #ifndef CONFIG_ANSI_C_EXTRA
3070 static void wpa_cli_action_cb(char *msg, size_t len)
3072 wpa_cli_action_process(msg);
3074 #endif /* CONFIG_ANSI_C_EXTRA */
3077 static void wpa_cli_reconnect(void)
3079 wpa_cli_close_connection();
3080 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3085 printf("\rConnection to wpa_supplicant re-established\n");
3091 static void cli_event(const char *str)
3093 const char *start, *s;
3095 start = os_strchr(str, '>');
3101 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3102 s = os_strchr(start, ' ');
3105 s = os_strchr(s + 1, ' ');
3108 cli_txt_list_add(&bsses, s + 1);
3112 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3113 s = os_strchr(start, ' ');
3116 s = os_strchr(s + 1, ' ');
3119 cli_txt_list_del_addr(&bsses, s + 1);
3124 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3125 s = os_strstr(start, " p2p_dev_addr=");
3128 cli_txt_list_add_addr(&p2p_peers, s + 14);
3132 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3133 s = os_strstr(start, " p2p_dev_addr=");
3136 cli_txt_list_del_addr(&p2p_peers, s + 14);
3140 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3141 s = os_strchr(start, ' ');
3144 cli_txt_list_add_word(&p2p_groups, s + 1);
3148 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3149 s = os_strchr(start, ' ');
3152 cli_txt_list_del_word(&p2p_groups, s + 1);
3155 #endif /* CONFIG_P2P */
3159 static int check_terminating(const char *msg)
3161 const char *pos = msg;
3165 pos = os_strchr(pos, '>');
3172 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3174 printf("\rConnection to wpa_supplicant lost - trying to "
3177 wpa_cli_attached = 0;
3178 wpa_cli_close_connection();
3186 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3188 if (ctrl_conn == NULL) {
3189 wpa_cli_reconnect();
3192 while (wpa_ctrl_pending(ctrl) > 0) {
3194 size_t len = sizeof(buf) - 1;
3195 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3198 wpa_cli_action_process(buf);
3201 if (wpa_cli_show_event(buf)) {
3203 printf("\r%s\n", buf);
3207 if (interactive && check_terminating(buf) > 0)
3211 printf("Could not read pending message.\n");
3216 if (wpa_ctrl_pending(ctrl) < 0) {
3217 printf("Connection to wpa_supplicant lost - trying to "
3219 wpa_cli_reconnect();
3225 static int tokenize_cmd(char *cmd, char *argv[])
3238 if (argc == max_args)
3241 char *pos2 = os_strrchr(pos, '"');
3245 while (*pos != '\0' && *pos != ' ')
3255 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3257 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3258 printf("Connection to wpa_supplicant lost - trying to "
3260 wpa_cli_close_connection();
3263 wpa_cli_reconnect();
3264 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3268 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3270 wpa_cli_recv_pending(mon_conn, 0);
3274 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3276 char *argv[max_args];
3278 argc = tokenize_cmd(cmd, argv);
3280 wpa_request(ctrl_conn, argc, argv);
3284 static void wpa_cli_edit_eof_cb(void *ctx)
3290 static int warning_displayed = 0;
3291 static char *hfile = NULL;
3292 static int edit_started = 0;
3294 static void start_edit(void)
3299 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3300 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3301 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3303 home = getenv("HOME");
3305 const char *fname = ".wpa_cli_history";
3306 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3307 hfile = os_malloc(hfile_len);
3309 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3312 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3313 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3319 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3323 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3325 if (ctrl_ifname == NULL)
3326 ctrl_ifname = wpa_cli_get_default_ifname();
3328 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3329 if (!warning_displayed) {
3330 printf("Could not connect to wpa_supplicant: "
3331 "%s - re-trying\n", ctrl_ifname);
3332 warning_displayed = 1;
3334 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3338 if (warning_displayed)
3339 printf("Connection established.\n");
3345 static void wpa_cli_interactive(void)
3347 printf("\nInteractive mode\n\n");
3349 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3351 eloop_cancel_timeout(try_connection, NULL, NULL);
3353 cli_txt_list_flush(&p2p_peers);
3354 cli_txt_list_flush(&p2p_groups);
3355 cli_txt_list_flush(&bsses);
3357 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3359 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3360 wpa_cli_close_connection();
3364 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3366 #ifdef CONFIG_ANSI_C_EXTRA
3367 /* TODO: ANSI C version(?) */
3368 printf("Action processing not supported in ANSI C build.\n");
3369 #else /* CONFIG_ANSI_C_EXTRA */
3373 char buf[256]; /* note: large enough to fit in unsolicited messages */
3376 fd = wpa_ctrl_get_fd(ctrl);
3378 while (!wpa_cli_quit) {
3381 tv.tv_sec = ping_interval;
3383 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3384 if (res < 0 && errno != EINTR) {
3389 if (FD_ISSET(fd, &rfds))
3390 wpa_cli_recv_pending(ctrl, 1);
3392 /* verify that connection is still working */
3393 len = sizeof(buf) - 1;
3394 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3395 wpa_cli_action_cb) < 0 ||
3396 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3397 printf("wpa_supplicant did not reply to PING "
3398 "command - exiting\n");
3403 #endif /* CONFIG_ANSI_C_EXTRA */
3407 static void wpa_cli_cleanup(void)
3409 wpa_cli_close_connection();
3411 os_daemonize_terminate(pid_file);
3413 os_program_deinit();
3417 static void wpa_cli_terminate(int sig, void *ctx)
3423 static char * wpa_cli_get_default_ifname(void)
3425 char *ifname = NULL;
3427 #ifdef CONFIG_CTRL_IFACE_UNIX
3428 struct dirent *dent;
3429 DIR *dir = opendir(ctrl_iface_dir);
3432 char ifprop[PROPERTY_VALUE_MAX];
3433 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3434 ifname = os_strdup(ifprop);
3435 printf("Using interface '%s'\n", ifname);
3438 #endif /* ANDROID */
3441 while ((dent = readdir(dir))) {
3442 #ifdef _DIRENT_HAVE_D_TYPE
3444 * Skip the file if it is not a socket. Also accept
3445 * DT_UNKNOWN (0) in case the C library or underlying
3446 * file system does not support d_type.
3448 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3450 #endif /* _DIRENT_HAVE_D_TYPE */
3451 if (os_strcmp(dent->d_name, ".") == 0 ||
3452 os_strcmp(dent->d_name, "..") == 0)
3454 printf("Selected interface '%s'\n", dent->d_name);
3455 ifname = os_strdup(dent->d_name);
3459 #endif /* CONFIG_CTRL_IFACE_UNIX */
3461 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3462 char buf[2048], *pos;
3464 struct wpa_ctrl *ctrl;
3467 ctrl = wpa_ctrl_open(NULL);
3471 len = sizeof(buf) - 1;
3472 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3475 pos = os_strchr(buf, '\n');
3478 ifname = os_strdup(buf);
3480 wpa_ctrl_close(ctrl);
3481 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3487 int main(int argc, char *argv[])
3492 const char *global = NULL;
3494 if (os_program_init())
3498 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3503 action_file = optarg;
3512 ping_interval = atoi(optarg);
3518 printf("%s\n", wpa_cli_version);
3521 os_free(ctrl_ifname);
3522 ctrl_ifname = os_strdup(optarg);
3525 ctrl_iface_dir = optarg;
3536 interactive = (argc == optind) && (action_file == NULL);
3539 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3545 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3546 ctrl_conn = wpa_ctrl_open(NULL);
3547 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3548 ctrl_conn = wpa_ctrl_open(global);
3549 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3550 if (ctrl_conn == NULL) {
3551 fprintf(stderr, "Failed to connect to wpa_supplicant "
3552 "global interface: %s error: %s\n",
3553 global, strerror(errno));
3558 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3560 if (ctrl_ifname == NULL)
3561 ctrl_ifname = wpa_cli_get_default_ifname();
3564 wpa_cli_interactive();
3567 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3568 fprintf(stderr, "Failed to connect to non-global "
3569 "ctrl_ifname: %s error: %s\n",
3570 ctrl_ifname, strerror(errno));
3575 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3576 wpa_cli_attached = 1;
3578 printf("Warning: Failed to attach to "
3579 "wpa_supplicant.\n");
3584 if (daemonize && os_daemonize(pid_file))
3588 wpa_cli_action(ctrl_conn);
3590 ret = wpa_request(ctrl_conn, argc - optind,
3594 os_free(ctrl_ifname);
3601 #else /* CONFIG_CTRL_IFACE */
3602 int main(int argc, char *argv[])
3604 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3607 #endif /* CONFIG_CTRL_IFACE */