GAS: Report GAS-QUERY-DONE event on initial req TX failure
[mech_eap.git] / wpa_supplicant / wpa_cli.c
index 5fe4618..53036ae 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
 #endif /* ANDROID */
 
 
 #endif /* ANDROID */
 
 
-static const char *wpa_cli_version =
+static const char *const wpa_cli_version =
 "wpa_cli v" VERSION_STR "\n"
 "wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors";
 
 
 
 
-static const char *wpa_cli_license =
+static const char *const wpa_cli_license =
 "This software may be distributed under the terms of the BSD license.\n"
 "See README for more details.\n";
 
 "This software may be distributed under the terms of the BSD license.\n"
 "See README for more details.\n";
 
-static const char *wpa_cli_full_license =
+static const char *const wpa_cli_full_license =
 "This software may be distributed under the terms of the BSD license.\n"
 "\n"
 "Redistribution and use in source and binary forms, with or without\n"
 "This software may be distributed under the terms of the BSD license.\n"
 "\n"
 "Redistribution and use in source and binary forms, with or without\n"
@@ -66,6 +66,12 @@ static const char *wpa_cli_full_license =
 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 "\n";
 
 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 "\n";
 
+#define VENDOR_ELEM_FRAME_ID \
+       "  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
+       "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
+       "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
+       "11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
+
 static struct wpa_ctrl *ctrl_conn;
 static struct wpa_ctrl *mon_conn;
 static int wpa_cli_quit = 0;
 static struct wpa_ctrl *ctrl_conn;
 static struct wpa_ctrl *mon_conn;
 static int wpa_cli_quit = 0;
@@ -76,6 +82,7 @@ static int wpa_cli_last_id = 0;
 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
 #endif /* CONFIG_CTRL_IFACE_DIR */
 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
 #endif /* CONFIG_CTRL_IFACE_DIR */
 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
+static const char *client_socket_dir = NULL;
 static char *ctrl_ifname = NULL;
 static const char *pid_file = NULL;
 static const char *action_file = NULL;
 static char *ctrl_ifname = NULL;
 static const char *pid_file = NULL;
 static const char *action_file = NULL;
@@ -107,7 +114,9 @@ static void usage(void)
 {
        printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
               "[-a<action file>] \\\n"
 {
        printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
               "[-a<action file>] \\\n"
-              "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
+              "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
+              "\\\n"
+              "        [-s<wpa_client_socket_file_path>] "
               "[command..]\n"
               "  -h = help (show this usage text)\n"
               "  -v = shown version information\n"
               "[command..]\n"
               "  -h = help (show this usage text)\n"
               "  -v = shown version information\n"
@@ -330,6 +339,13 @@ static int wpa_cli_open_connection(const char *ifname, int attach)
        }
 #endif /* ANDROID */
 
        }
 #endif /* ANDROID */
 
+       if (client_socket_dir && client_socket_dir[0] &&
+           access(client_socket_dir, F_OK) < 0) {
+               perror(client_socket_dir);
+               os_free(cfile);
+               return -1;
+       }
+
        if (cfile == NULL) {
                flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
                cfile = os_malloc(flen);
        if (cfile == NULL) {
                flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
                cfile = os_malloc(flen);
@@ -343,14 +359,14 @@ static int wpa_cli_open_connection(const char *ifname, int attach)
                }
        }
 
                }
        }
 
-       ctrl_conn = wpa_ctrl_open(cfile);
+       ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir);
        if (ctrl_conn == NULL) {
                os_free(cfile);
                return -1;
        }
 
        if (attach && interactive)
        if (ctrl_conn == NULL) {
                os_free(cfile);
                return -1;
        }
 
        if (attach && interactive)
-               mon_conn = wpa_ctrl_open(cfile);
+               mon_conn = wpa_ctrl_open2(cfile, client_socket_dir);
        else
                mon_conn = NULL;
        os_free(cfile);
        else
                mon_conn = NULL;
        os_free(cfile);
@@ -502,6 +518,10 @@ static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
                return wpa_ctrl_command(ctrl, "STATUS-WPS");
        if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
                return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
                return wpa_ctrl_command(ctrl, "STATUS-WPS");
        if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
                return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
+#ifdef ANDROID
+       if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
+               return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
+#endif /* ANDROID */
        return wpa_ctrl_command(ctrl, "STATUS");
 }
 
        return wpa_ctrl_command(ctrl, "STATUS");
 }
 
