18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / Control interface (shared code for all backends)
304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/version.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "common/ieee802_11_common.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/preauth.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet/l2_packet.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ibss_rsn.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h"
3204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h"
3361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "wifi_display.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h"
381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "interworking.h"
39e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt#include "blacklist.h"
401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "wpas_glue.h"
4104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "autoscan.h"
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern struct wpa_driver_ops *wpa_drivers[];
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_list(struct wpa_global *global,
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    char *buf, int len);
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  char *buf, int len);
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int pno_start(struct wpa_supplicant *wpa_s)
521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t i, num_ssid;
551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *ssid;
561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_driver_scan_params params;
571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->pno)
591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_memset(&params, 0, sizeof(params));
621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	num_ssid = 0;
641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid = wpa_s->conf->ssid;
651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	while (ssid) {
6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, ssid))
671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			num_ssid++;
681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ssid = ssid->next;
691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		num_ssid = WPAS_MAX_SCAN_SSIDS;
741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (num_ssid == 0) {
771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) *
821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					num_ssid);
831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (params.filter_ssids == NULL)
841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	i = 0;
861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid = wpa_s->conf->ssid;
871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	while (ssid) {
8804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, ssid)) {
891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.ssids[i].ssid = ssid->ssid;
901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.ssids[i].ssid_len = ssid->ssid_len;
911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.num_ssids++;
921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  ssid->ssid_len);
941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.filter_ssids[i].ssid_len = ssid->ssid_len;
951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.num_filter_ssids++;
961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			i++;
971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (i == num_ssid)
981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				break;
991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ssid = ssid->next;
1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->conf->filter_rssi)
10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		params.filter_rssi = wpa_s->conf->filter_rssi;
10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = wpa_drv_sched_scan(wpa_s, &params, 10 * 1000);
1071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(params.filter_ssids);
1081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret == 0)
1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->pno = 1;
1101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return ret;
1111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
1121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int pno_stop(struct wpa_supplicant *wpa_s)
1151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
1161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->pno) {
1171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->pno = 0;
1181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return wpa_drv_stop_sched_scan(wpa_s);
1191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
1201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
1211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
1221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
12504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
12604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *pos;
12704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 addr[ETH_ALEN], *filter = NULL, *n;
12804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t count = 0;
12904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos = val;
13104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (pos) {
13204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (*pos == '\0')
13304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
13404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (hwaddr_aton(pos, addr)) {
13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_free(filter);
13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		n = os_realloc_array(filter, count + 1, ETH_ALEN);
13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (n == NULL) {
14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_free(filter);
14104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
14204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
14304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		filter = n;
14404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN);
14504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		count++;
14604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
14704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = os_strchr(pos, ' ');
14804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (pos)
14904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
15004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
15104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
15204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN);
15304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(wpa_s->bssid_filter);
15404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->bssid_filter = filter;
15504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->bssid_filter_count = count;
15604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
15704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
15804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
15904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
16004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 char *cmd)
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = 0;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = os_strchr(cmd, ' ');
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*value++ = '\0';
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_configure(wpa_s->eapol,
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   atoi(value), -1, -1, -1);
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_configure(wpa_s->eapol,
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   -1, atoi(value), -1, -1);
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_configure(wpa_s->eapol,
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   -1, -1, atoi(value), -1);
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_configure(wpa_s->eapol,
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   -1, -1, -1, atoi(value));
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     atoi(value)))
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   0) {
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     atoi(value)))
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->wps_fragment_size = atoi(value);
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_TESTING
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		long int val;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		val = strtol(value, NULL, 0);
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (val < 0 || val > 0xff) {
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "WPS: Invalid "
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "wps_version_number %ld", val);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wps_version_number = val;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "version %u.%u",
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (wps_version_number & 0xf0) >> 4,
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   wps_version_number & 0x0f);
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_testing_dummy_cred = atoi(value);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wps_testing_dummy_cred);
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_TESTING */
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "ampdu") == 0) {
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS_TESTING
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "tdls_testing") == 0) {
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		extern unsigned int tdls_testing;
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tdls_testing = strtol(value, NULL, 0);
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS_TESTING */
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcasecmp(cmd, "tdls_disabled") == 0) {
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int disabled = atoi(value);
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled);
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (disabled) {
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0)
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = -1;
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0)
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_tdls_enable(wpa_s->wpa, !disabled);
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strcasecmp(cmd, "pno") == 0) {
2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (atoi(value))
2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = pno_start(wpa_s);
2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else
2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = pno_stop(wpa_s);
24404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcasecmp(cmd, "radio_disabled") == 0) {
24504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int disabled = atoi(value);
24604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_drv_radio_disable(wpa_s, disabled) < 0)
24704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			ret = -1;
24804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else if (disabled)
24904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
25004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcasecmp(cmd, "uapsd") == 0) {
25104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (os_strcmp(value, "disable") == 0)
25204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->set_sta_uapsd = 0;
25304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else {
25404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			int be, bk, vi, vo;
25504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			char *pos;
25604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			/* format: BE,BK,VI,VO;max SP Length */
25704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			be = atoi(value);
25804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos = os_strchr(value, ',');
25904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (pos == NULL)
26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return -1;
26104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
26204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bk = atoi(pos);
26304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos = os_strchr(pos, ',');
26404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (pos == NULL)
26504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return -1;
26604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
26704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			vi = atoi(pos);
26804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos = os_strchr(pos, ',');
26904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (pos == NULL)
27004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return -1;
27104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
27204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			vo = atoi(pos);
27304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			/* ignore max SP Length for now */
27404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
27504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->set_sta_uapsd = 1;
27604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->sta_uapsd = 0;
27704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (be)
27804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->sta_uapsd |= BIT(0);
27904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (bk)
28004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->sta_uapsd |= BIT(1);
28104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (vi)
28204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->sta_uapsd |= BIT(2);
28304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (vo)
28404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->sta_uapsd |= BIT(3);
28504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
28621d6bc8c6acd01cd2c4b2abdaf1b0ff58e25aacdJouni Malinen	} else if (os_strcasecmp(cmd, "ps") == 0) {
28721d6bc8c6acd01cd2c4b2abdaf1b0ff58e25aacdJouni Malinen		ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
28861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
28961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strcasecmp(cmd, "wifi_display") == 0) {
29061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wifi_display_enable(wpa_s->global, !!atoi(value));
29161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
29204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcasecmp(cmd, "bssid_filter") == 0) {
29304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = set_bssid_filter(wpa_s, value);
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		value[-1] = '=';
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == 0)
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_update_config(wpa_s);
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 char *cmd, char *buf, size_t buflen)
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3086f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt	int res = -1;
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "version") == 0) {
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res = os_snprintf(buf, buflen, "%s", VERSION_STR);
3146f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt	} else if (os_strcasecmp(cmd, "country") == 0) {
3156f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt		if (wpa_s->conf->country[0] && wpa_s->conf->country[1])
3166f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt			res = os_snprintf(buf, buflen, "%c%c",
3176f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt					  wpa_s->conf->country[0],
3186f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt					  wpa_s->conf->country[1]);
31961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
32061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strcasecmp(cmd, "wifi_display") == 0) {
32161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		res = os_snprintf(buf, buflen, "%d",
32261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				  wpa_s->global->wifi_display);
32361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (res < 0 || (unsigned int) res >= buflen)
32461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return -1;
32561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return res;
32661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3296f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt	if (res < 0 || (unsigned int) res >= buflen)
3306f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt		return -1;
3316f3bdcf8c96ad38245e927ac1afe28b98621a4e5Dmitry Shmidt	return res;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     char *addr)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, bssid)) {
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "'%s'", addr);
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_preauth_deinit(wpa_s->wpa);
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* MLME-STKSTART.request(peer) */
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_stkstart(
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer)) {
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(peer));
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_sm_stkstart(wpa_s->wpa, peer);
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_tdls_discover(
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer)) {
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(peer));
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_tdls_is_external_setup(wpa_s->wpa))
3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else
3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return ret;
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_tdls_setup(
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer)) {
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(peer));
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpa_tdls_reneg(wpa_s->wpa, peer);
4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret) {
4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_tdls_is_external_setup(wpa_s->wpa))
4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = wpa_tdls_start(wpa_s->wpa, peer);
4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else
4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_tdls_teardown(
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer)) {
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(peer));
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpa_tdls_teardown_link(wpa_s->wpa, peer,
4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_ft_ds(
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 target_ap[ETH_ALEN];
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *mdie;
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, target_ap)) {
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = wpa_bss_get_bssid(wpa_s, target_ap);
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss)
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		mdie = NULL;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     char *cmd)
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN], *_bssid = bssid;
48575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#ifdef CONFIG_P2P
48675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 p2p_dev_addr[ETH_ALEN];
48775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#endif /* CONFIG_P2P */
48875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#ifdef CONFIG_AP
48975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 *_p2p_dev_addr = NULL;
49075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#endif /* CONFIG_AP */
4911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
492a7534b9cdb4f9c2b9ca56761119b0505626f03d6Irfan Sheriff	if (cmd == NULL || os_strcmp(cmd, "any") == 0 || cmd[0] == '\0') {
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		_bssid = NULL;
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "P2P Device Address '%s'",
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   cmd + 13);
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		_p2p_dev_addr = p2p_dev_addr;
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (hwaddr_aton(cmd, bssid)) {
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   cmd);
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface)
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_start_pbc(wpa_s, _bssid, 0);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     char *cmd, char *buf,
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     size_t buflen)
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN], *_bssid = bssid;
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pin;
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = os_strchr(cmd, ' ');
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin)
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pin++ = '\0';
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "any") == 0)
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		_bssid = NULL;
5331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else if (os_strcmp(cmd, "get") == 0) {
5341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret = wps_generate_pin();
5351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		goto done;
5361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (hwaddr_aton(cmd, bssid)) {
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   cmd);
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface)
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 buf, buflen);
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin) {
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 DEV_PW_DEFAULT);
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0)
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(buf, buflen, "%s", pin);
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || (size_t) ret >= buflen)
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0)
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdone:
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Return the generated PIN */
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(buf, buflen, "%08d", ret);
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || (size_t) ret >= buflen)
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_check_pin(
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char pin[9];
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      (u8 *) cmd, os_strlen(cmd));
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (pos = cmd, len = 0; *pos != '\0'; pos++) {
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos < '0' || *pos > '9')
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin[len++] = *pos;
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len == 9) {
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len != 4 && len != 8) {
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin[len] = '\0';
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len == 8) {
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		unsigned int pin_val;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin_val = atoi(pin);
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wps_pin_valid(pin_val)) {
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret < 0 || (size_t) ret >= buflen)
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return ret;
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(buf, buflen, "%s", pin);
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || (size_t) ret >= buflen)
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_OOB
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     char *cmd)
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *path, *method, *name;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	path = os_strchr(cmd, ' ');
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (path == NULL)
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*path++ = '\0';
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	method = os_strchr(path, ' ');
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (method == NULL)
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*method++ = '\0';
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	name = os_strchr(method, ' ');
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (name != NULL)
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*name++ = '\0';
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_OOB */
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
64304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
64404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s,
64504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     char *cmd)
64604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
64704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 bssid[ETH_ALEN], *_bssid = bssid;
64804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
64904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (cmd == NULL || cmd[0] == '\0')
65004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		_bssid = NULL;
65104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (hwaddr_aton(cmd, bssid))
65204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
65304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
65404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_wps_start_nfc(wpa_s, _bssid);
65504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
65604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
65704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
65804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_nfc_token(
65904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
66004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
66104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ndef;
66204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *buf;
66304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int res;
66404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
66504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strcmp(cmd, "WPS") == 0)
66604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ndef = 0;
66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (os_strcmp(cmd, "NDEF") == 0)
66804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ndef = 1;
66904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
67004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
67104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
67204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf = wpas_wps_nfc_token(wpa_s, ndef);
67304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (buf == NULL)
67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
67504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
67604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
67704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpabuf_len(buf));
67804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reply[res++] = '\n';
67904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reply[res] = '\0';
68004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
68104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(buf);
68204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
68304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return res;
68404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
68504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
68604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
68704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_nfc_tag_read(
68804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s, char *pos)
68904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
69004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
69104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *buf;
69204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ret;
69304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
69404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = os_strlen(pos);
69504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len & 0x01)
69604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
69704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len /= 2;
69804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
69904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf = wpabuf_alloc(len);
70004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (buf == NULL)
70104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
70204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
70304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpabuf_free(buf);
70404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
70504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
70604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
70704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = wpas_wps_nfc_tag_read(wpa_s, buf);
70804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(buf);
70904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return ret;
71104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
71204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
71404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     char *cmd)
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pin;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_ssid;
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_auth;
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_encr;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_key;
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_new_ap_settings ap;
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = os_strchr(cmd, ' ');
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin == NULL)
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pin++ = '\0';
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(cmd, bssid)) {
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   cmd);
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_ssid = os_strchr(pin, ' ');
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_ssid == NULL)
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_ssid++ = '\0';
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_auth = os_strchr(new_ssid, ' ');
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_auth == NULL)
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_auth++ = '\0';
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_encr = os_strchr(new_auth, ' ');
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_encr == NULL)
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_encr++ = '\0';
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_key = os_strchr(new_encr, ' ');
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_key == NULL)
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_key++ = '\0';
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&ap, 0, sizeof(ap));
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.ssid_hex = new_ssid;
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.auth = new_auth;
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.encr = new_encr;
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.key_hex = new_key;
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						char *cmd, char *buf,
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						size_t buflen)
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int timeout = 300;
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *pin_txt;
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos)
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos++ = '\0';
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "disable") == 0) {
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_wps_ap_pin_disable(wpa_s);
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return os_snprintf(buf, buflen, "OK\n");
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "random") == 0) {
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = atoi(pos);
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pin_txt == NULL)
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return os_snprintf(buf, buflen, "%s", pin_txt);
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "get") == 0) {
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin_txt = wpas_wps_ap_pin_get(wpa_s);
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pin_txt == NULL)
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return os_snprintf(buf, buflen, "%s", pin_txt);
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "set") == 0) {
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *pin;
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin = pos;
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, ' ');
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos) {
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = atoi(pos);
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strlen(pin) > buflen)
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return os_snprintf(buf, buflen, "%s", pin);
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_ER
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						char *cmd)
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *uuid = cmd, *pin, *pos;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr_buf[ETH_ALEN], *addr = NULL;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = os_strchr(uuid, ' ');
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin == NULL)
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pin++ = '\0';
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(pin, ' ');
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos) {
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos++ = '\0';
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(pos, addr_buf) == 0)
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			addr = addr_buf;
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  char *cmd)
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *uuid = cmd, *pin;
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = os_strchr(uuid, ' ');
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin == NULL)
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pin++ = '\0';
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_er_learn(wpa_s, uuid, pin);
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_er_set_config(
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *uuid = cmd, *id;
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = os_strchr(uuid, ' ');
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (id == NULL)
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*id++ = '\0';
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_er_config(
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pin;
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_ssid;
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_auth;
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_encr;
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *new_key;
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_new_ap_settings ap;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = os_strchr(cmd, ' ');
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin == NULL)
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pin++ = '\0';
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_ssid = os_strchr(pin, ' ');
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_ssid == NULL)
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_ssid++ = '\0';
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_auth = os_strchr(new_ssid, ' ');
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_auth == NULL)
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_auth++ = '\0';
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_encr = os_strchr(new_auth, ' ');
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_encr == NULL)
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_encr++ = '\0';
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_key = os_strchr(new_encr, ' ');
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_key == NULL)
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*new_key++ = '\0';
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&ap, 0, sizeof(ap));
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.ssid_hex = new_ssid;
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.auth = new_auth;
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.encr = new_encr;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ap.key_hex = new_key;
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
91204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
91304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
91404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
91504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
91604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
91704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
91804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ndef;
91904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *buf;
92004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int res;
92104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *uuid;
92204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
92304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	uuid = os_strchr(cmd, ' ');
92404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (uuid == NULL)
92504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
92604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	*uuid++ = '\0';
92704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
92804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strcmp(cmd, "WPS") == 0)
92904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ndef = 0;
93004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (os_strcmp(cmd, "NDEF") == 0)
93104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ndef = 1;
93204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
93304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
93404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
93504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid);
93604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (buf == NULL)
93704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
93804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
93904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
94004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpabuf_len(buf));
94104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reply[res++] = '\n';
94204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reply[res] = '\0';
94304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
94404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(buf);
94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return res;
94704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
94804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_ER */
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_ibss_rsn(
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *addr)
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer)) {
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(peer));
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ibss_rsn_start(wpa_s->ibss_rsn, peer);
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
9751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      char *rsp)
9761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
9771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef IEEE8021X_EAPOL
9781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char *pos, *id_pos;
9791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int id;
9801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *ssid;
9811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
9821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = os_strchr(rsp, '-');
9831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos == NULL)
9841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
9851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*pos++ = '\0';
9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	id_pos = pos;
9871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = os_strchr(pos, ':');
9881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos == NULL)
9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*pos++ = '\0';
9911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	id = atoi(id_pos);
9921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
9931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      (u8 *) pos, os_strlen(pos));
9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid == NULL) {
9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "to update", id);
10001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
10011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
10021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp,
10041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 pos);
10051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#else /* IEEE8021X_EAPOL */
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    const char *params,
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    char *buf, size_t buflen)
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end, tmp[30];
10171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int res, verbose, wps, ret;
101844da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	verbose = os_strcmp(params, "-VERBOSE") == 0;
10201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wps = os_strcmp(params, "-WPS") == 0;
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + buflen;
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ssid *ssid = wpa_s->current_ssid;
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  MAC2STR(wpa_s->bssid));
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid) {
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *_ssid = ssid->ssid;
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			size_t ssid_len = ssid->ssid_len;
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 ssid_buf[MAX_SSID_LEN];
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid_len == 0) {
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (_res < 0)
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					ssid_len = 0;
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				else
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					ssid_len = _res;
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				_ssid = ssid_buf;
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  wpa_ssid_txt(_ssid, ssid_len),
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  ssid->id);
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return pos - buf;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos += ret;
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (wps && ssid->passphrase &&
10501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    wpa_key_mgmt_wpa_psk(ssid->key_mgmt) &&
10511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    (ssid->mode == WPAS_MODE_AP ||
10521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			     ssid->mode == WPAS_MODE_P2P_GO)) {
10531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				ret = os_snprintf(pos, end - pos,
10541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  "passphrase=%s\n",
10551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  ssid->passphrase);
10561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (ret < 0 || ret >= end - pos)
10571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					return pos - buf;
10581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				pos += ret;
10591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->id_str) {
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "id_str=%s\n",
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  ssid->id_str);
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (ret < 0 || ret >= end - pos)
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					return pos - buf;
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos += ret;
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			switch (ssid->mode) {
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			case WPAS_MODE_INFRA:
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "mode=station\n");
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			case WPAS_MODE_IBSS:
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "mode=IBSS\n");
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			case WPAS_MODE_AP:
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "mode=AP\n");
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			case WPAS_MODE_P2P_GO:
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "mode=P2P GO\n");
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			case WPAS_MODE_P2P_GROUP_FORMATION:
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(pos, end - pos,
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "mode=P2P GO - group "
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  "formation\n");
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			default:
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = 0;
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return pos - buf;
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos += ret;
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface) {
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							    end - pos,
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							    verbose);
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_supplicant_state_txt(wpa_s->wpa_state));
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2 &&
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p) {
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  MAC2STR(wpa_s->own_addr));
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
113904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
114004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->current_bss &&
114161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    wpa_bss_get_vendor_ie(wpa_s->current_bss, HS20_IE_VENDOR_TYPE) &&
114261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    wpa_s->wpa_proto == WPA_PROTO_RSN &&
114361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
114404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "hs20=1\n");
114504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
114604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return pos - buf;
114704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos += ret;
114804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
114904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
115004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  verbose);
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res >= 0)
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos += res;
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res >= 0)
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += res;
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11632fd7fa6c75ed351b89297991cc5b5afff08d734cDmitry Shmidt#ifdef ANDROID
11642fd7fa6c75ed351b89297991cc5b5afff08d734cDmitry Shmidt	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
1165f20a4432808cee548326c4b35c83071ca576a239Irfan Sheriff		     "id=%d state=%d BSSID=" MACSTR " SSID=%s",
11662fd7fa6c75ed351b89297991cc5b5afff08d734cDmitry Shmidt		     wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
1167f20a4432808cee548326c4b35c83071ca576a239Irfan Sheriff		     wpa_s->wpa_state,
1168e78e767aea5576ec0ba7edadfe25fd9dc7dce48fIrfan Sheriff		     MAC2STR(wpa_s->bssid),
11695b5fb02b225c5c05a4477bef58bdaceede5d68dcandy		     wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
11705b5fb02b225c5c05a4477bef58bdaceede5d68dcandy		     wpa_ssid_txt(wpa_s->current_ssid->ssid,
11711029477547084d210cb810e8e5463c628972b315Irfan Sheriff		     wpa_s->current_ssid->ssid_len) : "");
1172bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff	if (wpa_s->wpa_state == WPA_COMPLETED) {
1173bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff		struct wpa_ssid *ssid = wpa_s->current_ssid;
1174bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- connection to "
1175bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff			MACSTR " completed %s [id=%d id_str=%s]",
1176bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff			MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ?
1177bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff			"(reauth)" : "(auth)",
1178bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff			ssid ? ssid->id : -1,
1179bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff			ssid && ssid->id_str ? ssid->id_str : "");
1180bf5edf439c90418b6f4122ff5e3925123263bda4Irfan Sheriff	}
11812fd7fa6c75ed351b89297991cc5b5afff08d734cDmitry Shmidt#endif /* ANDROID */
11822fd7fa6c75ed351b89297991cc5b5afff08d734cDmitry Shmidt
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   char *cmd)
11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id> <BSSID>" */
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(pos, bssid)) {
12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "to update", id);
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(ssid->bssid, bssid, ETH_ALEN);
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->bssid_set = !is_zero_ether_addr(bssid);
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1221e19501da312b59453448d587376062d5b3053a58Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
12221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       char *cmd, char *buf,
12231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       size_t buflen)
1224e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt{
1225e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	u8 bssid[ETH_ALEN];
1226e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	struct wpa_blacklist *e;
1227e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	char *pos, *end;
1228e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	int ret;
1229e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
1230e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	/* cmd: "BLACKLIST [<BSSID>]" */
1231e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	if (*cmd == '\0') {
1232e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		pos = buf;
1233e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		end = buf + buflen;
1234e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		e = wpa_s->blacklist;
1235e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		while (e) {
12361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = os_snprintf(pos, end - pos, MACSTR "\n",
12371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					  MAC2STR(e->bssid));
12381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (ret < 0 || ret >= end - pos)
1239e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt				return pos - buf;
1240e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt			pos += ret;
1241e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt			e = e->next;
1242e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		}
1243e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		return pos - buf;
1244e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	}
1245e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
1246e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	cmd++;
1247e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	if (os_strncmp(cmd, "clear", 5) == 0) {
1248e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		wpa_blacklist_clear(wpa_s);
1249e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		os_memcpy(buf, "OK\n", 3);
1250e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		return 3;
1251e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	}
1252e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
1253e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
1254e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	if (hwaddr_aton(cmd, bssid)) {
12551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
1256e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		return -1;
1257e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	}
1258e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
12591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/*
12601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * Add the BSSID twice, so its count will be 2, causing it to be
12611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * skipped when processing scan results.
12621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 */
1263e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	ret = wpa_blacklist_add(wpa_s, bssid);
12641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret != 0)
1265e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		return -1;
1266e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	ret = wpa_blacklist_add(wpa_s, bssid);
12671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret != 0)
1268e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt		return -1;
1269e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	os_memcpy(buf, "OK\n", 3);
1270e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	return 3;
1271e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt}
1272e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
1273e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt
12741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtextern int wpa_debug_level;
12751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtextern int wpa_debug_timestamp;
12761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const char * debug_level_str(int level)
12781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
12791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	switch (level) {
12801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_EXCESSIVE:
12811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "EXCESSIVE";
12821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_MSGDUMP:
12831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "MSGDUMP";
12841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_DEBUG:
12851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "DEBUG";
12861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_INFO:
12871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "INFO";
12881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_WARNING:
12891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "WARNING";
12901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case MSG_ERROR:
12911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "ERROR";
12921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	default:
12931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return "?";
12941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
12951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
12961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int str_to_debug_level(const char *s)
12991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
13001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "EXCESSIVE") == 0)
13011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_EXCESSIVE;
13021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "MSGDUMP") == 0)
13031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_MSGDUMP;
13041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "DEBUG") == 0)
13051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_DEBUG;
13061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "INFO") == 0)
13071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_INFO;
13081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "WARNING") == 0)
13091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_WARNING;
13101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcasecmp(s, "ERROR") == 0)
13111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return MSG_ERROR;
13121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return -1;
13131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
13141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
13171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       char *cmd, char *buf,
13181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       size_t buflen)
13191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
13201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char *pos, *end, *stamp;
13211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (cmd == NULL) {
13241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
13251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
13261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* cmd: "LOG_LEVEL [<level>]" */
13281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (*cmd == '\0') {
13291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos = buf;
13301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		end = buf + buflen;
13311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "Current level: %s\n"
13321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  "Timestamp: %d\n",
13331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  debug_level_str(wpa_debug_level),
13341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  wpa_debug_timestamp);
13351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
13361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			ret = 0;
13371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return ret;
13391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
13401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	while (*cmd == ' ')
13421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		cmd++;
13431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	stamp = os_strchr(cmd, ' ');
13451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (stamp) {
13461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*stamp++ = '\0';
13471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		while (*stamp == ' ') {
13481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			stamp++;
13491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
13501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
13511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (cmd && os_strlen(cmd)) {
13531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		int level = str_to_debug_level(cmd);
13541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (level < 0)
13551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
13561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_debug_level = level;
13571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
13581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (stamp && os_strlen(stamp))
13601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_debug_timestamp = atoi(stamp);
13611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_memcpy(buf, "OK\n", 3);
13631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 3;
13641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
13651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_list_networks(
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + buflen;
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos,
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "network id / ssid / bssid / flags\n");
13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->conf->ssid;
13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (ssid) {
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%d\t%s",
13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ssid->id,
13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->bssid_set) {
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "\t" MACSTR,
13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  MAC2STR(ssid->bssid));
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "\tany");
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
139961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "\t%s%s%s%s",
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ssid == wpa_s->current_ssid ?
14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  "[CURRENT]" : "",
14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ssid->disabled ? "[DISABLED]" : "",
140361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				  ssid->disabled_until.sec ?
140461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				  "[TEMP-DISABLED]" : "",
14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  "");
14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "\n");
14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = ssid->next;
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int first = 1, ret;
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "-");
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos;
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cipher & WPA_CIPHER_NONE) {
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cipher & WPA_CIPHER_WEP40) {
14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cipher & WPA_CIPHER_WEP104) {
14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sWEP104",
14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : "+");
14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cipher & WPA_CIPHER_TKIP) {
14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cipher & WPA_CIPHER_CCMP) {
14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
146561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (cipher & WPA_CIPHER_GCMP) {
146661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sGCMP", first ? "" : "+");
146761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
146861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return pos;
146961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos += ret;
147061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		first = 0;
147161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos;
14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    const u8 *ie, size_t ie_len)
14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data data;
14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int first, ret;
14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "[%s-", proto);
14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos;
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "?]");
14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos;
14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	first = 1;
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sFT/EAP",
15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : "+");
15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sFT/PSK",
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : "+");
15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : "+");
15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : "+");
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "-preauth");
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos;
15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "]");
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos;
15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos;
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    char *pos, char *end,
15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    struct wpabuf *wps_ie)
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *txt;
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL)
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos;
15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_is_selected_pbc_registrar(wps_ie))
15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		txt = "[WPS-PBC]";
15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS2
15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		txt = "[WPS-AUTH]";
15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS2 */
15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wps_is_selected_pin_registrar(wps_ie))
15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		txt = "[WPS-PIN]";
15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		txt = "[WPS]";
15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "%s", txt);
15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret >= 0 && ret < end - pos)
15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(wps_ie);
15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos;
15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					char *pos, char *end,
16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					const struct wpa_bss *bss)
16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *wps_ie;
16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_WPS */
16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos;
16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Format one result on one text line into a buffer. */
16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_scan_result(
16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s,
16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct wpa_bss *bss, char *buf, size_t buflen)
16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *ie, *ie2, *p2p;
16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    0)
16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0; /* Do not show P2P listen discovery results here */
16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + buflen;
16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  MAC2STR(bss->bssid), bss->freq, bss->level);
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie)
16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie2)
16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "[WEP]");
16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->caps & IEEE80211_CAP_IBSS) {
16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "[IBSS]");
16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->caps & IEEE80211_CAP_ESS) {
16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "[ESS]");
16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p) {
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "[P2P]");
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
167004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
167161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) {
167204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "[HS20]");
167304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
167404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
167504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos += ret;
167604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
167704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "\t%s",
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_ssid_txt(bss->ssid, bss->ssid_len));
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "\n");
16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_scan_results(
16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + buflen;
17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "flags / ssid\n");
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							    end - pos);
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_select_network(
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id>" or "any" */
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "any") == 0) {
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = NULL;
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		id = atoi(cmd);
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, id);
17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL) {
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "network id=%d", id);
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->disabled == 2) {
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "SELECT_NETWORK with persistent P2P group");
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_select_network(wpa_s, ssid);
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_enable_network(
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id>" or "all" */
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "all") == 0) {
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = NULL;
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		id = atoi(cmd);
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, id);
17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL) {
17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "network id=%d", id);
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->disabled == 2) {
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "ENABLE_NETWORK with persistent P2P group");
17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
177904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
178004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (os_strstr(cmd, " no-connect")) {
178104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			ssid->disabled = 0;
178204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return 0;
178304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_enable_network(wpa_s, ssid);
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_disable_network(
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id>" or "all" */
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "all") == 0) {
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = NULL;
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		id = atoi(cmd);
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, id);
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL) {
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "network id=%d", id);
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->disabled == 2) {
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "DISABLE_NETWORK with persistent P2P "
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "group");
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_disable_network(wpa_s, ssid);
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_add_network(
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_add_network(wpa_s->conf);
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL)
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_network_added(wpa_s, ssid);
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->disabled = 1;
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_set_network_defaults(ssid);
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || (size_t) ret >= buflen)
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_remove_network(
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id>" or "all" */
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "all") == 0) {
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_s->conf->ssid;
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (ssid) {
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct wpa_ssid *remove_ssid = ssid;
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			id = ssid->id;
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid = ssid->next;
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_removed(wpa_s, remove_ssid);
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf, id);
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->current_ssid) {
186704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
186804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->sme.prev_bssid_set = 0;
186904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
187075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_sm_set_config(wpa_s->wpa, NULL);
187175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_disassociate(wpa_s,
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				                    WLAN_REASON_DEAUTH_LEAVING);
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
18821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid)
18831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_notify_network_removed(wpa_s, ssid);
1884a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri	if (ssid == NULL) {
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "id=%d", id);
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
189104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
189204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sme.prev_bssid_set = 0;
189304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
18951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * Invalidate the EAP session cache if the current or
18961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * previously used network is removed.
18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
18991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
19001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
19011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid == wpa_s->current_ssid) {
190275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_sm_set_config(wpa_s->wpa, NULL);
190375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1909a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the "
1910a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri			   "network id=%d", id);
1911a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri		return -1;
1912a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri	}
1913a831d78b5fb6af549533456cda57f88d73f6d153Deepthi Gowri
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_set_network(
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *name, *value;
19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id> <variable name> <value>" */
19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	name = os_strchr(cmd, ' ');
19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (name == NULL)
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*name++ = '\0';
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = os_strchr(name, ' ');
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*value++ = '\0';
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   id, name);
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      (u8 *) value, os_strlen(value));
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "id=%d", id);
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_set(ssid, name, value, 0) < 0) {
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "variable '%s'", name);
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
19561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
19571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Invalidate the EAP session cache if anything in the current
19601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * or previously used configuration changes.
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((os_strcmp(name, "psk") == 0 &&
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     value[0] == '"' && ssid->ssid_len) ||
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_update_psk(ssid);
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (os_strcmp(name, "priority") == 0)
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_update_prio_list(wpa_s->conf);
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_get_network(
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t res;
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *name, *value;
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* cmd: "<network id> <variable name>" */
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	name = os_strchr(cmd, ' ');
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (name == NULL || buflen == 0)
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*name++ = '\0';
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   id, name);
19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "id=%d", id);
19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get_no_key(ssid, name);
20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL) {
20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "variable '%s'", name);
20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = os_strlcpy(buf, value, buflen);
20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res >= buflen) {
20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(value);
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return res;
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
202004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
202104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						char *buf, size_t buflen)
202204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
202304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *pos, *end;
202404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_cred *cred;
202504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ret;
202604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
202704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos = buf;
202804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	end = buf + buflen;
202904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = os_snprintf(pos, end - pos,
203004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			  "cred id / realm / username / domain / imsi\n");
203104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ret < 0 || ret >= end - pos)
203204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return pos - buf;
203304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos += ret;
203404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
203504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	cred = wpa_s->conf->cred;
203604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (cred) {
203704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
203804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  cred->id, cred->realm ? cred->realm : "",
203904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  cred->username ? cred->username : "",
204004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  cred->domain ? cred->domain : "",
204104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  cred->imsi ? cred->imsi : "");
204204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
204304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return pos - buf;
204404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos += ret;
204504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
204604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		cred = cred->next;
204704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
204804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
204904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return pos - buf;
205004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
205104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
205204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
205304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s,
205404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      char *buf, size_t buflen)
205504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
205604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_cred *cred;
205704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ret;
205804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
205904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED");
206004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
206104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	cred = wpa_config_add_cred(wpa_s->conf);
206204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (cred == NULL)
206304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
206404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
206504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = os_snprintf(buf, buflen, "%d\n", cred->id);
206604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ret < 0 || (size_t) ret >= buflen)
206704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
206804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return ret;
206904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
207004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
207104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
207204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
207304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 char *cmd)
207404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
207504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int id;
207604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_cred *cred;
207704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
207804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* cmd: "<cred id>" or "all" */
207904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strcmp(cmd, "all") == 0) {
208004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
208104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		cred = wpa_s->conf->cred;
208204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		while (cred) {
208304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			id = cred->id;
208404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			cred = cred->next;
208504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_config_remove_cred(wpa_s->conf, id);
208604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
208704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
208804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
208904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
209004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	id = atoi(cmd);
209104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
209204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
209304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	cred = wpa_config_get_cred(wpa_s->conf, id);
209404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (cred == NULL ||
209504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_config_remove_cred(wpa_s->conf, id) < 0) {
209604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
209704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   id);
209804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
209904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
210004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
210104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
210204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
210304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
210404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
210504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s,
210604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      char *cmd)
210704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
210804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int id;
210904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_cred *cred;
211004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *name, *value;
211104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
211204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* cmd: "<cred id> <variable name> <value>" */
211304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	name = os_strchr(cmd, ' ');
211404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (name == NULL)
211504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
211604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	*name++ = '\0';
211704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
211804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	value = os_strchr(name, ' ');
211904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (value == NULL)
212004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
212104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	*value++ = '\0';
212204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
212304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	id = atoi(cmd);
212404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'",
212504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   id, name);
212604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
212704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			      (u8 *) value, os_strlen(value));
212804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
212904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	cred = wpa_config_get_cred(wpa_s->conf, id);
213004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (cred == NULL) {
213104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
213204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   id);
213304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
213404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
213504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
213604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_config_set_cred(cred, name, value, 0) < 0) {
213704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred "
213804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "variable '%s'", name);
213904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
214004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
214104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
214204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
214304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
214404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
214504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE
21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->conf->update_config) {
21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "to update configuration (update_config=0)");
21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "update configuration");
21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " updated");
21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */
21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ctrl_iface_get_capability_pairwise(int res, char *strict,
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      struct wpa_driver_capa *capa,
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      char *buf, size_t buflen)
21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, first = 1;
21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = pos + buflen;
21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strict)
21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= buflen)
21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return len;
21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
219961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_GCMP) {
220061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sGCMP", first ? "" : " ");
220161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
220261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return pos - buf;
220361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos += ret;
220461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		first = 0;
220561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
220661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ctrl_iface_get_capability_group(int res, char *strict,
22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_driver_capa *capa,
22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   char *buf, size_t buflen)
22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, first = 1;
22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = pos + buflen;
22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strict)
22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= buflen)
22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return len;
22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
225561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_GCMP) {
225661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sGCMP", first ? "" : " ");
225761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
225861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return pos - buf;
225961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos += ret;
226061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		first = 0;
226161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
226261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sWEP104",
22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : " ");
22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      struct wpa_driver_capa *capa,
22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      char *buf, size_t buflen)
22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = pos + buflen;
23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strict)
23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 "NONE", buflen);
23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= buflen)
23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return len;
23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, " WPA-EAP");
23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, " WPA-PSK");
23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, " WPA-NONE");
23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ctrl_iface_get_capability_proto(int res, char *strict,
23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_driver_capa *capa,
23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   char *buf, size_t buflen)
23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, first = 1;
23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = pos + buflen;
23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strict)
23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlcpy(buf, "RSN WPA", buflen);
23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= buflen)
23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return len;
23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ctrl_iface_get_capability_auth_alg(int res, char *strict,
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      struct wpa_driver_capa *capa,
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      char *buf, size_t buflen)
23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, first = 1;
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = pos + buflen;
23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strict)
24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= buflen)
24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return len;
24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sSHARED",
24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  first ? "" : " ");
24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		first = 0;
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24360e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidtstatic int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s,
24370e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt					      char *buf, size_t buflen)
24380e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt{
24390e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	struct hostapd_channel_data *chnl;
24400e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	int ret, i, j;
24410e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	char *pos, *end, *hmode;
24420e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
24430e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	pos = buf;
24440e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	end = pos + buflen;
24450e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
24460e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	for (j = 0; j < wpa_s->hw.num_modes; j++) {
24470e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		switch (wpa_s->hw.modes[j].mode) {
24480e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		case HOSTAPD_MODE_IEEE80211B:
24490e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			hmode = "B";
24500e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			break;
24510e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		case HOSTAPD_MODE_IEEE80211G:
24520e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			hmode = "G";
24530e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			break;
24540e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		case HOSTAPD_MODE_IEEE80211A:
24550e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			hmode = "A";
24560e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			break;
24570e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		default:
245861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			continue;
24590e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		}
24600e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:", hmode);
24610e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
24620e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			return pos - buf;
24630e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		pos += ret;
24640e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		chnl = wpa_s->hw.modes[j].channels;
24650e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) {
246661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (chnl[i].flag & HOSTAPD_CHAN_DISABLED)
246761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				continue;
24680e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			ret = os_snprintf(pos, end - pos, " %d", chnl[i].chan);
24690e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			if (ret < 0 || ret >= end - pos)
24700e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt				return pos - buf;
24710e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			pos += ret;
24720e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		}
24730e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "\n");
24740e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
24750e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt			return pos - buf;
24760e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		pos += ret;
24770e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	}
24780e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
24790e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	return pos - buf;
24800e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt}
24810e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
24820e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_get_capability(
24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, const char *_field, char *buf,
24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t buflen)
24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *strict;
24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char field[30];
24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Determine whether or not strict checking was requested */
24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlcpy(field, _field, sizeof(field));
24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len >= sizeof(field))
24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	strict = os_strchr(field, ' ');
24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (strict != NULL) {
24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*strict++ = '\0';
25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(strict, "strict") != 0)
25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		field, strict ? strict : "");
25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "eap") == 0) {
25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return eap_get_names(buf, buflen);
25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = wpa_drv_get_capa(wpa_s, &capa);
25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "pairwise") == 0)
25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ctrl_iface_get_capability_pairwise(res, strict, &capa,
25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							  buf, buflen);
25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "group") == 0)
25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ctrl_iface_get_capability_group(res, strict, &capa,
25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       buf, buflen);
25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "key_mgmt") == 0)
25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							  buf, buflen);
25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "proto") == 0)
25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ctrl_iface_get_capability_proto(res, strict, &capa,
25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       buf, buflen);
25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(field, "auth_alg") == 0)
25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							  buf, buflen);
25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25330e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt	if (os_strcmp(field, "channels") == 0)
25340e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt		return ctrl_iface_get_capability_channels(wpa_s, buf, buflen);
25350e6d08e6ec9e3ef3b65a76124d7700d56fe67a8aDmitry Shmidt
25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   field);
25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
25441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic char * anqp_add_hex(char *pos, char *end, const char *title,
25451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   struct wpabuf *data)
25461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
25471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char *start = pos;
25481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t i;
25491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
25501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 *d;
25511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (data == NULL)
25531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return start;
25541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = os_snprintf(pos, end - pos, "%s=", title);
25561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret < 0 || ret >= end - pos)
25571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return start;
25581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos += ret;
25591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	d = wpabuf_head_u8(data);
25611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < wpabuf_len(data); i++) {
25621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret = os_snprintf(pos, end - pos, "%02x", *d++);
25631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ret < 0 || ret >= end - pos)
25641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return start;
25651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos += ret;
25661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
25671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = os_snprintf(pos, end - pos, "\n");
25691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ret < 0 || ret >= end - pos)
25701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return start;
25711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos += ret;
25721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return pos;
25741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
25751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
25761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
25771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2578f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidtstatic int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
2579f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			  unsigned long mask, char *buf, size_t buflen)
25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *ie, *ie2;
25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2586f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	pos = buf;
2587f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	end = buf + buflen;
2588f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2589f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_ID) {
2590f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
2591f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2592f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2593f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2594f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2595f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2596f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_BSSID) {
2597f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
2598f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  MAC2STR(bss->bssid));
2599f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2600f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2601f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2602f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2603f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2604f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_FREQ) {
2605f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
2606f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2607f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2608f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2609f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2610f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2611f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_BEACON_INT) {
2612f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
2613f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  bss->beacon_int);
2614f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2615f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2616f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2617f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2618f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2619f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_CAPABILITIES) {
2620f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n",
2621f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  bss->caps);
2622f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2623f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2624f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2625f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2626f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2627f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_QUAL) {
2628f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual);
2629f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2630f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2631f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2632f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2633f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2634f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_NOISE) {
2635f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise);
2636f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2637f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2638f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2639f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2640f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2641f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_LEVEL) {
2642f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level);
2643f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2644f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2645f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2646f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2647f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2648f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_TSF) {
2649f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "tsf=%016llu\n",
2650f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  (unsigned long long) bss->tsf);
2651f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2652f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2653f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2654f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2655f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2656f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_AGE) {
265704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		struct os_time now;
265804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
265904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_get_time(&now);
2660f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "age=%d\n",
2661f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  (int) (now.sec - bss->last_update.sec));
2662f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2663f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2664f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2665f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2666f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2667f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_IE) {
2668f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "ie=");
2669f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2670f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2671f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2672f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2673f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ie = (const u8 *) (bss + 1);
2674f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		for (i = 0; i < bss->ie_len; i++) {
2675f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "%02x", *ie++);
2676f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
2677f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2678f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos += ret;
2679f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
2680f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2681f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "\n");
2682f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2683f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2684f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2685f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2686f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2687f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_FLAGS) {
2688f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "flags=");
2689f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2690f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2691f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2692f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2693f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
2694f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ie)
2695f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
2696f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt						    2 + ie[1]);
2697f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
2698f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ie2)
2699f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2,
2700f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt						    2 + ie2[1]);
2701f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
2702f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
2703f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "[WEP]");
2704f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
2705f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2706f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos += ret;
2707f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
2708f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (bss->caps & IEEE80211_CAP_IBSS) {
2709f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "[IBSS]");
2710f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
2711f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2712f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos += ret;
2713f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
2714f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (bss->caps & IEEE80211_CAP_ESS) {
2715f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "[ESS]");
2716f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
2717f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2718f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos += ret;
2719f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
2720f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
2721f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "[P2P]");
2722f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
2723f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2724f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			pos += ret;
2725f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
272604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
272704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) {
272804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			ret = os_snprintf(pos, end - pos, "[HS20]");
272904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (ret < 0 || ret >= end - pos)
273004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return -1;
273104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos += ret;
273204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
273304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
2734f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2735f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "\n");
2736f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2737f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2738f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2739f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2740f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2741f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_SSID) {
2742f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = os_snprintf(pos, end - pos, "ssid=%s\n",
2743f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				  wpa_ssid_txt(bss->ssid, bss->ssid_len));
2744f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2745f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2746f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2747f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2748f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2749f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#ifdef CONFIG_WPS
2750f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_WPS_SCAN) {
2751f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ie = (const u8 *) (bss + 1);
2752f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
2753f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2754f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2755f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2756f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2757f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#endif /* CONFIG_WPS */
2758f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2759f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#ifdef CONFIG_P2P
2760f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (mask & WPA_BSS_MASK_P2P_SCAN) {
2761f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ie = (const u8 *) (bss + 1);
2762f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
2763f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (ret < 0 || ret >= end - pos)
2764f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			return 0;
2765f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos += ret;
2766f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2767f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#endif /* CONFIG_P2P */
2768f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
276961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
277061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (mask & WPA_BSS_MASK_WIFI_DISPLAY) {
277161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		struct wpabuf *wfd;
277261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ie = (const u8 *) (bss + 1);
277361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wfd = ieee802_11_vendor_ie_concat(ie, bss->ie_len,
277461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						  WFD_IE_VENDOR_TYPE);
277561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wfd) {
277661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "wfd_subelems=");
277761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
277861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return pos - buf;
277961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos += ret;
278061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
278161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos += wpa_snprintf_hex(pos, end - pos,
278261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						wpabuf_head(wfd),
278361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						wpabuf_len(wfd));
278461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpabuf_free(wfd);
278561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
278661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ret = os_snprintf(pos, end - pos, "\n");
278761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (ret < 0 || ret >= end - pos)
278861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return pos - buf;
278961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos += ret;
279061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
279161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
279261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
279361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
2794f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#ifdef CONFIG_INTERWORKING
27954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt	if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) {
27964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt		struct wpa_bss_anqp *anqp = bss->anqp;
2797f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_venue_name",
27984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->venue_name);
2799f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
28004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->network_auth_type);
2801f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
28024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->roaming_consortium);
2803f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
28044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->ip_addr_type_availability);
2805f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_nai_realm",
28064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->nai_realm);
28074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp);
2808f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		pos = anqp_add_hex(pos, end, "anqp_domain_name",
28094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->domain_name);
281004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
281104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name",
28124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->hs20_operator_friendly_name);
281304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = anqp_add_hex(pos, end, "hs20_wan_metrics",
28144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->hs20_wan_metrics);
281504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = anqp_add_hex(pos, end, "hs20_connection_capability",
28164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt				   anqp->hs20_connection_capability);
281704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
2818f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	}
2819f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
2820f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2821e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff#ifdef ANDROID
2822e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff	ret = os_snprintf(pos, end - pos, "====\n");
2823e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff	if (ret < 0 || ret >= end - pos)
2824e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff		return 0;
2825e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff	pos += ret;
2826e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff#endif
2827e2ea008a74fb04cee45dee9451812ff147502a5aIrfan Sheriff
2828f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	return pos - buf;
2829f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt}
2830f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
283104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2832f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
2833f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt					 const char *cmd, char *buf,
2834f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt					 size_t buflen)
2835f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt{
2836f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	u8 bssid[ETH_ALEN];
2837f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	size_t i;
283804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_bss *bss;
2839f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	struct wpa_bss *bsslast = NULL;
2840f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	struct dl_list *next;
2841f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	int ret = 0;
2842f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	int len;
2843f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	char *ctmp;
2844f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	unsigned long mask = WPA_BSS_MASK_ALL;
2845f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt
2846f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (os_strncmp(cmd, "RANGE=", 6) == 0) {
2847f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (os_strncmp(cmd + 6, "ALL", 3) == 0) {
2848f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss,
284904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    list_id);
2850f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss,
2851f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt					       list_id);
2852f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		} else { /* N1-N2 */
285304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			unsigned int id1, id2;
285404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
285504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if ((ctmp = os_strchr(cmd + 6, '-')) == NULL) {
285604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_INFO, "Wrong BSS range "
285704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "format");
2858f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt				return 0;
2859f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			}
286004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
286104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			id1 = atoi(cmd + 6);
286204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss = wpa_bss_get_id(wpa_s, id1);
286304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			id2 = atoi(ctmp + 1);
286404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (id2 == 0)
286504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bsslast = dl_list_last(&wpa_s->bss_id,
286604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						       struct wpa_bss,
286704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						       list_id);
286804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			else {
286904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bsslast = wpa_bss_get_id(wpa_s, id2);
287004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				if (bsslast == NULL && bss && id2 > id1) {
287104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					struct wpa_bss *tmp = bss;
287204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					for (;;) {
287304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						next = tmp->list_id.next;
287404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						if (next == &wpa_s->bss_id)
287504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							break;
287604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						tmp = dl_list_entry(
287704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							next, struct wpa_bss,
287804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							list_id);
287904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						if (tmp->id > id2)
288004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							break;
288104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						bsslast = tmp;
288204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					}
288304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				}
288404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
2885f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		}
2886f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	} else if (os_strcmp(cmd, "FIRST") == 0)
288704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, list_id);
28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (os_strncmp(cmd, "ID-", 3) == 0) {
28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		i = atoi(cmd + 3);
28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = wpa_bss_get_id(wpa_s, i);
28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		i = atoi(cmd + 5);
28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = wpa_bss_get_id(wpa_s, i);
28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss) {
2895f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			next = bss->list_id.next;
28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (next == &wpa_s->bss_id)
28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss = NULL;
28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss = dl_list_entry(next, struct wpa_bss,
29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    list_id);
29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2902c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_P2P
2903c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
2904c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (hwaddr_aton(cmd + 13, bssid) == 0)
2905c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
2906c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		else
2907c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			bss = NULL;
2908c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_P2P */
29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (hwaddr_aton(cmd, bssid) == 0)
29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = wpa_bss_get_bssid(wpa_s, bssid);
29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else {
29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_bss *tmp;
29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		i = atoi(cmd);
29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = NULL;
29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (i-- == 0) {
29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss = tmp;
29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
292404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) {
292504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		mask = strtoul(ctmp + 5, NULL, 0x10);
292604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (mask == 0)
292704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			mask = WPA_BSS_MASK_ALL;
292804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
292904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL)
29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2933f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	if (bsslast == NULL)
2934f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		bsslast = bss;
2935f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	do {
2936f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		len = print_bss_info(wpa_s, bss, mask, buf, buflen);
2937f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		ret += len;
2938f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		buf += len;
2939f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		buflen -= len;
2940f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (bss == bsslast)
2941f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			break;
2942f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		next = bss->list_id.next;
2943f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		if (next == &wpa_s->bss_id)
2944f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt			break;
2945f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt		bss = dl_list_entry(next, struct wpa_bss, list_id);
2946f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	} while (bss && len);
29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2948f2df2f2f5318f4ce3046b93207fada30fe694069Dmitry Shmidt	return ret;
29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_ap_scan(
29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ap_scan = atoi(cmd);
29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_scan_interval(
29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int scan_int = atoi(cmd);
296404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpa_supplicant_set_scan_interval(wpa_s, scan_int);
29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_bss_expire_age(
29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int expire_age = atoi(cmd);
29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_bss_expire_count(
29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int expire_count = atoi(cmd);
29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2984f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_bss_flush(
2985f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
2986f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt{
2987f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	int flush_age = atoi(cmd);
2988f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt
2989f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	if (flush_age == 0)
2990f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt		wpa_bss_flush(wpa_s);
2991f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	else
2992f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt		wpa_bss_flush_by_age(wpa_s, flush_age);
2993f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	return 0;
2994f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt}
2995f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt
2996f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt
29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* MLME-DELETEKEYS.request */
30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			0);
30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* MLME-SETPROTECTION.request(None) */
30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   MLME_SETPROTECTION_PROTECT_TYPE_NONE,
30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_drop_sa(wpa_s->wpa);
30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  char *addr)
30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_NO_SCAN_PROCESSING
30241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return -1;
30251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#else /* CONFIG_NO_SCAN_PROCESSING */
30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, bssid)) {
30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address '%s'", addr);
30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = wpa_bss_get_bssid(wpa_s, bssid);
30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!bss) {
30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "from BSS table");
30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: Find best network configuration block from configuration to
30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * allow roaming to other networks
30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!ssid) {
30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configuration known for the target AP");
30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 1;
30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_connect(wpa_s, bss, ssid);
30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
30601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int timeout = atoi(cmd);
30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
3069c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u8 dev_id[ETH_ALEN], *_dev_id = NULL;
3070c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	char *pos;
307161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	unsigned int search_delay;
30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(cmd, "type=social"))
30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		type = P2P_FIND_ONLY_SOCIAL;
30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (os_strstr(cmd, "type=progressive"))
30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		type = P2P_FIND_PROGRESSIVE;
30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3078c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	pos = os_strstr(cmd, "dev_id=");
3079c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (pos) {
3080c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		pos += 7;
3081c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (hwaddr_aton(pos, dev_id))
3082c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			return -1;
3083c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		_dev_id = dev_id;
3084c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
3085c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
308661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strstr(cmd, "delay=");
308761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos) {
308861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos += 6;
308961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		search_delay = atoi(pos);
309061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else
309161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		search_delay = wpas_p2p_search_delay(wpa_s);
309261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
309361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id,
309461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			     search_delay);
30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    char *buf, size_t buflen)
31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN];
31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *pos2;
31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pin = NULL;
31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum p2p_wps_method wps_method;
31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int new_pin;
31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
310704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int persistent_group, persistent_id = -1;
31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int join;
31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int auth;
311004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int automatic;
31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int go_intent = -1;
31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq = 0;
311304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int pd;
311461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int ht40;
31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
311604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
311704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * [persistent|persistent=<network id>]
311861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
311961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	 * [ht40] */
31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(cmd, addr))
31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = cmd + 17;
31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*pos != ' ')
31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos++;
31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	persistent_group = os_strstr(pos, " persistent") != NULL;
313004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos2 = os_strstr(pos, " persistent=");
313104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pos2) {
313204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		struct wpa_ssid *ssid;
313304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		persistent_id = atoi(pos2 + 12);
313404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
313504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == NULL || ssid->disabled != 2 ||
313604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    ssid->mode != WPAS_MODE_P2P_GO) {
313704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
313804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "SSID id=%d for persistent P2P group (GO)",
313904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   persistent_id);
314004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
314104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
314204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	join = os_strstr(pos, " join") != NULL;
31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	auth = os_strstr(pos, " auth") != NULL;
314504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	automatic = os_strstr(pos, " auto") != NULL;
314604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pd = os_strstr(pos, " provdisc") != NULL;
314761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ht40 = os_strstr(pos, " ht40") != NULL;
31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos2 = os_strstr(pos, " go_intent=");
31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos2) {
31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos2 += 11;
31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		go_intent = atoi(pos2);
31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (go_intent < 0 || go_intent > 15)
31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos2 = os_strstr(pos, " freq=");
31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos2) {
31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos2 += 6;
31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = atoi(pos2);
31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freq <= 0)
31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(pos, "pin", 3) == 0) {
31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Request random PIN (to be displayed) and enable the PIN */
31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_method = WPS_PIN_DISPLAY;
31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(pos, "pbc", 3) == 0) {
31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_method = WPS_PBC;
31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin = pos;
31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pin, ' ');
31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_method = WPS_PIN_KEYPAD;
31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos) {
31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
31761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (os_strncmp(pos, "display", 7) == 0)
31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wps_method = WPS_PIN_DISPLAY;
31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
317904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wps_pin_str_valid(pin)) {
318004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_memcpy(buf, "FAIL-INVALID-PIN\n", 17);
318104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return 17;
318204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
318604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   persistent_group, automatic, join,
318761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				   auth, go_intent, freq, persistent_id, pd,
318861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				   ht40);
31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_pin == -2) {
31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 25;
31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_pin == -3) {
31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 25;
31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_pin < 0)
31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(buf, buflen, "%08d", new_pin);
32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || (size_t) ret >= buflen)
32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(buf, "OK\n", 3);
32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 3;
32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int timeout = atoi(cmd);
32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_listen(wpa_s, timeout);
32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN];
32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
322204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG;
32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
322404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* <addr> <config method> [join|auto] */
32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(cmd, addr))
32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = cmd + 17;
32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*pos != ' ')
32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos++;
32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
323404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(pos, " join") != NULL)
323504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		use = WPAS_P2P_PD_FOR_JOIN;
323604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (os_strstr(pos, " auto") != NULL)
323704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		use = WPAS_P2P_PD_AUTO;
323804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
323904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_p2p_prov_disc(wpa_s, addr, pos, use);
32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      size_t buflen)
32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->passphrase == NULL)
32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(buf, ssid->passphrase, buflen);
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_strlen(buf);
32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  char *buf, size_t buflen)
32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u64 ref;
32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 dst_buf[ETH_ALEN], *dst;
32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *tlvs;
32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(cmd, dst_buf))
32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dst = dst_buf;
32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dst = NULL;
32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = cmd + 17;
32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*pos != ' ')
32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos++;
32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(pos, "upnp ", 5) == 0) {
32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 version;
32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += 5;
32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hexstr2bin(pos, &version, 1) < 0)
32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += 2;
32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos != ' ')
32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
32871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
328861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
328961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strncmp(pos, "wifi-display ", 13) == 0) {
329061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ref = wpas_p2p_sd_request_wifi_display(wpa_s, dst, pos + 13);
329161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlen(pos);
32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len & 1)
32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len /= 2;
32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tlvs = wpabuf_alloc(len);
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (tlvs == NULL)
32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(tlvs);
33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ref = wpas_p2p_sd_request(wpa_s, dst, tlvs);
33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(tlvs);
33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ref == 0)
33091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0 || (unsigned) res >= buflen)
33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return res;
33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 char *cmd)
33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	long long unsigned val;
33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u64 req;
33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sscanf(cmd, "%llx", &val) != 1)
33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	req = val;
33251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpas_p2p_sd_cancel_request(wpa_s, req);
33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 dst[ETH_ALEN];
33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 dialog_token;
33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *resp_tlvs;
33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *pos2;
33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freq = atoi(cmd);
33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq == 0)
33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(pos, dst))
33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += 17;
33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*pos != ' ')
33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos++;
33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos2 = os_strchr(pos, ' ');
33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos2 == NULL)
33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos2++ = '\0';
33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dialog_token = atoi(pos);
33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(pos2);
33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len & 1)
33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len /= 2;
33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	resp_tlvs = wpabuf_alloc(len);
33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (resp_tlvs == NULL)
33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(resp_tlvs);
33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(resp_tlvs);
33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       char *cmd)
33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
338004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1"))
338104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					char *cmd)
33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *query, *resp;
33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(cmd);
34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len & 1)
34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len /= 2;
34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	query = wpabuf_alloc(len);
34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (query == NULL)
34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(pos);
34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len & 1) {
34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len /= 2;
34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	resp = wpabuf_alloc(len);
34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (resp == NULL) {
34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(resp);
34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(resp);
34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 version;
34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(cmd, &version, 1) < 0)
34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_service_add_upnp(wpa_s, version, pos);
34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "bonjour") == 0)
34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_service_add_bonjour(wpa_s, pos);
34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "upnp") == 0)
34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_service_add_upnp(wpa_s, pos);
34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					char *cmd)
34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *query;
34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(cmd);
34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len & 1)
34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len /= 2;
34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	query = wpabuf_alloc(len);
34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (query == NULL)
34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(query);
34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpas_p2p_service_del_bonjour(wpa_s, query);
34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(query);
34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 version;
35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(cmd, &version, 1) < 0)
35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_service_del_upnp(wpa_s, version, pos);
35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(cmd, ' ');
35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos == NULL)
35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos++ = '\0';
35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "bonjour") == 0)
35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_service_del_bonjour(wpa_s, pos);
35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "upnp") == 0)
35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_service_del_upnp(wpa_s, pos);
35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN];
35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* <addr> */
35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(cmd, addr))
35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_reject(wpa_s, addr);
35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
3550aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	u8 *_peer = NULL, peer[ETH_ALEN];
355131be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	int freq = 0;
355231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	int ht40;
35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
3555aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	pos = os_strstr(cmd, " peer=");
3556aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	if (pos) {
3557aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		pos += 6;
3558aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		if (hwaddr_aton(pos, peer))
3559aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			return -1;
3560aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		_peer = peer;
3561aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	}
35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL || ssid->disabled != 2) {
35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "for persistent P2P group",
35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   id);
35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
357031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	pos = os_strstr(cmd, " freq=");
357131be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	if (pos) {
357231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen		pos += 6;
357331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen		freq = atoi(pos);
357431be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen		if (freq <= 0)
357531be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen			return -1;
357631be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	}
357731be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen
357831be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	ht40 = os_strstr(cmd, " ht40") != NULL;
357931be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen
3580aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40);
35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strstr(cmd, " peer=");
35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!pos)
35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*pos = '\0';
35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += 6;
35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(pos, peer)) {
35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strstr(pos, " go_dev_addr=");
36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos) {
36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += 13;
36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(pos, go_dev_addr)) {
36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   pos);
36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		go_dev = go_dev_addr;
36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(cmd, "persistent=", 11) == 0)
36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(cmd, "group=", 6) == 0)
36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_ctrl_invite_group(wpa_s, cmd + 6);
36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
362761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					 char *cmd, int freq, int ht40)
36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = atoi(cmd);
36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL || ssid->disabled != 2) {
36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "for persistent P2P group",
36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   id);
36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
364161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40);
36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
364761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int freq = 0, ht40;
36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strstr(cmd, "freq=");
36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos)
36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = atoi(pos + 5);
36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
365461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ht40 = os_strstr(cmd, "ht40") != NULL;
365561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(cmd, "persistent=", 11) == 0)
365761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq,
365861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						     ht40);
36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "persistent") == 0 ||
36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_strncmp(cmd, "persistent ", 11) == 0)
366161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return wpas_p2p_group_add(wpa_s, 1, freq, ht40);
36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(cmd, "freq=", 5) == 0)
366361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
366461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ht40)
366561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cmd);
36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 char *buf, size_t buflen)
36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN], *addr_ptr;
36771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int next, res;
36781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const struct p2p_peer_info *info;
36791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char *pos, *end;
36801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char devtype[WPS_DEV_TYPE_BUFSIZE];
36811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *ssid;
36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->global->p2p)
36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "FIRST") == 0) {
36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr_ptr = NULL;
36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		next = 0;
36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(cmd + 5, addr) < 0)
36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr_ptr = addr;
36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		next = 1;
36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(cmd, addr) < 0)
36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr_ptr = addr;
36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		next = 0;
36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
37011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
37021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (info == NULL)
37031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
37051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = buf;
37061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	end = buf + buflen;
37071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	res = os_snprintf(pos, end - pos, MACSTR "\n"
37091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "pri_dev_type=%s\n"
37101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "device_name=%s\n"
37111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "manufacturer=%s\n"
37121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "model_name=%s\n"
37131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "model_number=%s\n"
37141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "serial_number=%s\n"
37151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "config_methods=0x%x\n"
37161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "dev_capab=0x%x\n"
37171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "group_capab=0x%x\n"
37181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  "level=%d\n",
37191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  MAC2STR(info->p2p_device_addr),
37201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  wps_dev_type_bin2str(info->pri_dev_type,
37211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       devtype, sizeof(devtype)),
37221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->device_name,
37231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->manufacturer,
37241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->model_name,
37251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->model_number,
37261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->serial_number,
37271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->config_methods,
37281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->dev_capab,
37291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->group_capab,
37301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  info->level);
37311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (res < 0 || res >= end - pos)
37321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return pos - buf;
37331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos += res;
37341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3735c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0);
37361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid) {
37371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
37381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (res < 0 || res >= end - pos)
37391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return pos - buf;
37401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos += res;
37411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
37421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	res = p2p_get_peer_info_txt(info, pos, end - pos);
37441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (res < 0)
37451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return pos - buf;
37461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos += res;
37471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return pos - buf;
3749fc41cadcff448cdd2b60e376fc6e7378e2e57b5eDmitry Shmidt}
37501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
375204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
375304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  const char *param)
375404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
375504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_freq_range *freq = NULL, *n;
375604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	unsigned int count = 0, i;
375704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const char *pos, *pos2, *pos3;
375804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
375904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->global->p2p == NULL)
376004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
376104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
376204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/*
376304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * param includes comma separated frequency range.
376404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * For example: 2412-2432,2462,5000-6000
376504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 */
376604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos = param;
376704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (pos && pos[0]) {
376861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		n = os_realloc_array(freq, count + 1,
376961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				     sizeof(struct wpa_freq_range));
377004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (n == NULL) {
377104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_free(freq);
377204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
377304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
377404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		freq = n;
377504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		freq[count].min = atoi(pos);
377604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos2 = os_strchr(pos, '-');
377704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos3 = os_strchr(pos, ',');
377804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (pos2 && (!pos3 || pos2 < pos3)) {
377904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos2++;
378004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			freq[count].max = atoi(pos2);
378104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else
378204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			freq[count].max = freq[count].min;
378304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = pos3;
378404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (pos)
378504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
378604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		count++;
378704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
378804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
378904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < count; i++) {
379004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
379104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   freq[i].min, freq[i].max);
379204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
379304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
379404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(wpa_s->global->p2p_disallow_freq);
379504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->global->p2p_disallow_freq = freq;
379604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->global->num_p2p_disallow_freq = count;
379704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_p2p_update_channel_list(wpa_s);
379804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
379904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
380004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
380104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *param;
38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL)
38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	param = os_strchr(cmd, ' ');
38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param == NULL)
38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*param++ = '\0';
38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "discoverability") == 0) {
38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_client_discoverability(wpa_s->global->p2p,
38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       atoi(param));
38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "managed") == 0) {
38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "listen_channel") == 0) {
38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_set_listen_channel(wpa_s->global->p2p, 81,
38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      atoi(param));
38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "ssid_postfix") == 0) {
38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    os_strlen(param));
38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "noa") == 0) {
38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *pos;
38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int count, start, duration;
38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* GO NoA parameters: count,start_offset(ms),duration(ms) */
38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		count = atoi(param);
38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(param, ',');
38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		start = atoi(pos);
38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, ',');
38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
38478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		duration = atoi(pos);
38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (count < 0 || count > 255 || start < 0 || duration < 0)
38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (count == 0 && duration > 0)
38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "start=%d duration=%d", count, start, duration);
38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_p2p_set_noa(wpa_s, count, start, duration);
38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "ps") == 0)
38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "oppps") == 0)
38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "ctwindow") == 0)
38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "disabled") == 0) {
38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->global->p2p_disabled = atoi(param);
38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P functionality %s",
38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->global->p2p_disabled ?
38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "disabled" : "enabled");
38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->global->p2p_disabled) {
38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_stop_find(wpa_s);
38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_flush(wpa_s->global->p2p);
38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
388004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
38812fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt	if (os_strcmp(cmd, "conc_pref") == 0) {
38822fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt		if (os_strcmp(param, "sta") == 0)
38832fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt			wpa_s->global->conc_pref = WPA_CONC_PREF_STA;
38842fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt		else if (os_strcmp(param, "p2p") == 0)
38852fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt			wpa_s->global->conc_pref = WPA_CONC_PREF_P2P;
3886687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt		else {
38872fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt			wpa_printf(MSG_INFO, "Invalid conc_pref value");
3888687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt			return -1;
3889687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt		}
38902fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Single channel concurrency preference: "
389104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "%s", param);
3892687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt		return 0;
3893687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt	}
389404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "force_long_sd") == 0) {
38968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->force_long_sd = atoi(param);
38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "peer_filter") == 0) {
39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 addr[ETH_ALEN];
39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(param, addr))
39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_peer_filter(wpa_s->global->p2p, addr);
39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "cross_connect") == 0)
39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "go_apsd") == 0) {
39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(param, "disable") == 0)
39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->set_ap_uapsd = 0;
39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->set_ap_uapsd = 1;
39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->ap_uapsd = atoi(param);
39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(cmd, "client_apsd") == 0) {
39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(param, "disable") == 0)
39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->set_sta_uapsd = 0;
39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int be, bk, vi, vo;
39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			char *pos;
39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* format: BE,BK,VI,VO;max SP Length */
39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			be = atoi(param);
39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = os_strchr(param, ',');
39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos == NULL)
39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bk = atoi(pos);
39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = os_strchr(pos, ',');
39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos == NULL)
39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			vi = atoi(pos);
39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = os_strchr(pos, ',');
39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos == NULL)
39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			vo = atoi(pos);
39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* ignore max SP Length for now */
39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->set_sta_uapsd = 1;
39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->sta_uapsd = 0;
39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (be)
39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->sta_uapsd |= BIT(0);
39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bk)
39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->sta_uapsd |= BIT(1);
39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (vi)
39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->sta_uapsd |= BIT(2);
39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (vo)
39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->sta_uapsd |= BIT(3);
39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
396004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strcmp(cmd, "disallow_freq") == 0)
396104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return p2p_ctrl_disallow_freq(wpa_s, param);
396204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cmd);
39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *pos2;
39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmd[0]) {
39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(cmd, ' ');
39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos++ = '\0';
39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dur1 = atoi(cmd);
39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos2 = os_strchr(pos, ' ');
39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos2)
39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos2++ = '\0';
39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int1 = atoi(pos);
39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos2 = NULL;
39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos2) {
39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos2, ' ');
39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos++ = '\0';
39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dur2 = atoi(pos2);
39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int2 = atoi(pos);
39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int period = 0, interval = 0;
40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmd[0]) {
40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(cmd, ' ');
40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos++ = '\0';
40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		period = atoi(cmd);
40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		interval = atoi(pos);
40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_p2p_ext_listen(wpa_s, period, interval);
40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
40231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
40241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
40251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 bssid[ETH_ALEN];
40261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_bss *bss;
40271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hwaddr_aton(dst, bssid)) {
40291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst);
40301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
40311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
40321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	bss = wpa_bss_get_bssid(wpa_s, bssid);
40341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss == NULL) {
40351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR,
40361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   MAC2STR(bssid));
40371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
40381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
40391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return interworking_connect(wpa_s, bss);
40411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
40421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
40451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
40461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 dst_addr[ETH_ALEN];
40471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int used;
40481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char *pos;
40491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define MAX_ANQP_INFO_ID 100
40501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u16 id[MAX_ANQP_INFO_ID];
40511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t num_id = 0;
40521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	used = hwaddr_aton2(dst, dst_addr);
40541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (used < 0)
40551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
40561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = dst + used;
40571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	while (num_id < MAX_ANQP_INFO_ID) {
40581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		id[num_id] = atoi(pos);
40591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (id[num_id])
40601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			num_id++;
40611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos = os_strchr(pos + 1, ',');
40621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (pos == NULL)
40631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
40641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos++;
40651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
40661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (num_id == 0)
40681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
40691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return anqp_send_req(wpa_s, dst_addr, id, num_id);
40711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
407261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
407361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
407461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int gas_request(struct wpa_supplicant *wpa_s, char *cmd)
407561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
407661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	u8 dst_addr[ETH_ALEN];
407761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct wpabuf *advproto, *query = NULL;
407861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int used, ret = -1;
407961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos, *end;
408061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t len;
408161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
408261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	used = hwaddr_aton2(cmd, dst_addr);
408361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (used < 0)
408461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
408561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
408661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = cmd + used;
408761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	while (*pos == ' ')
408861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos++;
408961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
409061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Advertisement Protocol ID */
409161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	end = os_strchr(pos, ' ');
409261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (end)
409361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len = end - pos;
409461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else
409561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len = os_strlen(pos);
409661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (len & 0x01)
409761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
409861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	len /= 2;
409961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (len == 0)
410061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
410161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	advproto = wpabuf_alloc(len);
410261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (advproto == NULL)
410361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
410461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hexstr2bin(pos, wpabuf_put(advproto, len), len) < 0)
410561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
410661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
410761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (end) {
410861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* Optional Query Request */
410961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = end + 1;
411061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		while (*pos == ' ')
411161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos++;
411261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
411361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len = os_strlen(pos);
411461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (len) {
411561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (len & 0x01)
411661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
411761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			len /= 2;
411861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (len == 0)
411961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
412061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			query = wpabuf_alloc(len);
412161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (query == NULL)
412261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
412361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hexstr2bin(pos, wpabuf_put(query, len), len) < 0)
412461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
412561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
412661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
412761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
412861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ret = gas_send_request(wpa_s, dst_addr, advproto, query);
412961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
413061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail:
413161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpabuf_free(advproto);
413261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpabuf_free(query);
413361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
413461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return ret;
413561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
413661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
413761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
413861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
413961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    size_t buflen)
414061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
414161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	u8 addr[ETH_ALEN];
414261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int dialog_token;
414361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int used;
414461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos;
414561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t resp_len, start, requested_len;
414661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
414761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (!wpa_s->last_gas_resp)
414861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
414961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
415061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	used = hwaddr_aton2(cmd, addr);
415161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (used < 0)
415261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
415361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
415461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = cmd + used;
415561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	while (*pos == ' ')
415661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos++;
415761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	dialog_token = atoi(pos);
415861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
415961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) != 0 ||
416061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    dialog_token != wpa_s->last_gas_dialog_token)
416161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
416261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
416361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	resp_len = wpabuf_len(wpa_s->last_gas_resp);
416461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	start = 0;
416561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	requested_len = resp_len;
416661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
416761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ' ');
416861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos) {
416961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		start = atoi(pos);
417061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (start > resp_len)
417161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return os_snprintf(buf, buflen, "FAIL-Invalid range");
417261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = os_strchr(pos, ',');
417361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (pos == NULL)
417461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return -1;
417561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos++;
417661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		requested_len = atoi(pos);
417761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (start + requested_len > resp_len)
417861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return os_snprintf(buf, buflen, "FAIL-Invalid range");
417961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
418061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
418161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (requested_len * 2 + 1 > buflen)
418261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return os_snprintf(buf, buflen, "FAIL-Too long response");
418361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
418461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return wpa_snprintf_hex(buf, buflen,
418561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpabuf_head_u8(wpa_s->last_gas_resp) + start,
418661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				requested_len);
418761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
41881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
41891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
41901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
419104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
419204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
419304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int get_hs20_anqp(struct wpa_supplicant *wpa_s, char *dst)
419404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
419504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 dst_addr[ETH_ALEN];
419604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int used;
419704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *pos;
419804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u32 subtypes = 0;
419904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
420004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	used = hwaddr_aton2(dst, dst_addr);
420104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (used < 0)
420204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
420304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos = dst + used;
420404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (;;) {
420504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int num = atoi(pos);
420604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (num <= 0 || num > 31)
420704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
420804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		subtypes |= BIT(num);
420904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = os_strchr(pos + 1, ',');
421004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (pos == NULL)
421104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
421204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos++;
421304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
421404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
421504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (subtypes == 0)
421604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
421704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
421804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hs20_anqp_send_req(wpa_s, dst_addr, subtypes, NULL, 0);
421904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
422004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
422104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
422204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hs20_nai_home_realm_list(struct wpa_supplicant *wpa_s,
422304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    const u8 *addr, const char *realm)
422404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
422504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 *buf;
422604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t rlen, len;
422704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ret;
422804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
422904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	rlen = os_strlen(realm);
423004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = 3 + rlen;
423104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf = os_malloc(len);
423204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (buf == NULL)
423304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
423404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf[0] = 1; /* NAI Home Realm Count */
423504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf[1] = 0; /* Formatted in accordance with RFC 4282 */
423604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf[2] = rlen;
423704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_memcpy(buf + 3, realm, rlen);
423804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
423904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = hs20_anqp_send_req(wpa_s, addr,
424004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
424104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 buf, len);
424204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
424304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(buf);
424404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
424504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return ret;
424604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
424704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
424804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
424904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s,
425004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					char *dst)
425104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
425204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_cred *cred = wpa_s->conf->cred;
425304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 dst_addr[ETH_ALEN];
425404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int used;
425504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 *buf;
425604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
425704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int ret;
425804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
425904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	used = hwaddr_aton2(dst, dst_addr);
426004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (used < 0)
426104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
426204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
426304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (dst[used] == ' ')
426404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		used++;
426504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strncmp(dst + used, "realm=", 6) == 0)
426604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return hs20_nai_home_realm_list(wpa_s, dst_addr,
426704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						dst + used + 6);
426804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
426904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = os_strlen(dst + used);
427004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
427104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len == 0 && cred && cred->realm)
427204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm);
427304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
427404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len % 1)
427504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
427604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len /= 2;
427704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	buf = os_malloc(len);
427804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (buf == NULL)
427904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
428004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hexstr2bin(dst + used, buf, len) < 0) {
428104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(buf);
428204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
428304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
428404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
428504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = hs20_anqp_send_req(wpa_s, dst_addr,
428604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
428704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 buf, len);
428804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(buf);
428904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
429004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return ret;
429104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
429204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
429304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
429404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
429504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ctrl_iface_sta_autoconnect(
42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, char *cmd)
42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
42998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
43008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
43018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
430404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN
430504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
430604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant *wpa_s,
430704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      char *cmd)
430804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
430904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	enum wpa_states state = wpa_s->wpa_state;
431004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *new_params = NULL;
431104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
431204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strlen(cmd) > 0) {
431304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		new_params = os_strdup(cmd);
431404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (new_params == NULL)
431504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
431604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
431704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
431804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(wpa_s->conf->autoscan);
431904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->conf->autoscan = new_params;
432004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
432104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->autoscan == NULL)
432204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		autoscan_deinit(wpa_s);
432304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
432404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		autoscan_init(wpa_s, 1);
432504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (state == WPA_SCANNING)
432604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_reinit_autoscan(wpa_s);
432704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
432804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
432904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
433004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
433104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN */
433204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
433304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
43348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
43358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      size_t buflen)
43368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
43378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_signal_info si;
43388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
43398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpa_drv_signal_poll(wpa_s, &si);
43418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret)
43428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
43438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n"
43458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "NOISE=%d\nFREQUENCY=%u\n",
43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  si.current_signal, si.current_txrate / 1000,
43478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  si.current_noise, si.frequency);
43488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || (unsigned int) ret > buflen)
43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
43508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
43518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
43528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43531e6c57fee4a56b421cc20f6dc0785c9138b21337Jouni Malinen
4354fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zhengstatic int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
4355fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng				      size_t buflen)
4356fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng{
4357fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	struct hostap_sta_driver_data sta;
4358fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	int ret;
4359fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng
4360fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	ret = wpa_drv_pktcnt_poll(wpa_s, &sta);
4361fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	if (ret)
4362fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng		return -1;
4363fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng
4364fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n",
43651e6c57fee4a56b421cc20f6dc0785c9138b21337Jouni Malinen			  sta.tx_packets, sta.tx_retry_failed, sta.rx_packets);
43661e6c57fee4a56b421cc20f6dc0785c9138b21337Jouni Malinen	if (ret < 0 || (size_t) ret > buflen)
4367fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng		return -1;
4368fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	return ret;
4369fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng}
4370fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng
4371fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng
43721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID
4373bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidtstatic int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
4374bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt				     char *buf, size_t buflen)
4375bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt{
4376bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt	int ret;
4377bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt
4378bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt	ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
4379bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt	if (ret == 0)
4380bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt		ret = sprintf(buf, "%s\n", "OK");
4381bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt	return ret;
4382bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt}
43831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif
4384bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt
43854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt
43868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
43878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 char *buf, size_t *resp_len)
43888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *reply;
43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const int reply_size = 4096;
43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ctrl_rsp = 0;
43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reply_len;
43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
43958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
43968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
43978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      (const u8 *) buf, os_strlen(buf));
43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
43998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int level = MSG_DEBUG;
44008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(buf, "PING") == 0)
44018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			level = MSG_EXCESSIVE;
44028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(level, "RX ctrl_iface",
44038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (const u8 *) buf, os_strlen(buf));
4404aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, level, "Control interface command '%s'", buf);
44058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
44068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = os_malloc(reply_size);
44088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply == NULL) {
44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*resp_len = 1;
44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
44118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
44128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(reply, "OK\n", 3);
44148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply_len = 3;
44158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(buf, "PING") == 0) {
44178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "PONG\n", 5);
44188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 5;
441961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strcmp(buf, "IFNAME") == 0) {
442061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		reply_len = os_strlen(wpa_s->ifname);
442161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(reply, wpa_s->ifname, reply_len);
44228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "RELOG", 5) == 0) {
44238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_debug_reopen_file() < 0)
44248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
44268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
44278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "MIB") == 0) {
44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
44298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (reply_len >= 0) {
44308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int res;
44318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       reply_size - reply_len);
44338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (res < 0)
44348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				reply_len = -1;
44358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
44368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				reply_len += res;
44378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
44388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
44398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_status(
44408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 6, reply, reply_size);
44418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "PMKSA") == 0) {
44428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
44438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    reply_size);
44448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "SET ", 4) == 0) {
44458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
44468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "GET ", 4) == 0) {
44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							  reply, reply_size);
44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "LOGON") == 0) {
44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
44528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "LOGOFF") == 0) {
44538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
44548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "REASSOCIATE") == 0) {
44551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->normal_scans = 0;
445604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_reinit_autoscan(wpa_s);
44578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
44588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->disconnected = 0;
44618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->reassociate = 1;
44628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
44638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
44648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "RECONNECT") == 0) {
44651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->normal_scans = 0;
446604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_reinit_autoscan(wpa_s);
44678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
44688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (wpa_s->disconnected) {
44708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->disconnected = 0;
44718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->reassociate = 1;
44728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
44738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
44748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
44758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
44768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
44778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
44808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
44818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
44828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
44848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
44858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
44868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
44878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
44898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
44908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "WPS_PBC") == 0) {
44918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL);
44928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res == -2) {
44938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
44948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = 17;
44958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (res)
44968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
44978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
44988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8);
44998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res == -2) {
45008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
45018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = 17;
45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (res)
45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							      reply,
45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							      reply_size);
45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
45098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 14, reply, reply_size);
45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_cancel(wpa_s))
45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_OOB
45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
45168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_OOB */
451904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
452004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcmp(buf, "WPS_NFC") == 0) {
452104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, NULL))
452204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
452304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
452404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
452504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
452604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
452704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
452804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s, buf + 14, reply, reply_size);
452904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) {
453004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s,
453104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							       buf + 17))
453204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
453304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
45348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
45358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
45368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
45388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
45398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
45408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 11, reply, reply_size);
45418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
45428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_ER
45438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "WPS_ER_START") == 0) {
45448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_er_start(wpa_s, NULL))
45458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
45478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_er_start(wpa_s, buf + 13))
45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_er_stop(wpa_s))
45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
45538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
45548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == -2) {
45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = 17;
45608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (ret == -3) {
45618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
45628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = 18;
45638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (ret == -4) {
45648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
45658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = 20;
45668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (ret)
45678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
45698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
45708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
45728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
45738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								buf + 18))
45748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
45768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
45778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
457804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
457904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) {
458004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
458104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s, buf + 24, reply, reply_size);
458204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
45838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_ER */
45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
45908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
45918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
45928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_find(wpa_s, buf + 9))
45938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_FIND") == 0) {
45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_find(wpa_s, ""))
45968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_stop_find(wpa_s);
45998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
46008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
46018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     reply_size);
46028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
46038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_listen(wpa_s, buf + 11))
46048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
46068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_listen(wpa_s, ""))
46078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
46098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_group_remove(wpa_s, buf + 17))
46108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
461261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpas_p2p_group_add(wpa_s, 0, 0, 0))
46138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
46158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_group_add(wpa_s, buf + 14))
46168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
46188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
46218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
46228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
46238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
46248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   reply_size);
46258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
46268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
46278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
46298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
46308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
4632b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P
4633b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt		wpas_p2p_sd_service_update(wpa_s, SRV_UPDATE);
4634b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else
46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_sd_service_update(wpa_s);
4636b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif
46378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
46398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_service_flush(wpa_s);
46428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
46448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
46498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
46558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
46568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      reply_size);
46578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
46588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
46598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
46618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
46628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->force_long_sd = 0;
46638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->global->p2p)
46648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_flush(wpa_s->global->p2p);
46658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
46668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
46698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_cancel(wpa_s))
46708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
46728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
46738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
46758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_presence_req(wpa_s, "") < 0)
46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
46788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
46798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
46818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
46828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
46838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
468461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
468561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) {
468661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wifi_display_subelem_set(wpa_s->global, buf + 16) < 0)
468761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			reply_len = -1;
468861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) {
468961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		reply_len = wifi_display_subelem_get(wpa_s->global, buf + 16,
469061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						     reply, reply_size);
469161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
46921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
46931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strcmp(buf, "FETCH_ANQP") == 0) {
46941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (interworking_fetch_anqp(wpa_s) < 0)
46951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply_len = -1;
46961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
46971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		interworking_stop_fetch_anqp(wpa_s);
46981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) {
46991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") !=
47001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					NULL) < 0)
47011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply_len = -1;
47021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
47031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ctrl_interworking_connect(wpa_s, buf + 21) < 0)
47041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply_len = -1;
47051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) {
47061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (get_anqp(wpa_s, buf + 9) < 0)
47071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply_len = -1;
470861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strncmp(buf, "GAS_REQUEST ", 12) == 0) {
470961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (gas_request(wpa_s, buf + 12) < 0)
471061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			reply_len = -1;
471161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (os_strncmp(buf, "GAS_RESPONSE_GET ", 17) == 0) {
471261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		reply_len = gas_response_get(wpa_s, buf + 17, reply,
471361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					     reply_size);
47141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
471504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
471604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "HS20_ANQP_GET ", 14) == 0) {
471704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (get_hs20_anqp(wpa_s, buf + 14) < 0)
471804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
471904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) {
472004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0)
472104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
472204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
47238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
47248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
47258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_ctrl_rsp(
47268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
47278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
47298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ctrl_rsp = 1;
47308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "RECONFIGURE") == 0) {
47318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_reload_configuration(wpa_s))
47328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "TERMINATE") == 0) {
47348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_terminate_proc(wpa_s->global);
47358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "BSSID ", 6) == 0) {
47368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
47378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
4738e19501da312b59453448d587376062d5b3053a58Dmitry Shmidt	} else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
47391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_blacklist(
47401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, buf + 9, reply, reply_size);
47411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
47421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_log_level(
47431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, buf + 9, reply, reply_size);
47448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
47458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_list_networks(
47468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, reply, reply_size);
47478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "DISCONNECT") == 0) {
474804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
474904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sme.prev_bssid_set = 0;
475004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
47518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 0;
47528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->disconnected = 1;
47531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
475404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_cancel_scan(wpa_s);
47558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
47568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
47578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "SCAN") == 0) {
47588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
47598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
47618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_s->scanning &&
47628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    ((wpa_s->wpa_state <= WPA_SCANNING) ||
47638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     (wpa_s->wpa_state == WPA_COMPLETED))) {
476404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->normal_scans = 0;
476504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_s->scan_req = 2;
476604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_supplicant_req_scan(wpa_s, 0, 0);
476704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			} else if (wpa_s->sched_scanning) {
476804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_DEBUG, "Stop ongoing "
476904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "sched_scan to allow requested "
477004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "full scan to proceed");
477104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_supplicant_cancel_sched_scan(wpa_s);
47728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->scan_req = 2;
47738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_req_scan(wpa_s, 0, 0);
47748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
47758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Ongoing scan action - "
47768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "reject new request");
47778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				reply_len = os_snprintf(reply, reply_size,
47788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							"FAIL-BUSY\n");
47798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
47808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
47818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
47828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_scan_results(
47838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, reply, reply_size);
47848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
47858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
47868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
47888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
47898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
47918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
47928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
47948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_add_network(
47958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, reply, reply_size);
47968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
47978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
47988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
47998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
48008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
48018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
48038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_get_network(
48048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 12, reply, reply_size);
480504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcmp(buf, "LIST_CREDS") == 0) {
480604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_list_creds(
480704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s, reply, reply_size);
480804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strcmp(buf, "ADD_CRED") == 0) {
480904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_add_cred(
481004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s, reply, reply_size);
481104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) {
481204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12))
481304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
481404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "SET_CRED ", 9) == 0) {
481504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9))
481604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
48178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE
48188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
48198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
48208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */
48228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
48238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_get_capability(
48248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 15, reply, reply_size);
48258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
48268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
48278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) {
48298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14))
48308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
48328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_global_iface_list(
48338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->global, reply, reply_size);
48348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "INTERFACES") == 0) {
48358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_global_iface_interfaces(
48368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->global, reply, reply_size);
48378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "BSS ", 4) == 0) {
48388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_ctrl_iface_bss(
48398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, buf + 4, reply, reply_size);
48408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
48418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
48428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
48438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "STA ", 4) == 0) {
48448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
48458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      reply_size);
48468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
48478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
48488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   reply_size);
484904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
485004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15))
485104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
485204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
485304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13))
485404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
48558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
48568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "SUSPEND") == 0) {
48578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_suspend(wpa_s->global);
48588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "RESUME") == 0) {
48598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_resume(wpa_s->global);
48608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "DROP_SA") == 0) {
48618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
48628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "ROAM ", 5) == 0) {
48638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
48648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
48668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
48678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
48698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
48708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
48728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s,
48738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							       buf + 17))
48748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
4875f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt	} else if (os_strncmp(buf, "BSS_FLUSH ", 10) == 0) {
4876f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt		if (wpa_supplicant_ctrl_iface_bss_flush(wpa_s, buf + 10))
4877f48e4f901d4b39a4e03210fe0154cdb11112e22eDmitry Shmidt			reply_len = -1;
48788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
48798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
48808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
48818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
48838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
48868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
48878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
48888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
48898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
48908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
48918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       reply_size);
4892fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng	} else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) {
4893fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng		reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply,
4894fcd6f21dad589eb6fdba941c98e072ca2664726bYuhao Zheng						       reply_size);
489504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN
489604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) {
489704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
489804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			reply_len = -1;
489904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN */
4900c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID
4901bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt	} else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
4902bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt		reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
4903bd567ad93e03f285fdad93464100148cd5ae7941Dmitry Shmidt						      reply_size);
4904c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif
49051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
49061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		eapol_sm_request_reauth(wpa_s->eapol);
49078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
49088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
49098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 16;
49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply_len < 0) {
49138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "FAIL\n", 5);
49148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 5;
49158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ctrl_rsp)
49188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_ctrl_response(wpa_s->eapol);
49198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*resp_len = reply_len;
49218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
49228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
49238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_add(struct wpa_global *global,
49268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   char *cmd)
49278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
49288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface iface;
49298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
49308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TAB<bridge_ifname>
49348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
49358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
49368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&iface, 0, sizeof(iface));
49388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	do {
49408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.ifname = pos = cmd;
49418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.ifname[0] == '\0')
49458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
49468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.confname = pos;
49508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.confname[0] == '\0')
49548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface.confname = NULL;
49558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.driver = pos;
49598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.driver[0] == '\0')
49638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface.driver = NULL;
49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.ctrl_interface = pos;
49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.ctrl_interface[0] == '\0')
49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface.ctrl_interface = NULL;
49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.driver_param = pos;
49778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.driver_param[0] == '\0')
49818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface.driver_param = NULL;
49828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.bridge_ifname = pos;
49868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(pos, '\t');
49878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
49888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos++ = '\0';
49898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface.bridge_ifname[0] == '\0')
49908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface.bridge_ifname = NULL;
49918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
49928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
49938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} while (0);
49948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_get_iface(global, iface.ifname))
49968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
49978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
49998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_remove(struct wpa_global *global,
50038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      char *cmd)
50048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
50068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
50088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpa_supplicant_get_iface(global, cmd);
50108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
50118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5012e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	return wpa_supplicant_remove_iface(global, wpa_s, 0);
50138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_free_iface_info(struct wpa_interface_info *iface)
50178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface_info *prev;
50198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (iface) {
50218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev = iface;
50228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface = iface->next;
50238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(prev->ifname);
50258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(prev->desc);
50268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(prev);
50278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_list(struct wpa_global *global,
50328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    char *buf, int len)
50338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, res;
50358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
50368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
50378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i]; i++) {
50398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_driver_ops *drv = wpa_drivers[i];
50408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (drv->get_interfaces == NULL)
50418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
50428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tmp = drv->get_interfaces(global->drv_priv[i]);
50438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (tmp == NULL)
50448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
50458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (last == NULL)
50478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface = last = tmp;
50488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
50498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			last->next = tmp;
50508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (last->next)
50518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			last = last->next;
50528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
50558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + len;
50568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (tmp = iface; tmp; tmp = tmp->next) {
50578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
50588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  tmp->drv_name, tmp->ifname,
50598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  tmp->desc ? tmp->desc : "");
50608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res < 0 || res >= end - pos) {
50618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos = '\0';
50628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
50638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
50648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += res;
50658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_free_iface_info(iface);
50688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
50708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
50748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  char *buf, int len)
50758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
50778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
50788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
50798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = global->ifaces;
50818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = buf;
50828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = buf + len;
50838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_s) {
50858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
50868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res < 0 || res >= end - pos) {
50878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos = '\0';
50888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
50898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
50908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += res;
50918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = wpa_s->next;
50928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
50948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
50988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						char *buf, size_t *resp_len)
50998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
51008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *reply;
51018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const int reply_size = 2048;
51028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reply_len;
51031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int level = MSG_DEBUG;
51048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (os_strcmp(buf, "PING") == 0)
51061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		level = MSG_EXCESSIVE;
51071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_hexdump_ascii(level, "RX global ctrl_iface",
51088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  (const u8 *) buf, os_strlen(buf));
51098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = os_malloc(reply_size);
51118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply == NULL) {
51128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*resp_len = 1;
51138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
51148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
51158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(reply, "OK\n", 3);
51178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply_len = 3;
51188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(buf, "PING") == 0) {
51208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "PONG\n", 5);
51218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 5;
51228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
51238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_global_iface_add(global, buf + 14))
51248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
51258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
51268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_global_iface_remove(global, buf + 17))
51278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply_len = -1;
51288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
51298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_global_iface_list(
51308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			global, reply, reply_size);
51318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "INTERFACES") == 0) {
51328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = wpa_supplicant_global_iface_interfaces(
51338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			global, reply, reply_size);
51348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "TERMINATE") == 0) {
51358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_terminate_proc(global);
51368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "SUSPEND") == 0) {
51378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_suspend(global);
51388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(buf, "RESUME") == 0) {
51398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_resume(global);
51408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
51418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
51428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 16;
51438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
51448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply_len < 0) {
51468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(reply, "FAIL\n", 5);
51478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply_len = 5;
51488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
51498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
51508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*resp_len = reply_len;
51518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
51528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5153