2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2013, 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-2014, 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 = -1;
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 static char *ifname_prefix = NULL;
86 struct cli_txt_entry {
91 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
93 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
97 static void print_help(const char *cmd);
98 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
99 static void wpa_cli_close_connection(void);
100 static char * wpa_cli_get_default_ifname(void);
101 static char ** wpa_list_cmd_list(void);
104 static void usage(void)
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
115 " -B = run a daemon in the background\n"
116 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
117 " default interface: first interface found in socket path\n");
122 static void cli_txt_list_free(struct cli_txt_entry *e)
124 dl_list_del(&e->list);
130 static void cli_txt_list_flush(struct dl_list *list)
132 struct cli_txt_entry *e;
133 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
134 cli_txt_list_free(e);
138 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
141 struct cli_txt_entry *e;
142 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
143 if (os_strcmp(e->txt, txt) == 0)
150 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
152 struct cli_txt_entry *e;
153 e = cli_txt_list_get(txt_list, txt);
155 cli_txt_list_free(e);
159 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
163 if (hwaddr_aton(txt, addr) < 0)
165 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
166 cli_txt_list_del(txt_list, buf);
171 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
175 end = os_strchr(txt, ' ');
177 end = txt + os_strlen(txt);
178 buf = dup_binstr(txt, end - txt);
181 cli_txt_list_del(txt_list, buf);
184 #endif /* CONFIG_P2P */
187 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
189 struct cli_txt_entry *e;
190 e = cli_txt_list_get(txt_list, txt);
193 e = os_zalloc(sizeof(*e));
196 e->txt = os_strdup(txt);
197 if (e->txt == NULL) {
201 dl_list_add(txt_list, &e->list);
207 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
211 if (hwaddr_aton(txt, addr) < 0)
213 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
214 return cli_txt_list_add(txt_list, buf);
218 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
223 end = os_strchr(txt, ' ');
225 end = txt + os_strlen(txt);
226 buf = dup_binstr(txt, end - txt);
229 ret = cli_txt_list_add(txt_list, buf);
233 #endif /* CONFIG_P2P */
236 static char ** cli_txt_list_array(struct dl_list *txt_list)
238 unsigned int i, count = dl_list_len(txt_list);
240 struct cli_txt_entry *e;
242 res = os_calloc(count + 1, sizeof(char *));
247 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
248 res[i] = os_strdup(e->txt);
258 static int get_cmd_arg_num(const char *str, int pos)
262 for (i = 0; i <= pos; i++) {
265 while (i <= pos && str[i] != ' ')
276 static int str_starts(const char *src, const char *match)
278 return os_strncmp(src, match, os_strlen(match)) == 0;
282 static int wpa_cli_show_event(const char *event)
286 start = os_strchr(event, '>');
292 * Skip BSS added/removed events since they can be relatively frequent
293 * and are likely of not much use for an interactive user.
295 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
296 str_starts(start, WPA_EVENT_BSS_REMOVED))
303 static int wpa_cli_open_connection(const char *ifname, int attach)
305 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
306 ctrl_conn = wpa_ctrl_open(ifname);
307 if (ctrl_conn == NULL)
310 if (attach && interactive)
311 mon_conn = wpa_ctrl_open(ifname);
314 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
322 if (access(ctrl_iface_dir, F_OK) < 0) {
323 cfile = os_strdup(ifname);
330 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
331 cfile = os_malloc(flen);
334 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
336 if (res < 0 || res >= flen) {
342 ctrl_conn = wpa_ctrl_open(cfile);
343 if (ctrl_conn == NULL) {
348 if (attach && interactive)
349 mon_conn = wpa_ctrl_open(cfile);
353 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
356 if (wpa_ctrl_attach(mon_conn) == 0) {
357 wpa_cli_attached = 1;
359 eloop_register_read_sock(
360 wpa_ctrl_get_fd(mon_conn),
361 wpa_cli_mon_receive, NULL, NULL);
363 printf("Warning: Failed to attach to "
364 "wpa_supplicant.\n");
365 wpa_cli_close_connection();
374 static void wpa_cli_close_connection(void)
376 if (ctrl_conn == NULL)
379 if (wpa_cli_attached) {
380 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
381 wpa_cli_attached = 0;
383 wpa_ctrl_close(ctrl_conn);
386 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
387 wpa_ctrl_close(mon_conn);
393 static void wpa_cli_msg_cb(char *msg, size_t len)
399 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
405 if (ctrl_conn == NULL) {
406 printf("Not connected to wpa_supplicant - command dropped.\n");
410 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
412 buf[sizeof(buf) - 1] = '\0';
415 len = sizeof(buf) - 1;
416 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
419 printf("'%s' command timed out.\n", cmd);
421 } else if (ret < 0) {
422 printf("'%s' command failed.\n", cmd);
428 if (interactive && len > 0 && buf[len - 1] != '\n')
435 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
437 return _wpa_ctrl_command(ctrl, cmd, 1);
441 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
450 res = os_snprintf(pos, end - pos, "%s", cmd);
451 if (res < 0 || res >= end - pos)
455 for (i = 0; i < argc; i++) {
456 res = os_snprintf(pos, end - pos, " %s", argv[i]);
457 if (res < 0 || res >= end - pos)
462 buf[buflen - 1] = '\0';
466 printf("Too long command\n");
471 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
472 int argc, char *argv[])
475 if (argc < min_args) {
476 printf("Invalid %s command - at least %d argument%s "
477 "required.\n", cmd, min_args,
478 min_args > 1 ? "s are" : " is");
481 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
483 return wpa_ctrl_command(ctrl, buf);
487 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
489 return wpa_ctrl_command(ctrl, "IFNAME");
493 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
495 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
496 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
497 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
498 return wpa_ctrl_command(ctrl, "STATUS-WPS");
499 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
500 return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
501 return wpa_ctrl_command(ctrl, "STATUS");
505 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
507 return wpa_ctrl_command(ctrl, "PING");
511 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 return wpa_ctrl_command(ctrl, "RELOG");
517 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
519 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
523 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
525 return wpa_ctrl_command(ctrl, "MIB");
529 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
531 return wpa_ctrl_command(ctrl, "PMKSA");
535 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 print_help(argc > 0 ? argv[0] : NULL);
542 static char ** wpa_cli_complete_help(const char *str, int pos)
544 int arg = get_cmd_arg_num(str, pos);
549 res = wpa_list_cmd_list();
557 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
559 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
564 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
573 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
579 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
580 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
581 printf("Too long SET command.\n");
584 return wpa_ctrl_command(ctrl, cmd);
587 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
591 static char ** wpa_cli_complete_set(const char *str, int pos)
593 int arg = get_cmd_arg_num(str, pos);
594 const char *fields[] = {
596 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
597 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
598 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
599 "wps_fragment_size", "wps_version_number", "ampdu",
600 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
601 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
603 /* global configuration parameters */
604 "eapol_version", "ap_scan", "disable_scan_offload",
605 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
606 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
607 "driver_param", "dot11RSNAConfigPMKLifetime",
608 "dot11RSNAConfigPMKReauthThreshold",
609 "dot11RSNAConfigSATimeout",
610 "update_config", "load_dynamic_eap", "uuid", "device_name",
611 "manufacturer", "model_name", "model_number", "serial_number",
612 "device_type", "os_version", "config_methods",
613 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
614 "p2p_listen_reg_class", "p2p_listen_channel",
615 "p2p_oper_reg_class", "p2p_oper_channel",
616 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
617 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
619 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
621 "p2p_ignore_shared_freq", "country", "bss_max_count",
622 "bss_expiration_age", "bss_expiration_scan_count",
623 "filter_ssids", "filter_rssi", "max_num_sta",
624 "disassoc_low_ack", "hs20", "interworking", "hessid",
625 "access_network_type", "pbc_in_m1", "autoscan",
626 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
627 "wps_nfc_dev_pw", "ext_password_backend",
628 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
629 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
630 "ignore_old_scan_res", "freq_list", "external_sim"
632 int i, num_fields = ARRAY_SIZE(fields);
635 char **res = os_calloc(num_fields + 1, sizeof(char *));
638 for (i = 0; i < num_fields; i++) {
639 res[i] = os_strdup(fields[i]);
646 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
647 return cli_txt_list_array(&bsses);
653 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
655 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
659 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
661 return wpa_ctrl_command(ctrl, "LOGOFF");
665 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
667 return wpa_ctrl_command(ctrl, "LOGON");
671 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
674 return wpa_ctrl_command(ctrl, "REASSOCIATE");
678 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
681 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
685 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
687 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
691 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
694 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
698 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
701 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
705 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
708 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
712 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
718 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
720 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
721 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
722 printf("Too long BSS_FLUSH command.\n");
725 return wpa_ctrl_command(ctrl, cmd);
729 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
732 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
736 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
738 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
742 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
744 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
748 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
751 printf("Invalid WPS_PIN command: need one or two arguments:\n"
752 "- BSSID: use 'any' to select any\n"
753 "- PIN: optional, used only with devices that have no "
758 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
762 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
765 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
769 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
772 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
776 #ifdef CONFIG_WPS_NFC
778 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
780 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
784 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
787 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
791 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
794 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
798 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
806 printf("Invalid 'wps_nfc_tag_read' command - one argument "
811 buflen = 18 + os_strlen(argv[0]);
812 buf = os_malloc(buflen);
815 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
817 ret = wpa_ctrl_command(ctrl, buf);
824 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
827 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
831 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
834 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
838 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
846 printf("Invalid 'nfc_rx_handover_req' command - one argument "
851 buflen = 21 + os_strlen(argv[0]);
852 buf = os_malloc(buflen);
855 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
857 ret = wpa_ctrl_command(ctrl, buf);
864 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
872 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
877 buflen = 21 + os_strlen(argv[0]);
878 buf = os_malloc(buflen);
881 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
883 ret = wpa_ctrl_command(ctrl, buf);
890 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
893 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
896 #endif /* CONFIG_WPS_NFC */
899 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
905 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
907 else if (argc == 5 || argc == 6) {
908 char ssid_hex[2 * 32 + 1];
909 char key_hex[2 * 64 + 1];
913 for (i = 0; i < 32; i++) {
914 if (argv[2][i] == '\0')
916 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
921 for (i = 0; i < 64; i++) {
922 if (argv[5][i] == '\0')
924 os_snprintf(&key_hex[i * 2], 3, "%02x",
929 res = os_snprintf(cmd, sizeof(cmd),
930 "WPS_REG %s %s %s %s %s %s",
931 argv[0], argv[1], ssid_hex, argv[3], argv[4],
934 printf("Invalid WPS_REG command: need two arguments:\n"
935 "- BSSID of the target AP\n"
937 printf("Alternatively, six arguments can be used to "
938 "reconfigure the AP:\n"
939 "- BSSID of the target AP\n"
942 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
943 "- new encr (NONE, WEP, TKIP, CCMP)\n"
948 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
949 printf("Too long WPS_REG command.\n");
952 return wpa_ctrl_command(ctrl, cmd);
956 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
959 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
963 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
966 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
970 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
973 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
978 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
982 printf("Invalid WPS_ER_PIN command: need at least two "
984 "- UUID: use 'any' to select any\n"
985 "- PIN: Enrollee PIN\n"
986 "optional: - Enrollee MAC address\n");
990 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
994 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
997 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1001 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1005 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1006 "- UUID: specify which AP to use\n"
1011 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1015 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1019 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1021 "- UUID: specify which AP to use\n"
1022 "- Network configuration id\n");
1026 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1030 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1036 if (argc == 5 || argc == 6) {
1037 char ssid_hex[2 * 32 + 1];
1038 char key_hex[2 * 64 + 1];
1042 for (i = 0; i < 32; i++) {
1043 if (argv[2][i] == '\0')
1045 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1050 for (i = 0; i < 64; i++) {
1051 if (argv[5][i] == '\0')
1053 os_snprintf(&key_hex[i * 2], 3, "%02x",
1058 res = os_snprintf(cmd, sizeof(cmd),
1059 "WPS_ER_CONFIG %s %s %s %s %s %s",
1060 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1063 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1067 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1068 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1073 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1074 printf("Too long WPS_ER_CONFIG command.\n");
1077 return wpa_ctrl_command(ctrl, cmd);
1081 #ifdef CONFIG_WPS_NFC
1082 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1086 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1088 "- WPS/NDEF: token format\n"
1089 "- UUID: specify which AP to use\n");
1093 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1095 #endif /* CONFIG_WPS_NFC */
1098 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1100 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1104 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1106 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1110 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1112 char cmd[256], *pos, *end;
1116 printf("Invalid IDENTITY command: needs two arguments "
1117 "(network id and identity)\n");
1121 end = cmd + sizeof(cmd);
1123 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1125 if (ret < 0 || ret >= end - pos) {
1126 printf("Too long IDENTITY command.\n");
1130 for (i = 2; i < argc; i++) {
1131 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1132 if (ret < 0 || ret >= end - pos) {
1133 printf("Too long IDENTITY command.\n");
1139 return wpa_ctrl_command(ctrl, cmd);
1143 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1145 char cmd[256], *pos, *end;
1149 printf("Invalid PASSWORD command: needs two arguments "
1150 "(network id and password)\n");
1154 end = cmd + sizeof(cmd);
1156 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1158 if (ret < 0 || ret >= end - pos) {
1159 printf("Too long PASSWORD command.\n");
1163 for (i = 2; i < argc; i++) {
1164 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1165 if (ret < 0 || ret >= end - pos) {
1166 printf("Too long PASSWORD command.\n");
1172 return wpa_ctrl_command(ctrl, cmd);
1176 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1179 char cmd[256], *pos, *end;
1183 printf("Invalid NEW_PASSWORD command: needs two arguments "
1184 "(network id and password)\n");
1188 end = cmd + sizeof(cmd);
1190 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1192 if (ret < 0 || ret >= end - pos) {
1193 printf("Too long NEW_PASSWORD command.\n");
1197 for (i = 2; i < argc; i++) {
1198 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1199 if (ret < 0 || ret >= end - pos) {
1200 printf("Too long NEW_PASSWORD command.\n");
1206 return wpa_ctrl_command(ctrl, cmd);
1210 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1212 char cmd[256], *pos, *end;
1216 printf("Invalid PIN command: needs two arguments "
1217 "(network id and pin)\n");
1221 end = cmd + sizeof(cmd);
1223 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1225 if (ret < 0 || ret >= end - pos) {
1226 printf("Too long PIN command.\n");
1230 for (i = 2; i < argc; i++) {
1231 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1232 if (ret < 0 || ret >= end - pos) {
1233 printf("Too long PIN command.\n");
1238 return wpa_ctrl_command(ctrl, cmd);
1242 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1244 char cmd[256], *pos, *end;
1248 printf("Invalid OTP command: needs two arguments (network "
1249 "id and password)\n");
1253 end = cmd + sizeof(cmd);
1255 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1257 if (ret < 0 || ret >= end - pos) {
1258 printf("Too long OTP command.\n");
1262 for (i = 2; i < argc; i++) {
1263 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1264 if (ret < 0 || ret >= end - pos) {
1265 printf("Too long OTP command.\n");
1271 return wpa_ctrl_command(ctrl, cmd);
1275 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1277 char cmd[256], *pos, *end;
1281 printf("Invalid SIM command: needs two arguments "
1282 "(network id and SIM operation response)\n");
1286 end = cmd + sizeof(cmd);
1288 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1290 if (ret < 0 || ret >= end - pos) {
1291 printf("Too long SIM command.\n");
1295 for (i = 2; i < argc; i++) {
1296 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1297 if (ret < 0 || ret >= end - pos) {
1298 printf("Too long SIM command.\n");
1303 return wpa_ctrl_command(ctrl, cmd);
1307 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1310 char cmd[256], *pos, *end;
1314 printf("Invalid PASSPHRASE command: needs two arguments "
1315 "(network id and passphrase)\n");
1319 end = cmd + sizeof(cmd);
1321 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1323 if (ret < 0 || ret >= end - pos) {
1324 printf("Too long PASSPHRASE command.\n");
1328 for (i = 2; i < argc; i++) {
1329 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1330 if (ret < 0 || ret >= end - pos) {
1331 printf("Too long PASSPHRASE command.\n");
1337 return wpa_ctrl_command(ctrl, cmd);
1341 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1344 printf("Invalid BSSID command: needs two arguments (network "
1349 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1353 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1355 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1359 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1361 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1365 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1368 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1372 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1375 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1379 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1382 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1386 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1389 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1393 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1396 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1400 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1403 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1407 static void wpa_cli_show_network_variables(void)
1409 printf("set_network variables:\n"
1410 " ssid (network name, SSID)\n"
1411 " psk (WPA passphrase or pre-shared key)\n"
1412 " key_mgmt (key management protocol)\n"
1413 " identity (EAP identity)\n"
1414 " password (EAP password)\n"
1417 "Note: Values are entered in the same format as the "
1418 "configuration file is using,\n"
1419 "i.e., strings values need to be inside double quotation "
1421 "For example: set_network 1 ssid \"network name\"\n"
1423 "Please see wpa_supplicant.conf documentation for full list "
1424 "of\navailable variables.\n");
1428 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1432 wpa_cli_show_network_variables();
1437 printf("Invalid SET_NETWORK command: needs three arguments\n"
1438 "(network id, variable name, and value)\n");
1442 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1446 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1450 wpa_cli_show_network_variables();
1455 printf("Invalid GET_NETWORK command: needs two arguments\n"
1456 "(network id and variable name)\n");
1460 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1464 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1467 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1471 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1473 return wpa_ctrl_command(ctrl, "ADD_CRED");
1477 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1480 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1484 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1487 printf("Invalid SET_CRED command: needs three arguments\n"
1488 "(cred id, variable name, and value)\n");
1492 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1496 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1499 return wpa_ctrl_command(ctrl, "DISCONNECT");
1503 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1506 return wpa_ctrl_command(ctrl, "RECONNECT");
1510 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1513 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1517 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1519 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1523 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1526 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1530 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1532 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1536 static char ** wpa_cli_complete_bss(const char *str, int pos)
1538 int arg = get_cmd_arg_num(str, pos);
1543 res = cli_txt_list_array(&bsses);
1551 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1554 if (argc < 1 || argc > 2) {
1555 printf("Invalid GET_CAPABILITY command: need either one or "
1560 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1561 printf("Invalid GET_CAPABILITY command: second argument, "
1562 "if any, must be 'strict'\n");
1566 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1570 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1572 printf("Available interfaces:\n");
1573 return wpa_ctrl_command(ctrl, "INTERFACES");
1577 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1580 wpa_cli_list_interfaces(ctrl);
1584 wpa_cli_close_connection();
1585 os_free(ctrl_ifname);
1586 ctrl_ifname = os_strdup(argv[0]);
1588 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1589 printf("Connected to interface '%s.\n", ctrl_ifname);
1591 printf("Could not connect to interface '%s' - re-trying\n",
1598 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1601 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1605 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1608 return wpa_ctrl_command(ctrl, "TERMINATE");
1612 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1619 printf("Invalid INTERFACE_ADD command: needs at least one "
1620 "argument (interface name)\n"
1621 "All arguments: ifname confname driver ctrl_interface "
1622 "driver_param bridge_name\n");
1627 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1628 * <driver_param>TAB<bridge_name>
1630 res = os_snprintf(cmd, sizeof(cmd),
1631 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1633 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1634 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1635 argc > 5 ? argv[5] : "");
1636 if (res < 0 || (size_t) res >= sizeof(cmd))
1638 cmd[sizeof(cmd) - 1] = '\0';
1639 return wpa_ctrl_command(ctrl, cmd);
1643 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1646 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1650 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1653 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1658 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1660 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1664 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1665 char *addr, size_t addr_len)
1667 char buf[4096], *pos;
1671 if (ctrl_conn == NULL) {
1672 printf("Not connected to hostapd - command dropped.\n");
1675 len = sizeof(buf) - 1;
1676 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1679 printf("'%s' command timed out.\n", cmd);
1681 } else if (ret < 0) {
1682 printf("'%s' command failed.\n", cmd);
1687 if (os_memcmp(buf, "FAIL", 4) == 0)
1692 while (*pos != '\0' && *pos != '\n')
1695 os_strlcpy(addr, buf, addr_len);
1700 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1702 char addr[32], cmd[64];
1704 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1707 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1708 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1714 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1717 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1721 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1724 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1727 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1730 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1733 #endif /* CONFIG_AP */
1736 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1738 return wpa_ctrl_command(ctrl, "SUSPEND");
1742 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1744 return wpa_ctrl_command(ctrl, "RESUME");
1748 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1750 return wpa_ctrl_command(ctrl, "DROP_SA");
1754 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1756 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1762 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1764 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1768 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1771 int arg = get_cmd_arg_num(str, pos);
1773 res = os_calloc(6, sizeof(char *));
1776 res[0] = os_strdup("type=social");
1777 if (res[0] == NULL) {
1781 res[1] = os_strdup("type=progressive");
1784 res[2] = os_strdup("delay=");
1787 res[3] = os_strdup("dev_id=");
1791 res[4] = os_strdup("[timeout]");
1797 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1800 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1804 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1807 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1811 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1813 int arg = get_cmd_arg_num(str, pos);
1818 res = cli_txt_list_array(&p2p_peers);
1826 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1829 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1833 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1836 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1840 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1842 int arg = get_cmd_arg_num(str, pos);
1847 res = cli_txt_list_array(&p2p_groups);
1855 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1858 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1862 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1865 if (argc != 2 && argc != 3) {
1866 printf("Invalid P2P_PROV_DISC command: needs at least "
1867 "two arguments, address and config method\n"
1868 "(display, keypad, or pbc) and an optional join\n");
1872 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1876 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1879 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1883 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1888 if (argc != 2 && argc != 4) {
1889 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1890 "arguments (address and TLVs) or four arguments "
1891 "(address, \"upnp\", version, search target "
1896 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1898 return wpa_ctrl_command(ctrl, cmd);
1902 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1903 int argc, char *argv[])
1905 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1909 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1916 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1917 "arguments (freq, address, dialog token, and TLVs)\n");
1921 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1922 argv[0], argv[1], argv[2], argv[3]);
1923 if (res < 0 || (size_t) res >= sizeof(cmd))
1925 cmd[sizeof(cmd) - 1] = '\0';
1926 return wpa_ctrl_command(ctrl, cmd);
1930 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1933 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1937 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1938 int argc, char *argv[])
1940 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1944 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1947 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1951 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1957 if (argc != 3 && argc != 4) {
1958 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1964 res = os_snprintf(cmd, sizeof(cmd),
1965 "P2P_SERVICE_ADD %s %s %s %s",
1966 argv[0], argv[1], argv[2], argv[3]);
1968 res = os_snprintf(cmd, sizeof(cmd),
1969 "P2P_SERVICE_ADD %s %s %s",
1970 argv[0], argv[1], argv[2]);
1971 if (res < 0 || (size_t) res >= sizeof(cmd))
1973 cmd[sizeof(cmd) - 1] = '\0';
1974 return wpa_ctrl_command(ctrl, cmd);
1978 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1984 if (argc != 2 && argc != 3) {
1985 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1991 res = os_snprintf(cmd, sizeof(cmd),
1992 "P2P_SERVICE_DEL %s %s %s",
1993 argv[0], argv[1], argv[2]);
1995 res = os_snprintf(cmd, sizeof(cmd),
1996 "P2P_SERVICE_DEL %s %s",
1998 if (res < 0 || (size_t) res >= sizeof(cmd))
2000 cmd[sizeof(cmd) - 1] = '\0';
2001 return wpa_ctrl_command(ctrl, cmd);
2005 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2006 int argc, char *argv[])
2008 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2012 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2013 int argc, char *argv[])
2015 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2019 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2021 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2025 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2027 int arg = get_cmd_arg_num(str, pos);
2032 res = cli_txt_list_array(&p2p_peers);
2040 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2041 char *addr, size_t addr_len,
2044 char buf[4096], *pos;
2048 if (ctrl_conn == NULL)
2050 len = sizeof(buf) - 1;
2051 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2054 printf("'%s' command timed out.\n", cmd);
2056 } else if (ret < 0) {
2057 printf("'%s' command failed.\n", cmd);
2062 if (os_memcmp(buf, "FAIL", 4) == 0)
2066 while (*pos != '\0' && *pos != '\n')
2069 os_strlcpy(addr, buf, addr_len);
2070 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2071 printf("%s\n", addr);
2076 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2078 char addr[32], cmd[64];
2081 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2083 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2084 addr, sizeof(addr), discovered))
2087 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2088 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2095 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2097 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2101 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2103 int arg = get_cmd_arg_num(str, pos);
2104 const char *fields[] = {
2124 int i, num_fields = ARRAY_SIZE(fields);
2127 char **res = os_calloc(num_fields + 1, sizeof(char *));
2130 for (i = 0; i < num_fields; i++) {
2131 res[i] = os_strdup(fields[i]);
2138 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2139 return cli_txt_list_array(&p2p_peers);
2145 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2147 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2151 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2154 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2158 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2161 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2165 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2168 if (argc != 0 && argc != 2 && argc != 4) {
2169 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2170 "(preferred duration, interval; in microsecods).\n"
2171 "Optional second pair can be used to provide "
2172 "acceptable values.\n");
2176 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2180 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2183 if (argc != 0 && argc != 2) {
2184 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2185 "(availability period, availability interval; in "
2187 "Extended Listen Timing can be cancelled with this "
2188 "command when used without parameters.\n");
2192 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2196 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2199 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2202 #endif /* CONFIG_P2P */
2204 #ifdef CONFIG_WIFI_DISPLAY
2206 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2212 if (argc != 1 && argc != 2) {
2213 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2214 "arguments (subelem, hexdump)\n");
2218 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2219 argv[0], argc > 1 ? argv[1] : "");
2220 if (res < 0 || (size_t) res >= sizeof(cmd))
2222 cmd[sizeof(cmd) - 1] = '\0';
2223 return wpa_ctrl_command(ctrl, cmd);
2227 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2234 printf("Invalid WFD_SUBELEM_GET command: needs one "
2235 "argument (subelem)\n");
2239 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2241 if (res < 0 || (size_t) res >= sizeof(cmd))
2243 cmd[sizeof(cmd) - 1] = '\0';
2244 return wpa_ctrl_command(ctrl, cmd);
2246 #endif /* CONFIG_WIFI_DISPLAY */
2249 #ifdef CONFIG_INTERWORKING
2250 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2253 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2257 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2260 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2264 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2267 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2271 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2274 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2278 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2280 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2284 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2287 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2291 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2294 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2296 #endif /* CONFIG_INTERWORKING */
2301 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2304 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2308 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2314 printf("Command needs one or two arguments (dst mac addr and "
2315 "optional home realm)\n");
2319 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2323 return wpa_ctrl_command(ctrl, cmd);
2326 #endif /* CONFIG_HS20 */
2329 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2332 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2336 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2339 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2343 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2346 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2350 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2353 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2357 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2360 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2364 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2367 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2371 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2374 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2378 #ifdef CONFIG_AUTOSCAN
2380 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2383 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2385 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2388 #endif /* CONFIG_AUTOSCAN */
2393 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2395 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2399 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2401 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2404 #endif /* CONFIG_WNM */
2407 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2411 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2416 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2418 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2420 #endif /* ANDROID */
2423 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2425 return wpa_ctrl_command(ctrl, "FLUSH");
2429 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2431 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2435 enum wpa_cli_cmd_flags {
2436 cli_cmd_flag_none = 0x00,
2437 cli_cmd_flag_sensitive = 0x01
2440 struct wpa_cli_cmd {
2442 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2443 char ** (*completion)(const char *str, int pos);
2444 enum wpa_cli_cmd_flags flags;
2448 static struct wpa_cli_cmd wpa_cli_commands[] = {
2449 { "status", wpa_cli_cmd_status, NULL,
2451 "[verbose] = get current WPA/EAPOL/EAP status" },
2452 { "ifname", wpa_cli_cmd_ifname, NULL,
2454 "= get current interface name" },
2455 { "ping", wpa_cli_cmd_ping, NULL,
2457 "= pings wpa_supplicant" },
2458 { "relog", wpa_cli_cmd_relog, NULL,
2460 "= re-open log-file (allow rolling logs)" },
2461 { "note", wpa_cli_cmd_note, NULL,
2463 "<text> = add a note to wpa_supplicant debug log" },
2464 { "mib", wpa_cli_cmd_mib, NULL,
2466 "= get MIB variables (dot1x, dot11)" },
2467 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2469 "[command] = show usage help" },
2470 { "interface", wpa_cli_cmd_interface, NULL,
2472 "[ifname] = show interfaces/select interface" },
2473 { "level", wpa_cli_cmd_level, NULL,
2475 "<debug level> = change debug level" },
2476 { "license", wpa_cli_cmd_license, NULL,
2478 "= show full wpa_cli license" },
2479 { "quit", wpa_cli_cmd_quit, NULL,
2482 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2484 "= set variables (shows list of variables when run without "
2486 { "get", wpa_cli_cmd_get, NULL,
2488 "<name> = get information" },
2489 { "logon", wpa_cli_cmd_logon, NULL,
2491 "= IEEE 802.1X EAPOL state machine logon" },
2492 { "logoff", wpa_cli_cmd_logoff, NULL,
2494 "= IEEE 802.1X EAPOL state machine logoff" },
2495 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2497 "= show PMKSA cache" },
2498 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2500 "= force reassociation" },
2501 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2503 "<BSSID> = force preauthentication" },
2504 { "identity", wpa_cli_cmd_identity, NULL,
2506 "<network id> <identity> = configure identity for an SSID" },
2507 { "password", wpa_cli_cmd_password, NULL,
2508 cli_cmd_flag_sensitive,
2509 "<network id> <password> = configure password for an SSID" },
2510 { "new_password", wpa_cli_cmd_new_password, NULL,
2511 cli_cmd_flag_sensitive,
2512 "<network id> <password> = change password for an SSID" },
2513 { "pin", wpa_cli_cmd_pin, NULL,
2514 cli_cmd_flag_sensitive,
2515 "<network id> <pin> = configure pin for an SSID" },
2516 { "otp", wpa_cli_cmd_otp, NULL,
2517 cli_cmd_flag_sensitive,
2518 "<network id> <password> = configure one-time-password for an SSID"
2520 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2521 cli_cmd_flag_sensitive,
2522 "<network id> <passphrase> = configure private key passphrase\n"
2524 { "sim", wpa_cli_cmd_sim, NULL,
2525 cli_cmd_flag_sensitive,
2526 "<network id> <pin> = report SIM operation result" },
2527 { "bssid", wpa_cli_cmd_bssid, NULL,
2529 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2530 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2532 "<BSSID> = add a BSSID to the blacklist\n"
2533 "blacklist clear = clear the blacklist\n"
2534 "blacklist = display the blacklist" },
2535 { "log_level", wpa_cli_cmd_log_level, NULL,
2537 "<level> [<timestamp>] = update the log level/timestamp\n"
2538 "log_level = display the current log level and log options" },
2539 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2541 "= list configured networks" },
2542 { "select_network", wpa_cli_cmd_select_network, NULL,
2544 "<network id> = select a network (disable others)" },
2545 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2547 "<network id> = enable a network" },
2548 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2550 "<network id> = disable a network" },
2551 { "add_network", wpa_cli_cmd_add_network, NULL,
2553 "= add a network" },
2554 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2556 "<network id> = remove a network" },
2557 { "set_network", wpa_cli_cmd_set_network, NULL,
2558 cli_cmd_flag_sensitive,
2559 "<network id> <variable> <value> = set network variables (shows\n"
2560 " list of variables when run without arguments)" },
2561 { "get_network", wpa_cli_cmd_get_network, NULL,
2563 "<network id> <variable> = get network variables" },
2564 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2566 "= list configured credentials" },
2567 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2569 "= add a credential" },
2570 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2572 "<cred id> = remove a credential" },
2573 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2574 cli_cmd_flag_sensitive,
2575 "<cred id> <variable> <value> = set credential variables" },
2576 { "save_config", wpa_cli_cmd_save_config, NULL,
2578 "= save the current configuration" },
2579 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2581 "= disconnect and wait for reassociate/reconnect command before\n"
2583 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2585 "= like reassociate, but only takes effect if already disconnected"
2587 { "scan", wpa_cli_cmd_scan, NULL,
2589 "= request new BSS scan" },
2590 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2592 "= get latest scan results" },
2593 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2595 "<<idx> | <bssid>> = get detailed scan result info" },
2596 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2598 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2599 "= get capabilies" },
2600 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2602 "= force wpa_supplicant to re-read its configuration file" },
2603 { "terminate", wpa_cli_cmd_terminate, NULL,
2605 "= terminate wpa_supplicant" },
2606 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2608 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2609 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2611 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2613 "<ifname> = removes the interface" },
2614 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2616 "= list available interfaces" },
2617 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2619 "<value> = set ap_scan parameter" },
2620 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2622 "<value> = set scan_interval parameter (in seconds)" },
2623 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2625 "<value> = set BSS expiration age parameter" },
2626 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2628 "<value> = set BSS expiration scan count parameter" },
2629 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2631 "<value> = set BSS flush age (0 by default)" },
2632 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2634 "<addr> = request STK negotiation with <addr>" },
2635 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2637 "<addr> = request over-the-DS FT with <addr>" },
2638 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2640 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2641 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2642 cli_cmd_flag_sensitive,
2643 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2645 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2646 cli_cmd_flag_sensitive,
2647 "<PIN> = verify PIN checksum" },
2648 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2649 "Cancels the pending WPS operation" },
2650 #ifdef CONFIG_WPS_NFC
2651 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2653 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2654 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2656 "<WPS|NDEF> = build configuration token" },
2657 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2659 "<WPS|NDEF> = create password token" },
2660 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2661 cli_cmd_flag_sensitive,
2662 "<hexdump of payload> = report read NFC tag with WPS data" },
2663 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2665 "<NDEF> <WPS> = create NFC handover request" },
2666 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2668 "<NDEF> <WPS> = create NFC handover select" },
2669 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2671 "<hexdump of payload> = report received NFC handover request" },
2672 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2674 "<hexdump of payload> = report received NFC handover select" },
2675 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2677 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2679 #endif /* CONFIG_WPS_NFC */
2680 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2681 cli_cmd_flag_sensitive,
2682 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2683 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2684 cli_cmd_flag_sensitive,
2685 "[params..] = enable/disable AP PIN" },
2686 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2688 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2689 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2691 "= stop Wi-Fi Protected Setup External Registrar" },
2692 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2693 cli_cmd_flag_sensitive,
2694 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2695 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2697 "<UUID> = accept an Enrollee PBC using External Registrar" },
2698 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2699 cli_cmd_flag_sensitive,
2700 "<UUID> <PIN> = learn AP configuration" },
2701 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2703 "<UUID> <network id> = set AP configuration for enrolling" },
2704 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2705 cli_cmd_flag_sensitive,
2706 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2707 #ifdef CONFIG_WPS_NFC
2708 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2710 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2711 #endif /* CONFIG_WPS_NFC */
2712 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2714 "<addr> = request RSN authentication with <addr> in IBSS" },
2716 { "sta", wpa_cli_cmd_sta, NULL,
2718 "<addr> = get information about an associated station (AP)" },
2719 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2721 "= get information about all associated stations (AP)" },
2722 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2724 "<addr> = deauthenticate a station" },
2725 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2727 "<addr> = disassociate a station" },
2728 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
2730 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
2731 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
2732 " = CSA parameters" },
2733 #endif /* CONFIG_AP */
2734 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2735 "= notification of suspend/hibernate" },
2736 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2737 "= notification of resume/thaw" },
2738 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2739 "= drop SA without deauth/disassoc (test command)" },
2740 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2742 "<addr> = roam to the specified BSS" },
2744 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2746 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2747 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2748 "= stop P2P Devices search" },
2749 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2751 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2752 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2753 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2754 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2755 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2756 "<ifname> = remove P2P group interface (terminate group if GO)" },
2757 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2758 "[ht40] = add a new P2P group (local end as GO)" },
2759 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2760 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2761 "<addr> <method> = request provisioning discovery" },
2762 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2764 "= get the passphrase for a group (GO only)" },
2765 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2766 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2767 "<addr> <TLVs> = schedule service discovery request" },
2768 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2769 NULL, cli_cmd_flag_none,
2770 "<id> = cancel pending service discovery request" },
2771 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2773 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2774 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2776 "= indicate change in local services" },
2777 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2779 "<external> = set external processing of service discovery" },
2780 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2782 "= remove all stored service entries" },
2783 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2785 "<bonjour|upnp> <query|version> <response|service> = add a local "
2787 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2789 "<bonjour|upnp> <query|version> [|service] = remove a local "
2791 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2793 "<addr> = reject connection attempts from a specific peer" },
2794 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2796 "<cmd> [peer=addr] = invite peer" },
2797 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2798 "[discovered] = list known (optionally, only fully discovered) P2P "
2800 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2802 "<address> = show information about known P2P peer" },
2803 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
2805 "<field> <value> = set a P2P parameter" },
2806 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2807 "= flush P2P state" },
2808 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2809 "= cancel P2P group formation" },
2810 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2811 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2812 "<address> = unauthorize a peer" },
2813 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2815 "[<duration> <interval>] [<duration> <interval>] = request GO "
2817 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2819 "[<period> <interval>] = set extended listen timing" },
2820 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
2821 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2822 "<address|iface=address> = remove a peer from all groups" },
2823 #endif /* CONFIG_P2P */
2824 #ifdef CONFIG_WIFI_DISPLAY
2825 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2827 "<subelem> [contents] = set Wi-Fi Display subelement" },
2828 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2830 "<subelem> = get Wi-Fi Display subelement" },
2831 #endif /* CONFIG_WIFI_DISPLAY */
2832 #ifdef CONFIG_INTERWORKING
2833 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2834 "= fetch ANQP information for all APs" },
2835 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2837 "= stop fetch_anqp operation" },
2838 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2840 "[auto] = perform Interworking network selection" },
2841 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2842 wpa_cli_complete_bss, cli_cmd_flag_none,
2843 "<BSSID> = connect using Interworking credentials" },
2844 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2846 "<addr> <info id>[,<info id>]... = request ANQP information" },
2847 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2849 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2850 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2851 wpa_cli_complete_bss, cli_cmd_flag_none,
2852 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2853 #endif /* CONFIG_INTERWORKING */
2855 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2857 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2859 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2860 wpa_cli_complete_bss, cli_cmd_flag_none,
2861 "<addr> <home realm> = get HS20 nai home realm list" },
2862 #endif /* CONFIG_HS20 */
2863 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2865 "<0/1> = disable/enable automatic reconnection" },
2866 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2868 "<addr> = request TDLS discovery with <addr>" },
2869 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2871 "<addr> = request TDLS setup with <addr>" },
2872 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2874 "<addr> = tear down TDLS with <addr>" },
2875 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2877 "= get signal parameters" },
2878 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2880 "= get TX/RX packet counters" },
2881 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2883 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2884 #ifdef CONFIG_AUTOSCAN
2885 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2886 "[params] = Set or unset (if none) autoscan parameters" },
2887 #endif /* CONFIG_AUTOSCAN */
2889 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2890 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2891 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2892 "<query reason> = Send BSS Transition Management Query" },
2893 #endif /* CONFIG_WNM */
2894 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2895 "<params..> = Sent unprocessed command" },
2896 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2897 "= flush wpa_supplicant state" },
2899 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
2900 "<command> = driver private commands" },
2901 #endif /* ANDROID */
2902 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
2903 "= radio_work <show/add/done>" },
2904 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2909 * Prints command usage, lines are padded with the specified string.
2911 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2916 printf("%s%s ", pad, cmd->cmd);
2917 for (n = 0; (c = cmd->usage[n]); n++) {
2926 static void print_help(const char *cmd)
2929 printf("commands:\n");
2930 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2931 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2932 print_cmd_help(&wpa_cli_commands[n], " ");
2937 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2939 const char *c, *delim;
2943 delim = os_strchr(cmd, ' ');
2947 len = os_strlen(cmd);
2949 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2950 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2951 return (wpa_cli_commands[n].flags &
2952 cli_cmd_flag_sensitive);
2958 static char ** wpa_list_cmd_list(void)
2962 struct cli_txt_entry *e;
2964 count = ARRAY_SIZE(wpa_cli_commands);
2965 count += dl_list_len(&p2p_groups);
2966 count += dl_list_len(&ifnames);
2967 res = os_calloc(count + 1, sizeof(char *));
2971 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2972 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2977 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
2978 size_t len = 8 + os_strlen(e->txt);
2979 res[i] = os_malloc(len);
2982 os_snprintf(res[i], len, "ifname=%s", e->txt);
2986 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
2987 res[i] = os_strdup(e->txt);
2997 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3002 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3003 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3004 if (wpa_cli_commands[i].completion)
3005 return wpa_cli_commands[i].completion(str,
3008 printf("\r%s\n", wpa_cli_commands[i].usage);
3018 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3024 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3025 end = os_strchr(str, ' ');
3026 if (end && pos > end - str) {
3027 pos -= end - str + 1;
3032 end = os_strchr(str, ' ');
3033 if (end == NULL || str + pos < end)
3034 return wpa_list_cmd_list();
3036 cmd = os_malloc(pos + 1);
3039 os_memcpy(cmd, str, pos);
3040 cmd[end - str] = '\0';
3041 res = wpa_cli_cmd_completion(cmd, str, pos);
3047 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3049 struct wpa_cli_cmd *cmd, *match = NULL;
3053 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3054 ifname_prefix = argv[0] + 7;
3058 ifname_prefix = NULL;
3064 cmd = wpa_cli_commands;
3066 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3069 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3070 /* we have an exact match */
3080 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3081 cmd = wpa_cli_commands;
3083 if (os_strncasecmp(cmd->cmd, argv[0],
3084 os_strlen(argv[0])) == 0) {
3085 printf(" %s", cmd->cmd);
3091 } else if (count == 0) {
3092 printf("Unknown command '%s'\n", argv[0]);
3095 ret = match->handler(ctrl, argc - 1, &argv[1]);
3102 static int str_match(const char *a, const char *b)
3104 return os_strncmp(a, b, os_strlen(b)) == 0;
3108 static int wpa_cli_exec(const char *program, const char *arg1,
3116 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3117 cmd = os_malloc(len);
3120 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3121 if (res < 0 || (size_t) res >= len) {
3125 cmd[len - 1] = '\0';
3127 if (system(cmd) < 0)
3129 #endif /* _WIN32_WCE */
3136 static void wpa_cli_action_process(const char *msg)
3139 char *copy = NULL, *id, *pos2;
3144 pos = os_strchr(pos, '>');
3151 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3153 os_unsetenv("WPA_ID");
3154 os_unsetenv("WPA_ID_STR");
3155 os_unsetenv("WPA_CTRL_DIR");
3157 pos = os_strstr(pos, "[id=");
3159 copy = os_strdup(pos + 4);
3163 while (*pos2 && *pos2 != ' ')
3167 os_setenv("WPA_ID", id, 1);
3168 while (*pos2 && *pos2 != '=')
3173 while (*pos2 && *pos2 != ']')
3176 os_setenv("WPA_ID_STR", id, 1);
3180 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3182 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3183 wpa_cli_connected = 1;
3184 wpa_cli_last_id = new_id;
3185 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3187 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3188 if (wpa_cli_connected) {
3189 wpa_cli_connected = 0;
3190 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3192 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3193 wpa_cli_exec(action_file, ctrl_ifname, pos);
3194 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3195 wpa_cli_exec(action_file, ctrl_ifname, pos);
3196 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3197 wpa_cli_exec(action_file, ctrl_ifname, pos);
3198 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3199 wpa_cli_exec(action_file, ctrl_ifname, pos);
3200 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3201 wpa_cli_exec(action_file, ctrl_ifname, pos);
3202 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3203 wpa_cli_exec(action_file, ctrl_ifname, pos);
3204 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3205 wpa_cli_exec(action_file, ctrl_ifname, pos);
3206 } else if (str_match(pos, AP_STA_CONNECTED)) {
3207 wpa_cli_exec(action_file, ctrl_ifname, pos);
3208 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3209 wpa_cli_exec(action_file, ctrl_ifname, pos);
3210 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3211 wpa_cli_exec(action_file, ctrl_ifname, pos);
3212 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3213 printf("wpa_supplicant is terminating - stop monitoring\n");
3219 #ifndef CONFIG_ANSI_C_EXTRA
3220 static void wpa_cli_action_cb(char *msg, size_t len)
3222 wpa_cli_action_process(msg);
3224 #endif /* CONFIG_ANSI_C_EXTRA */
3227 static void wpa_cli_reconnect(void)
3229 wpa_cli_close_connection();
3230 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3235 printf("\rConnection to wpa_supplicant re-established\n");
3241 static void cli_event(const char *str)
3243 const char *start, *s;
3245 start = os_strchr(str, '>');
3251 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3252 s = os_strchr(start, ' ');
3255 s = os_strchr(s + 1, ' ');
3258 cli_txt_list_add(&bsses, s + 1);
3262 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3263 s = os_strchr(start, ' ');
3266 s = os_strchr(s + 1, ' ');
3269 cli_txt_list_del_addr(&bsses, s + 1);
3274 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3275 s = os_strstr(start, " p2p_dev_addr=");
3278 cli_txt_list_add_addr(&p2p_peers, s + 14);
3282 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3283 s = os_strstr(start, " p2p_dev_addr=");
3286 cli_txt_list_del_addr(&p2p_peers, s + 14);
3290 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3291 s = os_strchr(start, ' ');
3294 cli_txt_list_add_word(&p2p_groups, s + 1);
3298 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3299 s = os_strchr(start, ' ');
3302 cli_txt_list_del_word(&p2p_groups, s + 1);
3305 #endif /* CONFIG_P2P */
3309 static int check_terminating(const char *msg)
3311 const char *pos = msg;
3315 pos = os_strchr(pos, '>');
3322 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3324 printf("\rConnection to wpa_supplicant lost - trying to "
3327 wpa_cli_attached = 0;
3328 wpa_cli_close_connection();
3336 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3338 if (ctrl_conn == NULL) {
3339 wpa_cli_reconnect();
3342 while (wpa_ctrl_pending(ctrl) > 0) {
3344 size_t len = sizeof(buf) - 1;
3345 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3348 wpa_cli_action_process(buf);
3351 if (wpa_cli_show_event(buf)) {
3353 printf("\r%s\n", buf);
3357 if (interactive && check_terminating(buf) > 0)
3361 printf("Could not read pending message.\n");
3366 if (wpa_ctrl_pending(ctrl) < 0) {
3367 printf("Connection to wpa_supplicant lost - trying to "
3369 wpa_cli_reconnect();
3375 static int tokenize_cmd(char *cmd, char *argv[])
3388 if (argc == max_args)
3391 char *pos2 = os_strrchr(pos, '"');
3395 while (*pos != '\0' && *pos != ' ')
3405 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3407 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3408 printf("Connection to wpa_supplicant lost - trying to "
3410 wpa_cli_close_connection();
3413 wpa_cli_reconnect();
3414 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3418 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3420 wpa_cli_recv_pending(mon_conn, 0);
3424 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3426 char *argv[max_args];
3428 argc = tokenize_cmd(cmd, argv);
3430 wpa_request(ctrl_conn, argc, argv);
3434 static void wpa_cli_edit_eof_cb(void *ctx)
3440 static int warning_displayed = 0;
3441 static char *hfile = NULL;
3442 static int edit_started = 0;
3444 static void start_edit(void)
3449 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3450 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3451 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3453 home = getenv("HOME");
3455 const char *fname = ".wpa_cli_history";
3456 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3457 hfile = os_malloc(hfile_len);
3459 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3462 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3463 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3469 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3473 static void update_bssid_list(struct wpa_ctrl *ctrl)
3476 size_t len = sizeof(buf);
3478 char *cmd = "BSS RANGE=ALL MASK=0x2";
3483 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3490 pos = os_strstr(pos, "bssid=");
3494 end = os_strchr(pos, '\n');
3498 cli_txt_list_add(&bsses, pos);
3504 static void update_ifnames(struct wpa_ctrl *ctrl)
3507 size_t len = sizeof(buf);
3509 char *cmd = "INTERFACES";
3513 cli_txt_list_flush(&ifnames);
3517 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3524 end = os_strchr(pos, '\n');
3528 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3529 if (ret > 0 && ret < (int) sizeof(txt))
3530 cli_txt_list_add(&ifnames, txt);
3536 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3541 if (ctrl_ifname == NULL)
3542 ctrl_ifname = wpa_cli_get_default_ifname();
3544 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3545 if (!warning_displayed) {
3546 printf("Could not connect to wpa_supplicant: "
3547 "%s - re-trying\n", ctrl_ifname);
3548 warning_displayed = 1;
3550 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3554 update_bssid_list(ctrl_conn);
3556 if (warning_displayed)
3557 printf("Connection established.\n");
3564 static void wpa_cli_interactive(void)
3566 printf("\nInteractive mode\n\n");
3568 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3570 eloop_cancel_timeout(try_connection, NULL, NULL);
3572 cli_txt_list_flush(&p2p_peers);
3573 cli_txt_list_flush(&p2p_groups);
3574 cli_txt_list_flush(&bsses);
3575 cli_txt_list_flush(&ifnames);
3577 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3579 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3580 wpa_cli_close_connection();
3584 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3586 #ifdef CONFIG_ANSI_C_EXTRA
3587 /* TODO: ANSI C version(?) */
3588 printf("Action processing not supported in ANSI C build.\n");
3589 #else /* CONFIG_ANSI_C_EXTRA */
3593 char buf[256]; /* note: large enough to fit in unsolicited messages */
3596 fd = wpa_ctrl_get_fd(ctrl);
3598 while (!wpa_cli_quit) {
3601 tv.tv_sec = ping_interval;
3603 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3604 if (res < 0 && errno != EINTR) {
3609 if (FD_ISSET(fd, &rfds))
3610 wpa_cli_recv_pending(ctrl, 1);
3612 /* verify that connection is still working */
3613 len = sizeof(buf) - 1;
3614 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3615 wpa_cli_action_cb) < 0 ||
3616 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3617 printf("wpa_supplicant did not reply to PING "
3618 "command - exiting\n");
3623 #endif /* CONFIG_ANSI_C_EXTRA */
3627 static void wpa_cli_cleanup(void)
3629 wpa_cli_close_connection();
3631 os_daemonize_terminate(pid_file);
3633 os_program_deinit();
3637 static void wpa_cli_terminate(int sig, void *ctx)
3643 static char * wpa_cli_get_default_ifname(void)
3645 char *ifname = NULL;
3647 #ifdef CONFIG_CTRL_IFACE_UNIX
3648 struct dirent *dent;
3649 DIR *dir = opendir(ctrl_iface_dir);
3652 char ifprop[PROPERTY_VALUE_MAX];
3653 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3654 ifname = os_strdup(ifprop);
3655 printf("Using interface '%s'\n", ifname);
3658 #endif /* ANDROID */
3661 while ((dent = readdir(dir))) {
3662 #ifdef _DIRENT_HAVE_D_TYPE
3664 * Skip the file if it is not a socket. Also accept
3665 * DT_UNKNOWN (0) in case the C library or underlying
3666 * file system does not support d_type.
3668 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3670 #endif /* _DIRENT_HAVE_D_TYPE */
3671 if (os_strcmp(dent->d_name, ".") == 0 ||
3672 os_strcmp(dent->d_name, "..") == 0)
3674 printf("Selected interface '%s'\n", dent->d_name);
3675 ifname = os_strdup(dent->d_name);
3679 #endif /* CONFIG_CTRL_IFACE_UNIX */
3681 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3682 char buf[4096], *pos;
3684 struct wpa_ctrl *ctrl;
3687 ctrl = wpa_ctrl_open(NULL);
3691 len = sizeof(buf) - 1;
3692 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3695 pos = os_strchr(buf, '\n');
3698 ifname = os_strdup(buf);
3700 wpa_ctrl_close(ctrl);
3701 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3707 int main(int argc, char *argv[])
3712 const char *global = NULL;
3714 if (os_program_init())
3718 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3723 action_file = optarg;
3732 ping_interval = atoi(optarg);
3738 printf("%s\n", wpa_cli_version);
3741 os_free(ctrl_ifname);
3742 ctrl_ifname = os_strdup(optarg);
3745 ctrl_iface_dir = optarg;
3756 interactive = (argc == optind) && (action_file == NULL);
3759 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3765 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3766 ctrl_conn = wpa_ctrl_open(NULL);
3767 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3768 ctrl_conn = wpa_ctrl_open(global);
3769 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3770 if (ctrl_conn == NULL) {
3771 fprintf(stderr, "Failed to connect to wpa_supplicant "
3772 "global interface: %s error: %s\n",
3773 global, strerror(errno));
3778 update_ifnames(ctrl_conn);
3779 mon_conn = wpa_ctrl_open(global);
3781 if (wpa_ctrl_attach(mon_conn) == 0) {
3782 wpa_cli_attached = 1;
3783 eloop_register_read_sock(
3784 wpa_ctrl_get_fd(mon_conn),
3785 wpa_cli_mon_receive,
3788 printf("Failed to open monitor "
3789 "connection through global "
3790 "control interface\n");
3796 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3798 if (ctrl_ifname == NULL)
3799 ctrl_ifname = wpa_cli_get_default_ifname();
3802 wpa_cli_interactive();
3805 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3806 fprintf(stderr, "Failed to connect to non-global "
3807 "ctrl_ifname: %s error: %s\n",
3808 ctrl_ifname, strerror(errno));
3813 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3814 wpa_cli_attached = 1;
3816 printf("Warning: Failed to attach to "
3817 "wpa_supplicant.\n");
3822 if (daemonize && os_daemonize(pid_file))
3826 wpa_cli_action(ctrl_conn);
3828 ret = wpa_request(ctrl_conn, argc - optind,
3832 os_free(ctrl_ifname);
3839 #else /* CONFIG_CTRL_IFACE */
3840 int main(int argc, char *argv[])
3842 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3845 #endif /* CONFIG_CTRL_IFACE */