@@ -618,6 +638,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
                "eapol_version", "ap_scan", "bgscan",
 #ifdef CONFIG_MESH
                "user_mpm", "max_peer_links", "mesh_max_inactivity",
                "eapol_version", "ap_scan", "bgscan",
 #ifdef CONFIG_MESH
                "user_mpm", "max_peer_links", "mesh_max_inactivity",
+               "dot11RSNASAERetransPeriod",
 #endif /* CONFIG_MESH */
                "disable_scan_offload", "fast_reauth", "opensc_engine_path",
                "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
 #endif /* CONFIG_MESH */
                "disable_scan_offload", "fast_reauth", "opensc_engine_path",
                "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
@@ -662,7 +683,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
                "tdls_external_control", "osu_dir", "wowlan_triggers",
                "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
                "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
                "tdls_external_control", "osu_dir", "wowlan_triggers",
                "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
                "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
-               "reassoc_same_bss_optim"
+               "reassoc_same_bss_optim", "wps_priority"
        };
        int i, num_fields = ARRAY_SIZE(fields);
 
        };
        int i, num_fields = ARRAY_SIZE(fields);
 
@@ -967,12 +988,12 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
                res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
                                  argv[0], argv[1]);
        else if (argc == 5 || argc == 6) {
                res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
                                  argv[0], argv[1]);
        else if (argc == 5 || argc == 6) {
-               char ssid_hex[2 * 32 + 1];
+               char ssid_hex[2 * SSID_MAX_LEN + 1];
                char key_hex[2 * 64 + 1];
                int i;
 
                ssid_hex[0] = '\0';
                char key_hex[2 * 64 + 1];
                int i;
 
                ssid_hex[0] = '\0';
-               for (i = 0; i < 32; i++) {
+               for (i = 0; i < SSID_MAX_LEN; i++) {
                        if (argv[2][i] == '\0')
                                break;
                        os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
                        if (argv[2][i] == '\0')
                                break;
                        os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
@@ -1096,12 +1117,12 @@ static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
        int res;
 
        if (argc == 5 || argc == 6) {
        int res;
 
        if (argc == 5 || argc == 6) {
-               char ssid_hex[2 * 32 + 1];
+               char ssid_hex[2 * SSID_MAX_LEN + 1];
                char key_hex[2 * 64 + 1];
                int i;
 
                ssid_hex[0] = '\0';
                char key_hex[2 * 64 + 1];
                int i;
 
                ssid_hex[0] = '\0';
-               for (i = 0; i < 32; i++) {
+               for (i = 0; i < SSID_MAX_LEN; i++) {
                        if (argv[2][i] == '\0')
                                break;
                        os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
                        if (argv[2][i] == '\0')
                                break;
                        os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
@@ -1456,7 +1477,8 @@ static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
                                   char *argv[])
 {
        int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
                                   char *argv[])
 {
        int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
-       update_networks(ctrl);
+       if (interactive)
+               update_networks(ctrl);
        return res;
 }
 
        return res;
 }
 
@@ -1465,7 +1487,8 @@ static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
                                      char *argv[])
 {
        int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
                                      char *argv[])
 {
        int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
-       update_networks(ctrl);
+       if (interactive)
+               update_networks(ctrl);
        return res;
 }
 
        return res;
 }
 
@@ -1531,7 +1554,7 @@ static const char *network_fields[] = {
        "ssid", "scan_ssid", "bssid", "bssid_blacklist",
        "bssid_whitelist", "psk", "proto", "key_mgmt",
        "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
        "ssid", "scan_ssid", "bssid", "bssid_blacklist",
        "bssid_whitelist", "psk", "proto", "key_mgmt",
        "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
-       "freq_list",
+       "freq_list", "max_oper_chwidth",
 #ifdef IEEE8021X_EAPOL
        "eap", "identity", "anonymous_identity", "password", "ca_cert",
        "ca_path", "client_cert", "private_key", "private_key_passwd",
 #ifdef IEEE8021X_EAPOL
        "eap", "identity", "anonymous_identity", "password", "ca_cert",
        "ca_path", "client_cert", "private_key", "private_key_passwd",
@@ -1589,7 +1612,7 @@ static const char *network_fields[] = {
 #ifdef CONFIG_HS20
        "update_identifier",
 #endif /* CONFIG_HS20 */
 #ifdef CONFIG_HS20
        "update_identifier",
 #endif /* CONFIG_HS20 */
-       "mac_addr"
+       "mac_addr", "pbss", "wps_disabled"
 };
 
 
 };
 
 
@@ -1747,6 +1770,13 @@ static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
 }
 
 
 }
 
 
+static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
+                                 char *argv[])
+{
+       return wpa_ctrl_command(ctrl, "ABORT_SCAN");
+}
+
+
 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
@@ -1849,14 +1879,15 @@ static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
 
        /*
         * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
 
        /*
         * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
-        * <driver_param>TAB<bridge_name>[TAB<create>]
+        * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
         */
        res = os_snprintf(cmd, sizeof(cmd),
         */
        res = os_snprintf(cmd, sizeof(cmd),
-                         "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
+                         "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
                          argv[0],
                          argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
                          argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
                          argv[0],
                          argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
                          argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
-                         argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
+                         argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
+                         argc > 7 ? argv[7] : "");
        if (os_snprintf_error(sizeof(cmd), res))
                return -1;
        cmd[sizeof(cmd) - 1] = '\0';
        if (os_snprintf_error(sizeof(cmd), res))
                return -1;
        cmd[sizeof(cmd) - 1] = '\0';
@@ -1896,6 +1927,12 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
                printf("Not connected to hostapd - command dropped.\n");
                return -1;
        }
                printf("Not connected to hostapd - command dropped.\n");
                return -1;
        }
+       if (ifname_prefix) {
+               os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
+                           ifname_prefix, cmd);
+               buf[sizeof(buf) - 1] = '\0';
+               cmd = buf;
+       }
        len = sizeof(buf) - 1;
        ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
                               wpa_cli_msg_cb);
        len = sizeof(buf) - 1;
        ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
                               wpa_cli_msg_cb);
@@ -2005,6 +2042,20 @@ static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
 }
 
        return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
 }
 
+
+static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
+                                       char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
+                                    char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
+}
+
 #endif /* CONFIG_MESH */
 
 
 #endif /* CONFIG_MESH */
 
 
@@ -2124,6 +2175,13 @@ static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
 }
 
 
 }
 
 
+static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
+                                       char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
+}
+
+
 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
                                     char *argv[])
 {
 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
                                     char *argv[])
 {
@@ -2460,6 +2518,27 @@ static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
 }
 
        return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
 }
 
+
+static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
+                                      char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
+}
+
+
+static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
+                                      char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
+                                         char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
+}
+
 #endif /* CONFIG_P2P */
 
 #ifdef CONFIG_WIFI_DISPLAY
 #endif /* CONFIG_P2P */
 
 #ifdef CONFIG_WIFI_DISPLAY
@@ -2653,6 +2732,13 @@ static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
 }
 
 
 }
 
 
+static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
+                                       char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
+}
+
+
 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
                                    char *argv[])
 {
 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
                                    char *argv[])
 {
@@ -2695,6 +2781,13 @@ static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
 }
 
 
 }
 
 
+static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
+                                  char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
+}
+
+
 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
                                   char *argv[])
 {
 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
                                   char *argv[])
 {
@@ -2792,6 +2885,13 @@ static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
 }
 
 
 }
 
 
+static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
+                                         char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
+}
+
+
 enum wpa_cli_cmd_flags {
        cli_cmd_flag_none               = 0x00,
        cli_cmd_flag_sensitive          = 0x01
 enum wpa_cli_cmd_flags {
        cli_cmd_flag_none               = 0x00,
        cli_cmd_flag_sensitive          = 0x01
@@ -2805,7 +2905,7 @@ struct wpa_cli_cmd {
        const char *usage;
 };
 
        const char *usage;
 };
 
-static struct wpa_cli_cmd wpa_cli_commands[] = {
+static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "status", wpa_cli_cmd_status, NULL,
          cli_cmd_flag_none,
          "[verbose] = get current WPA/EAPOL/EAP status" },
        { "status", wpa_cli_cmd_status, NULL,
          cli_cmd_flag_none,
          "[verbose] = get current WPA/EAPOL/EAP status" },
@@ -2970,6 +3070,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "scan_results", wpa_cli_cmd_scan_results, NULL,
          cli_cmd_flag_none,
          "= get latest scan results" },
        { "scan_results", wpa_cli_cmd_scan_results, NULL,
          cli_cmd_flag_none,
          "= get latest scan results" },
+       { "abort_scan", wpa_cli_cmd_abort_scan, NULL,
+         cli_cmd_flag_none,
+         "= request ongoing scan to be aborted" },
        { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
          cli_cmd_flag_none,
          "<<idx> | <bssid>> = get detailed scan result info" },
        { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
          cli_cmd_flag_none,
          "<<idx> | <bssid>> = get detailed scan result info" },
@@ -2986,8 +3089,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "interface_add", wpa_cli_cmd_interface_add, NULL,
          cli_cmd_flag_none,
          "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
        { "interface_add", wpa_cli_cmd_interface_add, NULL,
          cli_cmd_flag_none,
          "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
-         "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
-         "  are optional" },
+         "  <bridge_name> <create> <type> = adds new interface, all "
+         "parameters but\n"
+         "  <ifname> are optional. Supported types are station ('sta') and "
+         "AP ('ap')" },
        { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = removes the interface" },
        { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = removes the interface" },
@@ -3126,6 +3231,12 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = Remove mesh group interface" },
        { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = Remove mesh group interface" },
+       { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
+         cli_cmd_flag_none,
+         "<addr> = Remove a mesh peer" },
+       { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
+         cli_cmd_flag_none,
+         "<addr> [duration=<seconds>] = Add a mesh peer" },
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
@@ -3149,6 +3260,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
          "<ifname> = remove P2P group interface (terminate group if GO)" },
        { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
          "[ht40] = add a new P2P group (local end as GO)" },
          "<ifname> = remove P2P group interface (terminate group if GO)" },
        { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
          "[ht40] = add a new P2P group (local end as GO)" },
+       { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
+         cli_cmd_flag_none,
+         "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
        { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<addr> <method> = request provisioning discovery" },
        { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<addr> <method> = request provisioning discovery" },
@@ -3217,6 +3331,18 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<address|iface=address> = remove a peer from all groups" },
        { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<address|iface=address> = remove a peer from all groups" },
+       { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
+         cli_cmd_flag_none,
+         "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
+       { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
+         cli_cmd_flag_none,
+         "<frame id> = get vendor specific IE(s) to frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
+       { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
+         cli_cmd_flag_none,
+         "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_WIFI_DISPLAY
        { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_WIFI_DISPLAY
        { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
@@ -3280,6 +3406,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
          cli_cmd_flag_none,
          "<addr> = tear down TDLS with <addr>" },
        { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
          cli_cmd_flag_none,
          "<addr> = tear down TDLS with <addr>" },
+       { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
+         cli_cmd_flag_none,
+         "<addr> = TDLS link status with <addr>" },
        { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
          cli_cmd_flag_none,
          "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
        { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
          cli_cmd_flag_none,
          "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
@@ -3302,6 +3431,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
          cli_cmd_flag_none,
          "= get signal parameters" },
        { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
          cli_cmd_flag_none,
          "= get signal parameters" },
+       { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
+         cli_cmd_flag_none,
+         "= set signal monitor parameters" },
        { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
          cli_cmd_flag_none,
          "= get TX/RX packet counters" },
        { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
          cli_cmd_flag_none,
          "= get TX/RX packet counters" },
@@ -3316,7 +3448,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
          "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
        { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
        { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
          "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
        { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
-         "<query reason> = Send BSS Transition Management Query" },
+         "<query reason> [list] = Send BSS Transition Management Query" },
 #endif /* CONFIG_WNM */
        { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
          "<params..> = Sent unprocessed command" },
 #endif /* CONFIG_WNM */
        { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
          "<params..> = Sent unprocessed command" },
@@ -3333,8 +3465,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        },
        { "neighbor_rep_request",
          wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
        },
        { "neighbor_rep_request",
          wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
-         "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
-         "(with optional given SSID, default: current SSID)"
+         "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
        },
        { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
          "= flush ERP keys" },
        },
        { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
          "= flush ERP keys" },
@@ -3343,6 +3474,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
          "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
          "mask=mac-address-mask] = scan MAC randomization"
        },
          "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
          "mask=mac-address-mask] = scan MAC randomization"
        },
+       { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
+         cli_cmd_flag_none,
+         "<interface type> = retrieve preferred freq list for the specified interface type" },
        { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
 };
 
        { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
 };
 
@@ -3350,7 +3484,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
 /*
  * Prints command usage, lines are padded with the specified string.
  */
 /*
  * Prints command usage, lines are padded with the specified string.
  */
-static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
+static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
 {
        char c;
        size_t n;
 {
        char c;
        size_t n;
@@ -3488,7 +3622,7 @@ static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
 
 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
 
 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
-       struct wpa_cli_cmd *cmd, *match = NULL;
+       const struct wpa_cli_cmd *cmd, *match = NULL;
        int count;
        int ret = 0;
 
        int count;
        int ret = 0;
 
@@ -3554,6 +3688,10 @@ static int wpa_cli_exec(const char *program, const char *arg1,
        size_t len;
        int res;
 
        size_t len;
        int res;
 
+       /* If no interface is specified, set the global */
+       if (!arg1)
+               arg1 = "global";
+
        len = os_strlen(arg1) + os_strlen(arg2) + 2;
        arg = os_malloc(len);
        if (arg == NULL)
        len = os_strlen(arg1) + os_strlen(arg2) + 2;
        arg = os_malloc(len);
        if (arg == NULL)
@@ -3573,6 +3711,9 @@ static void wpa_cli_action_process(const char *msg)
        const char *ifname = ctrl_ifname;
        char ifname_buf[100];
 
        const char *ifname = ctrl_ifname;
        char ifname_buf[100];
 
+       if (eloop_terminated())
+               return;
+
        pos = msg;
        if (os_strncmp(pos, "IFNAME=", 7) == 0) {
                const char *end;
        pos = msg;
        if (os_strncmp(pos, "IFNAME=", 7) == 0) {
                const char *end;
@@ -3636,6 +3777,10 @@ static void wpa_cli_action_process(const char *msg)
                        wpa_cli_connected = 0;
                        wpa_cli_exec(action_file, ifname, "DISCONNECTED");
                }
                        wpa_cli_connected = 0;
                        wpa_cli_exec(action_file, ifname, "DISCONNECTED");
                }
+       } else if (str_match(pos, AP_EVENT_ENABLED)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
+       } else if (str_match(pos, AP_EVENT_DISABLED)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, MESH_GROUP_STARTED)) {
                wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, MESH_GROUP_REMOVED)) {
        } else if (str_match(pos, MESH_GROUP_STARTED)) {
                wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, MESH_GROUP_REMOVED)) {
@@ -4044,7 +4189,7 @@ static void try_connection(void *eloop_ctx, void *timeout_ctx)
        if (ctrl_ifname == NULL)
                ctrl_ifname = wpa_cli_get_default_ifname();
 
        if (ctrl_ifname == NULL)
                ctrl_ifname = wpa_cli_get_default_ifname();
 
-       if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
+       if (wpa_cli_open_connection(ctrl_ifname, 1)) {
                if (!warning_displayed) {
                        printf("Could not connect to wpa_supplicant: "
                               "%s - re-trying\n",
                if (!warning_displayed) {
                        printf("Could not connect to wpa_supplicant: "
                               "%s - re-trying\n",
@@ -4087,45 +4232,49 @@ static void wpa_cli_interactive(void)
 }
 
 
 }
 
 
+static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_ctrl *ctrl = eloop_ctx;
+       char buf[256];
+       size_t len;
+
+       /* verify that connection is still working */
+       len = sizeof(buf) - 1;
+       if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
+                            wpa_cli_action_cb) < 0 ||
+           len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
+               printf("wpa_supplicant did not reply to PING command - exiting\n");
+               eloop_terminate();
+               return;
+       }
+       eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
+                              ctrl, NULL);
+}
+
+
+static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
+{
+       struct wpa_ctrl *ctrl = eloop_ctx;
+
+       wpa_cli_recv_pending(ctrl, 1);
+}
+
+
 static void wpa_cli_action(struct wpa_ctrl *ctrl)
 {
 #ifdef CONFIG_ANSI_C_EXTRA
        /* TODO: ANSI C version(?) */
        printf("Action processing not supported in ANSI C build.\n");
 #else /* CONFIG_ANSI_C_EXTRA */
 static void wpa_cli_action(struct wpa_ctrl *ctrl)
 {
 #ifdef CONFIG_ANSI_C_EXTRA
        /* TODO: ANSI C version(?) */
        printf("Action processing not supported in ANSI C build.\n");
 #else /* CONFIG_ANSI_C_EXTRA */
-       fd_set rfds;
-       int fd, res;
-       struct timeval tv;
-       char buf[256]; /* note: large enough to fit in unsolicited messages */
-       size_t len;
+       int fd;
 
        fd = wpa_ctrl_get_fd(ctrl);
 
        fd = wpa_ctrl_get_fd(ctrl);
-
-       while (!wpa_cli_quit) {
-               FD_ZERO(&rfds);
-               FD_SET(fd, &rfds);
-               tv.tv_sec = ping_interval;
-               tv.tv_usec = 0;
-               res = select(fd + 1, &rfds, NULL, NULL, &tv);
-               if (res < 0 && errno != EINTR) {
-                       perror("select");
-                       break;
-               }
-
-               if (FD_ISSET(fd, &rfds))
-                       wpa_cli_recv_pending(ctrl, 1);
-               else {
-                       /* verify that connection is still working */
-                       len = sizeof(buf) - 1;
-                       if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
-                                            wpa_cli_action_cb) < 0 ||
-                           len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
-                               printf("wpa_supplicant did not reply to PING "
-                                      "command - exiting\n");
-                               break;
-                       }
-               }
-       }
+       eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
+                              ctrl, NULL);
+       eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
+       eloop_run();
+       eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
+       eloop_unregister_read_sock(fd);
 #endif /* CONFIG_ANSI_C_EXTRA */
 }
 
 #endif /* CONFIG_ANSI_C_EXTRA */
 }
 
@@ -4150,18 +4299,17 @@ static char * wpa_cli_get_default_ifname(void)
 {
        char *ifname = NULL;
 
 {
        char *ifname = NULL;
 
+#ifdef ANDROID
+       char ifprop[PROPERTY_VALUE_MAX];
+       if (property_get("wifi.interface", ifprop, NULL) != 0) {
+               ifname = os_strdup(ifprop);
+               printf("Using interface '%s'\n", ifname ? ifname : "N/A");
+       }
+#else /* ANDROID */
 #ifdef CONFIG_CTRL_IFACE_UNIX
        struct dirent *dent;
        DIR *dir = opendir(ctrl_iface_dir);
        if (!dir) {
 #ifdef CONFIG_CTRL_IFACE_UNIX
        struct dirent *dent;
        DIR *dir = opendir(ctrl_iface_dir);
        if (!dir) {
-#ifdef ANDROID
-               char ifprop[PROPERTY_VALUE_MAX];
-               if (property_get("wifi.interface", ifprop, NULL) != 0) {
-                       ifname = os_strdup(ifprop);
-                       printf("Using interface '%s'\n", ifname);
-                       return ifname;
-               }
-#endif /* ANDROID */
                return NULL;
        }
        while ((dent = readdir(dir))) {
                return NULL;
        }
        while ((dent = readdir(dir))) {
@@ -4205,6 +4353,7 @@ static char * wpa_cli_get_default_ifname(void)
        }
        wpa_ctrl_close(ctrl);
 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
        }
        wpa_ctrl_close(ctrl);
 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
+#endif /* ANDROID */
 
        return ifname;
 }
 
        return ifname;
 }
@@ -4221,7 +4370,7 @@ int main(int argc, char *argv[])
                return -1;
 
        for (;;) {
                return -1;
 
        for (;;) {
-               c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
+               c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v");
                if (c < 0)
                        break;
                switch (c) {
                if (c < 0)
                        break;
                switch (c) {
@@ -4253,6 +4402,9 @@ int main(int argc, char *argv[])
                case 'P':
                        pid_file = optarg;
                        break;
                case 'P':
                        pid_file = optarg;
                        break;
+               case 's':
+                       client_socket_dir = optarg;
+                       break;
                default:
                        usage();
                        return -1;
                default:
                        usage();
                        return -1;
@@ -4326,7 +4478,7 @@ int main(int argc, char *argv[])
                        }
                }
 
                        }
                }
 
-               if (daemonize && os_daemonize(pid_file))
+               if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
                        return -1;
 
                if (action_file)
                        return -1;
 
                if (action_file)