Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant / Control interface (shared code for all backends)
      3  * Copyright (c) 2004-2010, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #include "utils/includes.h"
     16 
     17 #include "utils/common.h"
     18 #include "utils/eloop.h"
     19 #include "common/version.h"
     20 #include "common/ieee802_11_defs.h"
     21 #include "common/wpa_ctrl.h"
     22 #include "eap_peer/eap.h"
     23 #include "eapol_supp/eapol_supp_sm.h"
     24 #include "rsn_supp/wpa.h"
     25 #include "rsn_supp/preauth.h"
     26 #include "rsn_supp/pmksa_cache.h"
     27 #include "l2_packet/l2_packet.h"
     28 #include "wps/wps.h"
     29 #include "config.h"
     30 #include "wpa_supplicant_i.h"
     31 #include "driver_i.h"
     32 #include "wps_supplicant.h"
     33 #include "ibss_rsn.h"
     34 #include "ap.h"
     35 #include "p2p_supplicant.h"
     36 #include "p2p/p2p.h"
     37 #include "notify.h"
     38 #include "bss.h"
     39 #include "scan.h"
     40 #include "ctrl_iface.h"
     41 #include "blacklist.h"
     42 
     43 extern struct wpa_driver_ops *wpa_drivers[];
     44 
     45 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
     46 					    char *buf, int len);
     47 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
     48 						  char *buf, int len);
     49 
     50 
     51 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
     52 					 char *cmd)
     53 {
     54 	char *value;
     55 	int ret = 0;
     56 
     57 	value = os_strchr(cmd, ' ');
     58 	if (value == NULL)
     59 		return -1;
     60 	*value++ = '\0';
     61 
     62 	wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
     63 	if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
     64 		eapol_sm_configure(wpa_s->eapol,
     65 				   atoi(value), -1, -1, -1);
     66 	} else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
     67 		eapol_sm_configure(wpa_s->eapol,
     68 				   -1, atoi(value), -1, -1);
     69 	} else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
     70 		eapol_sm_configure(wpa_s->eapol,
     71 				   -1, -1, atoi(value), -1);
     72 	} else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
     73 		eapol_sm_configure(wpa_s->eapol,
     74 				   -1, -1, -1, atoi(value));
     75 	} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
     76 		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
     77 				     atoi(value)))
     78 			ret = -1;
     79 	} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
     80 		   0) {
     81 		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
     82 				     atoi(value)))
     83 			ret = -1;
     84 	} else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
     85 		if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
     86 			ret = -1;
     87 	} else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
     88 		wpa_s->wps_fragment_size = atoi(value);
     89 #ifdef CONFIG_WPS_TESTING
     90 	} else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
     91 		long int val;
     92 		val = strtol(value, NULL, 0);
     93 		if (val < 0 || val > 0xff) {
     94 			ret = -1;
     95 			wpa_printf(MSG_DEBUG, "WPS: Invalid "
     96 				   "wps_version_number %ld", val);
     97 		} else {
     98 			wps_version_number = val;
     99 			wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
    100 				   "version %u.%u",
    101 				   (wps_version_number & 0xf0) >> 4,
    102 				   wps_version_number & 0x0f);
    103 		}
    104 	} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
    105 		wps_testing_dummy_cred = atoi(value);
    106 		wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
    107 			   wps_testing_dummy_cred);
    108 #endif /* CONFIG_WPS_TESTING */
    109 	} else if (os_strcasecmp(cmd, "ampdu") == 0) {
    110 		if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
    111 			ret = -1;
    112 #ifdef CONFIG_TDLS_TESTING
    113 	} else if (os_strcasecmp(cmd, "tdls_testing") == 0) {
    114 		extern unsigned int tdls_testing;
    115 		tdls_testing = strtol(value, NULL, 0);
    116 		wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing);
    117 #endif /* CONFIG_TDLS_TESTING */
    118 #ifdef CONFIG_TDLS
    119 	} else if (os_strcasecmp(cmd, "tdls_disabled") == 0) {
    120 		int disabled = atoi(value);
    121 		wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled);
    122 		if (disabled) {
    123 			if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0)
    124 				ret = -1;
    125 		} else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0)
    126 			ret = -1;
    127 		wpa_tdls_enable(wpa_s->wpa, !disabled);
    128 #endif /* CONFIG_TDLS */
    129 	} else {
    130 		value[-1] = '=';
    131 		ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
    132 		if (ret == 0)
    133 			wpa_supplicant_update_config(wpa_s);
    134 	}
    135 
    136 	return ret;
    137 }
    138 
    139 
    140 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
    141 					 char *cmd, char *buf, size_t buflen)
    142 {
    143 	int res = -1;
    144 
    145 	wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
    146 
    147 	if (os_strcmp(cmd, "version") == 0) {
    148 		res = os_snprintf(buf, buflen, "%s", VERSION_STR);
    149 	} else if (os_strcasecmp(cmd, "country") == 0) {
    150 		if (wpa_s->conf->country[0] && wpa_s->conf->country[1])
    151 			res = os_snprintf(buf, buflen, "%c%c",
    152 					  wpa_s->conf->country[0],
    153 					  wpa_s->conf->country[1]);
    154 	}
    155 
    156 	if (res < 0 || (unsigned int) res >= buflen)
    157 		return -1;
    158 	return res;
    159 }
    160 
    161 
    162 #ifdef IEEE8021X_EAPOL
    163 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
    164 					     char *addr)
    165 {
    166 	u8 bssid[ETH_ALEN];
    167 	struct wpa_ssid *ssid = wpa_s->current_ssid;
    168 
    169 	if (hwaddr_aton(addr, bssid)) {
    170 		wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
    171 			   "'%s'", addr);
    172 		return -1;
    173 	}
    174 
    175 	wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
    176 	rsn_preauth_deinit(wpa_s->wpa);
    177 	if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
    178 		return -1;
    179 
    180 	return 0;
    181 }
    182 #endif /* IEEE8021X_EAPOL */
    183 
    184 
    185 #ifdef CONFIG_PEERKEY
    186 /* MLME-STKSTART.request(peer) */
    187 static int wpa_supplicant_ctrl_iface_stkstart(
    188 	struct wpa_supplicant *wpa_s, char *addr)
    189 {
    190 	u8 peer[ETH_ALEN];
    191 
    192 	if (hwaddr_aton(addr, peer)) {
    193 		wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
    194 			   "address '%s'", addr);
    195 		return -1;
    196 	}
    197 
    198 	wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
    199 		   MAC2STR(peer));
    200 
    201 	return wpa_sm_stkstart(wpa_s->wpa, peer);
    202 }
    203 #endif /* CONFIG_PEERKEY */
    204 
    205 
    206 #ifdef CONFIG_TDLS
    207 
    208 static int wpa_supplicant_ctrl_iface_tdls_discover(
    209 	struct wpa_supplicant *wpa_s, char *addr)
    210 {
    211 	u8 peer[ETH_ALEN];
    212 
    213 	if (hwaddr_aton(addr, peer)) {
    214 		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
    215 			   "address '%s'", addr);
    216 		return -1;
    217 	}
    218 
    219 	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
    220 		   MAC2STR(peer));
    221 
    222 	return wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
    223 }
    224 
    225 
    226 static int wpa_supplicant_ctrl_iface_tdls_setup(
    227 	struct wpa_supplicant *wpa_s, char *addr)
    228 {
    229 	u8 peer[ETH_ALEN];
    230 	int ret;
    231 
    232 	if (hwaddr_aton(addr, peer)) {
    233 		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
    234 			   "address '%s'", addr);
    235 		return -1;
    236 	}
    237 
    238 	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
    239 		   MAC2STR(peer));
    240 
    241 	ret = wpa_tdls_reneg(wpa_s->wpa, peer);
    242 	if (ret)
    243 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
    244 	return ret;
    245 }
    246 
    247 
    248 static int wpa_supplicant_ctrl_iface_tdls_teardown(
    249 	struct wpa_supplicant *wpa_s, char *addr)
    250 {
    251 	u8 peer[ETH_ALEN];
    252 
    253 	if (hwaddr_aton(addr, peer)) {
    254 		wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
    255 			   "address '%s'", addr);
    256 		return -1;
    257 	}
    258 
    259 	wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
    260 		   MAC2STR(peer));
    261 
    262 	return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
    263 }
    264 
    265 #endif /* CONFIG_TDLS */
    266 
    267 
    268 #ifdef CONFIG_IEEE80211R
    269 static int wpa_supplicant_ctrl_iface_ft_ds(
    270 	struct wpa_supplicant *wpa_s, char *addr)
    271 {
    272 	u8 target_ap[ETH_ALEN];
    273 	struct wpa_bss *bss;
    274 	const u8 *mdie;
    275 
    276 	if (hwaddr_aton(addr, target_ap)) {
    277 		wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
    278 			   "address '%s'", addr);
    279 		return -1;
    280 	}
    281 
    282 	wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
    283 
    284 	bss = wpa_bss_get_bssid(wpa_s, target_ap);
    285 	if (bss)
    286 		mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
    287 	else
    288 		mdie = NULL;
    289 
    290 	return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
    291 }
    292 #endif /* CONFIG_IEEE80211R */
    293 
    294 
    295 #ifdef CONFIG_WPS
    296 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
    297 					     char *cmd)
    298 {
    299 	u8 bssid[ETH_ALEN], *_bssid = bssid;
    300 #ifdef CONFIG_P2P
    301 	u8 p2p_dev_addr[ETH_ALEN];
    302 #endif /* CONFIG_P2P */
    303 #ifdef CONFIG_AP
    304 	u8 *_p2p_dev_addr = NULL;
    305 #endif /* CONFIG_AP */
    306 #ifdef ANDROID_BRCM_P2P_PATCH
    307 	struct wpa_supplicant *iface;
    308 #endif
    309 	if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
    310 		_bssid = NULL;
    311 #ifdef CONFIG_P2P
    312 	} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
    313 		if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
    314 			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
    315 				   "P2P Device Address '%s'",
    316 				   cmd + 13);
    317 			return -1;
    318 		}
    319 		_p2p_dev_addr = p2p_dev_addr;
    320 #endif /* CONFIG_P2P */
    321 	} else if (hwaddr_aton(cmd, bssid)) {
    322 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
    323 			   cmd);
    324 		return -1;
    325 	}
    326 
    327 #if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
    328 	for (iface = wpa_s->global->ifaces; iface; iface = iface->next)	{
    329 		if (iface->ap_iface){
    330 			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: iface 0x%08x wpa_s->ap_iface %p", (u32)iface, iface->ap_iface);
    331 			wpa_supplicant_ap_wps_pbc(iface, _bssid, _p2p_dev_addr);
    332 			return 0;
    333 		}
    334 		else
    335 			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: ap_iface is not set iface 0x%08x", (u32)iface);
    336 	}
    337 #elif defined CONFIG_AP
    338 	if (wpa_s->ap_iface)
    339 		return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
    340 #endif /* CONFIG_AP */
    341 
    342 	return wpas_wps_start_pbc(wpa_s, _bssid, 0);
    343 }
    344 
    345 
    346 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
    347 					     char *cmd, char *buf,
    348 					     size_t buflen)
    349 {
    350 	u8 bssid[ETH_ALEN], *_bssid = bssid;
    351 	char *pin;
    352 	int ret;
    353 
    354 #if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
    355 	struct wpa_supplicant *iface;
    356 #endif
    357 
    358 	pin = os_strchr(cmd, ' ');
    359 	if (pin)
    360 		*pin++ = '\0';
    361 
    362 	if (os_strcmp(cmd, "any") == 0)
    363 		_bssid = NULL;
    364 	else if (hwaddr_aton(cmd, bssid)) {
    365 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
    366 			   cmd);
    367 		return -1;
    368 	}
    369 
    370 #if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
    371 	for (iface = wpa_s->global->ifaces; iface; iface = iface->next)	{
    372 		if (iface->ap_iface){
    373 			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: iface 0x%08x wpa_s->ap_iface %p", (u32)iface, iface->ap_iface);
    374 			/* Call the wps registrar for the main interface */
    375 			wpa_supplicant_ap_wps_pin(iface, _bssid, pin,
    376 							 buf, buflen);
    377 			return 0;
    378 		}
    379 		else
    380 			wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: ap_iface is not set iface 0x%08x", (u32)iface);
    381 	}
    382 #elif defined CONFIG_AP
    383 	if (wpa_s->ap_iface)
    384 		return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
    385 						 buf, buflen);
    386 #endif /* CONFIG_AP */
    387 
    388 	if (pin) {
    389 		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
    390 					 DEV_PW_DEFAULT);
    391 		if (ret < 0)
    392 			return -1;
    393 		ret = os_snprintf(buf, buflen, "%s", pin);
    394 		if (ret < 0 || (size_t) ret >= buflen)
    395 			return -1;
    396 		return ret;
    397 	}
    398 
    399 	ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
    400 	if (ret < 0)
    401 		return -1;
    402 
    403 	/* Return the generated PIN */
    404 	ret = os_snprintf(buf, buflen, "%08d", ret);
    405 	if (ret < 0 || (size_t) ret >= buflen)
    406 		return -1;
    407 	return ret;
    408 }
    409 
    410 
    411 static int wpa_supplicant_ctrl_iface_wps_check_pin(
    412 	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
    413 {
    414 	char pin[9];
    415 	size_t len;
    416 	char *pos;
    417 	int ret;
    418 
    419 	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
    420 			      (u8 *) cmd, os_strlen(cmd));
    421 	for (pos = cmd, len = 0; *pos != '\0'; pos++) {
    422 		if (*pos < '0' || *pos > '9')
    423 			continue;
    424 		pin[len++] = *pos;
    425 		if (len == 9) {
    426 			wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
    427 			return -1;
    428 		}
    429 	}
    430 	if (len != 4 && len != 8) {
    431 		wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
    432 		return -1;
    433 	}
    434 	pin[len] = '\0';
    435 
    436 	if (len == 8) {
    437 		unsigned int pin_val;
    438 		pin_val = atoi(pin);
    439 		if (!wps_pin_valid(pin_val)) {
    440 			wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
    441 			ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
    442 			if (ret < 0 || (size_t) ret >= buflen)
    443 				return -1;
    444 			return ret;
    445 		}
    446 	}
    447 
    448 	ret = os_snprintf(buf, buflen, "%s", pin);
    449 	if (ret < 0 || (size_t) ret >= buflen)
    450 		return -1;
    451 
    452 	return ret;
    453 }
    454 
    455 
    456 #ifdef CONFIG_WPS_OOB
    457 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
    458 					     char *cmd)
    459 {
    460 	char *path, *method, *name;
    461 
    462 	path = os_strchr(cmd, ' ');
    463 	if (path == NULL)
    464 		return -1;
    465 	*path++ = '\0';
    466 
    467 	method = os_strchr(path, ' ');
    468 	if (method == NULL)
    469 		return -1;
    470 	*method++ = '\0';
    471 
    472 	name = os_strchr(method, ' ');
    473 	if (name != NULL)
    474 		*name++ = '\0';
    475 
    476 	return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
    477 }
    478 #endif /* CONFIG_WPS_OOB */
    479 
    480 
    481 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
    482 					     char *cmd)
    483 {
    484 	u8 bssid[ETH_ALEN];
    485 	char *pin;
    486 	char *new_ssid;
    487 	char *new_auth;
    488 	char *new_encr;
    489 	char *new_key;
    490 	struct wps_new_ap_settings ap;
    491 
    492 	pin = os_strchr(cmd, ' ');
    493 	if (pin == NULL)
    494 		return -1;
    495 	*pin++ = '\0';
    496 
    497 	if (hwaddr_aton(cmd, bssid)) {
    498 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
    499 			   cmd);
    500 		return -1;
    501 	}
    502 
    503 	new_ssid = os_strchr(pin, ' ');
    504 	if (new_ssid == NULL)
    505 		return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
    506 	*new_ssid++ = '\0';
    507 
    508 	new_auth = os_strchr(new_ssid, ' ');
    509 	if (new_auth == NULL)
    510 		return -1;
    511 	*new_auth++ = '\0';
    512 
    513 	new_encr = os_strchr(new_auth, ' ');
    514 	if (new_encr == NULL)
    515 		return -1;
    516 	*new_encr++ = '\0';
    517 
    518 	new_key = os_strchr(new_encr, ' ');
    519 	if (new_key == NULL)
    520 		return -1;
    521 	*new_key++ = '\0';
    522 
    523 	os_memset(&ap, 0, sizeof(ap));
    524 	ap.ssid_hex = new_ssid;
    525 	ap.auth = new_auth;
    526 	ap.encr = new_encr;
    527 	ap.key_hex = new_key;
    528 	return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
    529 }
    530 
    531 
    532 #ifdef CONFIG_AP
    533 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
    534 						char *cmd, char *buf,
    535 						size_t buflen)
    536 {
    537 	int timeout = 300;
    538 	char *pos;
    539 	const char *pin_txt;
    540 
    541 	if (!wpa_s->ap_iface)
    542 		return -1;
    543 
    544 	pos = os_strchr(cmd, ' ');
    545 	if (pos)
    546 		*pos++ = '\0';
    547 
    548 	if (os_strcmp(cmd, "disable") == 0) {
    549 		wpas_wps_ap_pin_disable(wpa_s);
    550 		return os_snprintf(buf, buflen, "OK\n");
    551 	}
    552 
    553 	if (os_strcmp(cmd, "random") == 0) {
    554 		if (pos)
    555 			timeout = atoi(pos);
    556 		pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
    557 		if (pin_txt == NULL)
    558 			return -1;
    559 		return os_snprintf(buf, buflen, "%s", pin_txt);
    560 	}
    561 
    562 	if (os_strcmp(cmd, "get") == 0) {
    563 		pin_txt = wpas_wps_ap_pin_get(wpa_s);
    564 		if (pin_txt == NULL)
    565 			return -1;
    566 		return os_snprintf(buf, buflen, "%s", pin_txt);
    567 	}
    568 
    569 	if (os_strcmp(cmd, "set") == 0) {
    570 		char *pin;
    571 		if (pos == NULL)
    572 			return -1;
    573 		pin = pos;
    574 		pos = os_strchr(pos, ' ');
    575 		if (pos) {
    576 			*pos++ = '\0';
    577 			timeout = atoi(pos);
    578 		}
    579 		if (os_strlen(pin) > buflen)
    580 			return -1;
    581 		if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
    582 			return -1;
    583 		return os_snprintf(buf, buflen, "%s", pin);
    584 	}
    585 
    586 	return -1;
    587 }
    588 #endif /* CONFIG_AP */
    589 
    590 
    591 #ifdef CONFIG_WPS_ER
    592 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
    593 						char *cmd)
    594 {
    595 	char *uuid = cmd, *pin, *pos;
    596 	u8 addr_buf[ETH_ALEN], *addr = NULL;
    597 	pin = os_strchr(uuid, ' ');
    598 	if (pin == NULL)
    599 		return -1;
    600 	*pin++ = '\0';
    601 	pos = os_strchr(pin, ' ');
    602 	if (pos) {
    603 		*pos++ = '\0';
    604 		if (hwaddr_aton(pos, addr_buf) == 0)
    605 			addr = addr_buf;
    606 	}
    607 	return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
    608 }
    609 
    610 
    611 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
    612 						  char *cmd)
    613 {
    614 	char *uuid = cmd, *pin;
    615 	pin = os_strchr(uuid, ' ');
    616 	if (pin == NULL)
    617 		return -1;
    618 	*pin++ = '\0';
    619 	return wpas_wps_er_learn(wpa_s, uuid, pin);
    620 }
    621 
    622 
    623 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
    624 	struct wpa_supplicant *wpa_s, char *cmd)
    625 {
    626 	char *uuid = cmd, *id;
    627 	id = os_strchr(uuid, ' ');
    628 	if (id == NULL)
    629 		return -1;
    630 	*id++ = '\0';
    631 	return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
    632 }
    633 
    634 
    635 static int wpa_supplicant_ctrl_iface_wps_er_config(
    636 	struct wpa_supplicant *wpa_s, char *cmd)
    637 {
    638 	char *pin;
    639 	char *new_ssid;
    640 	char *new_auth;
    641 	char *new_encr;
    642 	char *new_key;
    643 	struct wps_new_ap_settings ap;
    644 
    645 	pin = os_strchr(cmd, ' ');
    646 	if (pin == NULL)
    647 		return -1;
    648 	*pin++ = '\0';
    649 
    650 	new_ssid = os_strchr(pin, ' ');
    651 	if (new_ssid == NULL)
    652 		return -1;
    653 	*new_ssid++ = '\0';
    654 
    655 	new_auth = os_strchr(new_ssid, ' ');
    656 	if (new_auth == NULL)
    657 		return -1;
    658 	*new_auth++ = '\0';
    659 
    660 	new_encr = os_strchr(new_auth, ' ');
    661 	if (new_encr == NULL)
    662 		return -1;
    663 	*new_encr++ = '\0';
    664 
    665 	new_key = os_strchr(new_encr, ' ');
    666 	if (new_key == NULL)
    667 		return -1;
    668 	*new_key++ = '\0';
    669 
    670 	os_memset(&ap, 0, sizeof(ap));
    671 	ap.ssid_hex = new_ssid;
    672 	ap.auth = new_auth;
    673 	ap.encr = new_encr;
    674 	ap.key_hex = new_key;
    675 	return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
    676 }
    677 #endif /* CONFIG_WPS_ER */
    678 
    679 #endif /* CONFIG_WPS */
    680 
    681 
    682 #ifdef CONFIG_IBSS_RSN
    683 static int wpa_supplicant_ctrl_iface_ibss_rsn(
    684 	struct wpa_supplicant *wpa_s, char *addr)
    685 {
    686 	u8 peer[ETH_ALEN];
    687 
    688 	if (hwaddr_aton(addr, peer)) {
    689 		wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
    690 			   "address '%s'", addr);
    691 		return -1;
    692 	}
    693 
    694 	wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
    695 		   MAC2STR(peer));
    696 
    697 	return ibss_rsn_start(wpa_s->ibss_rsn, peer);
    698 }
    699 #endif /* CONFIG_IBSS_RSN */
    700 
    701 
    702 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
    703 					      char *rsp)
    704 {
    705 #ifdef IEEE8021X_EAPOL
    706 	char *pos, *id_pos;
    707 	int id;
    708 	struct wpa_ssid *ssid;
    709 	struct eap_peer_config *eap;
    710 
    711 	pos = os_strchr(rsp, '-');
    712 	if (pos == NULL)
    713 		return -1;
    714 	*pos++ = '\0';
    715 	id_pos = pos;
    716 	pos = os_strchr(pos, ':');
    717 	if (pos == NULL)
    718 		return -1;
    719 	*pos++ = '\0';
    720 	id = atoi(id_pos);
    721 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
    722 	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
    723 			      (u8 *) pos, os_strlen(pos));
    724 
    725 	ssid = wpa_config_get_network(wpa_s->conf, id);
    726 	if (ssid == NULL) {
    727 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    728 			   "to update", id);
    729 		return -1;
    730 	}
    731 	eap = &ssid->eap;
    732 
    733 	if (os_strcmp(rsp, "IDENTITY") == 0) {
    734 		os_free(eap->identity);
    735 		eap->identity = (u8 *) os_strdup(pos);
    736 		eap->identity_len = os_strlen(pos);
    737 		eap->pending_req_identity = 0;
    738 		if (ssid == wpa_s->current_ssid)
    739 			wpa_s->reassociate = 1;
    740 	} else if (os_strcmp(rsp, "PASSWORD") == 0) {
    741 		os_free(eap->password);
    742 		eap->password = (u8 *) os_strdup(pos);
    743 		eap->password_len = os_strlen(pos);
    744 		eap->pending_req_password = 0;
    745 		if (ssid == wpa_s->current_ssid)
    746 			wpa_s->reassociate = 1;
    747 	} else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
    748 		os_free(eap->new_password);
    749 		eap->new_password = (u8 *) os_strdup(pos);
    750 		eap->new_password_len = os_strlen(pos);
    751 		eap->pending_req_new_password = 0;
    752 		if (ssid == wpa_s->current_ssid)
    753 			wpa_s->reassociate = 1;
    754 	} else if (os_strcmp(rsp, "PIN") == 0) {
    755 		os_free(eap->pin);
    756 		eap->pin = os_strdup(pos);
    757 		eap->pending_req_pin = 0;
    758 		if (ssid == wpa_s->current_ssid)
    759 			wpa_s->reassociate = 1;
    760 	} else if (os_strcmp(rsp, "OTP") == 0) {
    761 		os_free(eap->otp);
    762 		eap->otp = (u8 *) os_strdup(pos);
    763 		eap->otp_len = os_strlen(pos);
    764 		os_free(eap->pending_req_otp);
    765 		eap->pending_req_otp = NULL;
    766 		eap->pending_req_otp_len = 0;
    767 	} else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
    768 		os_free(eap->private_key_passwd);
    769 		eap->private_key_passwd = (u8 *) os_strdup(pos);
    770 		eap->pending_req_passphrase = 0;
    771 		if (ssid == wpa_s->current_ssid)
    772 			wpa_s->reassociate = 1;
    773 	} else {
    774 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
    775 		return -1;
    776 	}
    777 
    778 	return 0;
    779 #else /* IEEE8021X_EAPOL */
    780 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
    781 	return -1;
    782 #endif /* IEEE8021X_EAPOL */
    783 }
    784 
    785 
    786 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
    787 					    const char *params,
    788 					    char *buf, size_t buflen)
    789 {
    790 	char *pos, *end, tmp[30];
    791 	int res, verbose, ret;
    792 
    793 #if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
    794 	/* We have to send status command to p2p interface if p2p_interface is started
    795 	 * otherwise we can send it to primary interface
    796 	*/
    797 	struct wpa_supplicant* ifs;
    798 	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
    799 		if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
    800 			wpa_s = ifs;
    801 			break;
    802 		}
    803 	}
    804 #endif /* defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_P2P */
    805 
    806 	verbose = os_strcmp(params, "-VERBOSE") == 0;
    807 	pos = buf;
    808 	end = buf + buflen;
    809 	if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
    810 		struct wpa_ssid *ssid = wpa_s->current_ssid;
    811 		ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
    812 				  MAC2STR(wpa_s->bssid));
    813 		if (ret < 0 || ret >= end - pos)
    814 			return pos - buf;
    815 		pos += ret;
    816 		if (ssid) {
    817 			u8 *_ssid = ssid->ssid;
    818 			size_t ssid_len = ssid->ssid_len;
    819 			u8 ssid_buf[MAX_SSID_LEN];
    820 			if (ssid_len == 0) {
    821 				int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
    822 				if (_res < 0)
    823 					ssid_len = 0;
    824 				else
    825 					ssid_len = _res;
    826 				_ssid = ssid_buf;
    827 			}
    828 			ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
    829 					  wpa_ssid_txt(_ssid, ssid_len),
    830 					  ssid->id);
    831 			if (ret < 0 || ret >= end - pos)
    832 				return pos - buf;
    833 			pos += ret;
    834 
    835 			if (ssid->id_str) {
    836 				ret = os_snprintf(pos, end - pos,
    837 						  "id_str=%s\n",
    838 						  ssid->id_str);
    839 				if (ret < 0 || ret >= end - pos)
    840 					return pos - buf;
    841 				pos += ret;
    842 			}
    843 
    844 			switch (ssid->mode) {
    845 			case WPAS_MODE_INFRA:
    846 				ret = os_snprintf(pos, end - pos,
    847 						  "mode=station\n");
    848 				break;
    849 			case WPAS_MODE_IBSS:
    850 				ret = os_snprintf(pos, end - pos,
    851 						  "mode=IBSS\n");
    852 				break;
    853 			case WPAS_MODE_AP:
    854 				ret = os_snprintf(pos, end - pos,
    855 						  "mode=AP\n");
    856 				break;
    857 			case WPAS_MODE_P2P_GO:
    858 				ret = os_snprintf(pos, end - pos,
    859 						  "mode=P2P GO\n");
    860 				break;
    861 			case WPAS_MODE_P2P_GROUP_FORMATION:
    862 				ret = os_snprintf(pos, end - pos,
    863 						  "mode=P2P GO - group "
    864 						  "formation\n");
    865 				break;
    866 			default:
    867 				ret = 0;
    868 				break;
    869 			}
    870 			if (ret < 0 || ret >= end - pos)
    871 				return pos - buf;
    872 			pos += ret;
    873 		}
    874 
    875 #ifdef CONFIG_AP
    876 		if (wpa_s->ap_iface) {
    877 			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
    878 							    end - pos,
    879 							    verbose);
    880 		} else
    881 #endif /* CONFIG_AP */
    882 		pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
    883 	}
    884 	ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
    885 			  wpa_supplicant_state_txt(wpa_s->wpa_state));
    886 	if (ret < 0 || ret >= end - pos)
    887 		return pos - buf;
    888 	pos += ret;
    889 
    890 	if (wpa_s->l2 &&
    891 	    l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
    892 		ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
    893 		if (ret < 0 || ret >= end - pos)
    894 			return pos - buf;
    895 		pos += ret;
    896 	}
    897 
    898 #ifdef CONFIG_P2P
    899 	if (wpa_s->global->p2p) {
    900 		ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
    901 				  "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
    902 		if (ret < 0 || ret >= end - pos)
    903 			return pos - buf;
    904 		pos += ret;
    905 	}
    906 #endif /* CONFIG_P2P */
    907 
    908 	ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
    909 			  MAC2STR(wpa_s->own_addr));
    910 	if (ret < 0 || ret >= end - pos)
    911 		return pos - buf;
    912 	pos += ret;
    913 
    914 	if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
    915 	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    916 		res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
    917 					  verbose);
    918 		if (res >= 0)
    919 			pos += res;
    920 	}
    921 
    922 	res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
    923 	if (res >= 0)
    924 		pos += res;
    925 
    926 	return pos - buf;
    927 }
    928 
    929 
    930 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
    931 					   char *cmd)
    932 {
    933 	char *pos;
    934 	int id;
    935 	struct wpa_ssid *ssid;
    936 	u8 bssid[ETH_ALEN];
    937 
    938 	/* cmd: "<network id> <BSSID>" */
    939 	pos = os_strchr(cmd, ' ');
    940 	if (pos == NULL)
    941 		return -1;
    942 	*pos++ = '\0';
    943 	id = atoi(cmd);
    944 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
    945 	if (hwaddr_aton(pos, bssid)) {
    946 		wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
    947 		return -1;
    948 	}
    949 
    950 	ssid = wpa_config_get_network(wpa_s->conf, id);
    951 	if (ssid == NULL) {
    952 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
    953 			   "to update", id);
    954 		return -1;
    955 	}
    956 
    957 	os_memcpy(ssid->bssid, bssid, ETH_ALEN);
    958 	ssid->bssid_set = !is_zero_ether_addr(bssid);
    959 
    960 	return 0;
    961 }
    962 
    963 
    964 extern int wpa_debug_level;
    965 extern int wpa_debug_timestamp;
    966 
    967 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
    968 					char *cmd, char *buf, size_t buflen)
    969 {
    970 	char *pos, *end, *stamp;
    971 	int ret;
    972 
    973 	if (cmd == NULL)
    974 		return -1;
    975 	/* cmd: "LOG_LEVEL [<level>]" */
    976 	if (*cmd == '\0') {
    977 		pos = buf;
    978 		end = buf + buflen;
    979 		ret = os_snprintf(pos, end-pos, "Current level: %d\n"
    980 			"{0-EXCESSIVE, 1-MSGDUMP, 2-DEBUG, 3-INFO, 4-WARNING, 5-ERROR}\n"
    981 			"Timestamp: %d\n", wpa_debug_level, wpa_debug_timestamp);
    982 		if ((ret < 0) || (ret >= end - pos))
    983 			ret = 0;
    984 		return ret;
    985 	}
    986 
    987 	cmd++;
    988 	stamp = os_strchr(cmd, ' ');
    989 	if (stamp) {
    990 		*stamp++ = '\0';
    991 		while (*stamp == ' ')
    992 			stamp++;
    993 	}
    994 
    995 	if (cmd && os_strlen(cmd))
    996 		wpa_debug_level = atoi(cmd);
    997 
    998 	if (stamp && os_strlen(stamp))
    999 		wpa_debug_timestamp = atoi(stamp);
   1000 
   1001 	os_memcpy(buf, "OK\n", 3);
   1002 	return 3;
   1003 }
   1004 
   1005 
   1006 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
   1007 					char *cmd, char *buf, size_t buflen)
   1008 {
   1009 	u8 bssid[ETH_ALEN];
   1010 	struct wpa_blacklist *e;
   1011 	char *pos, *end;
   1012 	int ret;
   1013 
   1014 	/* cmd: "BLACKLIST [<BSSID>]" */
   1015 	if (*cmd == '\0') {
   1016 		pos = buf;
   1017 		end = buf + buflen;
   1018 		e = wpa_s->blacklist;
   1019 		while (e) {
   1020 			ret = os_snprintf(pos, end-pos, MACSTR"\n", MAC2STR(e->bssid));
   1021 			if ((ret < 0) || (ret >= end - pos))
   1022 				return pos - buf;
   1023 			pos += ret;
   1024 			e = e->next;
   1025 		}
   1026 		return pos - buf;
   1027 	}
   1028 
   1029 	cmd++;
   1030 	if (os_strncmp(cmd, "clear", 5) == 0) {
   1031 		wpa_blacklist_clear(wpa_s);
   1032 		os_memcpy(buf, "OK\n", 3);
   1033 		return 3;
   1034 	}
   1035 
   1036 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
   1037 	if (hwaddr_aton(cmd, bssid)) {
   1038 		wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd);
   1039 		return -1;
   1040 	}
   1041 
   1042 	/* Add the BSSID twice, so its count will be 2, causing it to be
   1043 	   skipped when processing scan results. */
   1044 	ret = wpa_blacklist_add(wpa_s, bssid);
   1045 	if (ret < 0)
   1046 		return -1;
   1047 	ret = wpa_blacklist_add(wpa_s, bssid);
   1048 	if (ret < 0)
   1049 		return -1;
   1050 	os_memcpy(buf, "OK\n", 3);
   1051 	return 3;
   1052 }
   1053 
   1054 
   1055 static int wpa_supplicant_ctrl_iface_list_networks(
   1056 	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
   1057 {
   1058 	char *pos, *end;
   1059 	struct wpa_ssid *ssid;
   1060 	int ret;
   1061 
   1062 	pos = buf;
   1063 	end = buf + buflen;
   1064 	ret = os_snprintf(pos, end - pos,
   1065 			  "network id / ssid / bssid / flags\n");
   1066 	if (ret < 0 || ret >= end - pos)
   1067 		return pos - buf;
   1068 	pos += ret;
   1069 
   1070 	ssid = wpa_s->conf->ssid;
   1071 	while (ssid) {
   1072 		ret = os_snprintf(pos, end - pos, "%d\t%s",
   1073 				  ssid->id,
   1074 				  wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
   1075 		if (ret < 0 || ret >= end - pos)
   1076 			return pos - buf;
   1077 		pos += ret;
   1078 		if (ssid->bssid_set) {
   1079 			ret = os_snprintf(pos, end - pos, "\t" MACSTR,
   1080 					  MAC2STR(ssid->bssid));
   1081 		} else {
   1082 			ret = os_snprintf(pos, end - pos, "\tany");
   1083 		}
   1084 		if (ret < 0 || ret >= end - pos)
   1085 			return pos - buf;
   1086 		pos += ret;
   1087 		ret = os_snprintf(pos, end - pos, "\t%s%s%s",
   1088 				  ssid == wpa_s->current_ssid ?
   1089 				  "[CURRENT]" : "",
   1090 				  ssid->disabled ? "[DISABLED]" : "",
   1091 				  ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
   1092 				  "");
   1093 		if (ret < 0 || ret >= end - pos)
   1094 			return pos - buf;
   1095 		pos += ret;
   1096 		ret = os_snprintf(pos, end - pos, "\n");
   1097 		if (ret < 0 || ret >= end - pos)
   1098 			return pos - buf;
   1099 		pos += ret;
   1100 
   1101 		ssid = ssid->next;
   1102 	}
   1103 
   1104 	return pos - buf;
   1105 }
   1106 
   1107 
   1108 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
   1109 {
   1110 	int first = 1, ret;
   1111 	ret = os_snprintf(pos, end - pos, "-");
   1112 	if (ret < 0 || ret >= end - pos)
   1113 		return pos;
   1114 	pos += ret;
   1115 	if (cipher & WPA_CIPHER_NONE) {
   1116 		ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
   1117 		if (ret < 0 || ret >= end - pos)
   1118 			return pos;
   1119 		pos += ret;
   1120 		first = 0;
   1121 	}
   1122 	if (cipher & WPA_CIPHER_WEP40) {
   1123 		ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
   1124 		if (ret < 0 || ret >= end - pos)
   1125 			return pos;
   1126 		pos += ret;
   1127 		first = 0;
   1128 	}
   1129 	if (cipher & WPA_CIPHER_WEP104) {
   1130 		ret = os_snprintf(pos, end - pos, "%sWEP104",
   1131 				  first ? "" : "+");
   1132 		if (ret < 0 || ret >= end - pos)
   1133 			return pos;
   1134 		pos += ret;
   1135 		first = 0;
   1136 	}
   1137 	if (cipher & WPA_CIPHER_TKIP) {
   1138 		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
   1139 		if (ret < 0 || ret >= end - pos)
   1140 			return pos;
   1141 		pos += ret;
   1142 		first = 0;
   1143 	}
   1144 	if (cipher & WPA_CIPHER_CCMP) {
   1145 		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
   1146 		if (ret < 0 || ret >= end - pos)
   1147 			return pos;
   1148 		pos += ret;
   1149 		first = 0;
   1150 	}
   1151 	return pos;
   1152 }
   1153 
   1154 
   1155 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
   1156 				    const u8 *ie, size_t ie_len)
   1157 {
   1158 	struct wpa_ie_data data;
   1159 	int first, ret;
   1160 
   1161 	ret = os_snprintf(pos, end - pos, "[%s-", proto);
   1162 	if (ret < 0 || ret >= end - pos)
   1163 		return pos;
   1164 	pos += ret;
   1165 
   1166 	if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
   1167 		ret = os_snprintf(pos, end - pos, "?]");
   1168 		if (ret < 0 || ret >= end - pos)
   1169 			return pos;
   1170 		pos += ret;
   1171 		return pos;
   1172 	}
   1173 
   1174 	first = 1;
   1175 	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
   1176 		ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
   1177 		if (ret < 0 || ret >= end - pos)
   1178 			return pos;
   1179 		pos += ret;
   1180 		first = 0;
   1181 	}
   1182 	if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
   1183 		ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
   1184 		if (ret < 0 || ret >= end - pos)
   1185 			return pos;
   1186 		pos += ret;
   1187 		first = 0;
   1188 	}
   1189 	if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
   1190 		ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
   1191 		if (ret < 0 || ret >= end - pos)
   1192 			return pos;
   1193 		pos += ret;
   1194 		first = 0;
   1195 	}
   1196 #ifdef CONFIG_IEEE80211R
   1197 	if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
   1198 		ret = os_snprintf(pos, end - pos, "%sFT/EAP",
   1199 				  first ? "" : "+");
   1200 		if (ret < 0 || ret >= end - pos)
   1201 			return pos;
   1202 		pos += ret;
   1203 		first = 0;
   1204 	}
   1205 	if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
   1206 		ret = os_snprintf(pos, end - pos, "%sFT/PSK",
   1207 				  first ? "" : "+");
   1208 		if (ret < 0 || ret >= end - pos)
   1209 			return pos;
   1210 		pos += ret;
   1211 		first = 0;
   1212 	}
   1213 #endif /* CONFIG_IEEE80211R */
   1214 #ifdef CONFIG_IEEE80211W
   1215 	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
   1216 		ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
   1217 				  first ? "" : "+");
   1218 		if (ret < 0 || ret >= end - pos)
   1219 			return pos;
   1220 		pos += ret;
   1221 		first = 0;
   1222 	}
   1223 	if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
   1224 		ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
   1225 				  first ? "" : "+");
   1226 		if (ret < 0 || ret >= end - pos)
   1227 			return pos;
   1228 		pos += ret;
   1229 		first = 0;
   1230 	}
   1231 #endif /* CONFIG_IEEE80211W */
   1232 
   1233 	pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
   1234 
   1235 	if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
   1236 		ret = os_snprintf(pos, end - pos, "-preauth");
   1237 		if (ret < 0 || ret >= end - pos)
   1238 			return pos;
   1239 		pos += ret;
   1240 	}
   1241 
   1242 	ret = os_snprintf(pos, end - pos, "]");
   1243 	if (ret < 0 || ret >= end - pos)
   1244 		return pos;
   1245 	pos += ret;
   1246 
   1247 	return pos;
   1248 }
   1249 
   1250 
   1251 #ifdef CONFIG_WPS
   1252 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
   1253 					    char *pos, char *end,
   1254 					    struct wpabuf *wps_ie)
   1255 {
   1256 	int ret;
   1257 	const char *txt;
   1258 
   1259 	if (wps_ie == NULL)
   1260 		return pos;
   1261 	if (wps_is_selected_pbc_registrar(wps_ie))
   1262 		txt = "[WPS-PBC]";
   1263 #ifdef CONFIG_WPS2
   1264 	else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
   1265 		txt = "[WPS-AUTH]";
   1266 #endif /* CONFIG_WPS2 */
   1267 	else if (wps_is_selected_pin_registrar(wps_ie))
   1268 		txt = "[WPS-PIN]";
   1269 	else
   1270 		txt = "[WPS]";
   1271 
   1272 	ret = os_snprintf(pos, end - pos, "%s", txt);
   1273 	if (ret >= 0 && ret < end - pos)
   1274 		pos += ret;
   1275 	wpabuf_free(wps_ie);
   1276 	return pos;
   1277 }
   1278 #endif /* CONFIG_WPS */
   1279 
   1280 
   1281 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
   1282 					char *pos, char *end,
   1283 					const struct wpa_bss *bss)
   1284 {
   1285 #ifdef CONFIG_WPS
   1286 	struct wpabuf *wps_ie;
   1287 	wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1288 	return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
   1289 #else /* CONFIG_WPS */
   1290 	return pos;
   1291 #endif /* CONFIG_WPS */
   1292 }
   1293 
   1294 
   1295 /* Format one result on one text line into a buffer. */
   1296 static int wpa_supplicant_ctrl_iface_scan_result(
   1297 	struct wpa_supplicant *wpa_s,
   1298 	const struct wpa_bss *bss, char *buf, size_t buflen)
   1299 {
   1300 	char *pos, *end;
   1301 	int ret;
   1302 	const u8 *ie, *ie2, *p2p;
   1303 
   1304 	p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
   1305 	if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
   1306 	    os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
   1307 	    0)
   1308 		return 0; /* Do not show P2P listen discovery results here */
   1309 
   1310 	pos = buf;
   1311 	end = buf + buflen;
   1312 
   1313 	ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
   1314 			  MAC2STR(bss->bssid), bss->freq, bss->level);
   1315 	if (ret < 0 || ret >= end - pos)
   1316 		return -1;
   1317 	pos += ret;
   1318 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
   1319 	if (ie)
   1320 		pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
   1321 	ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
   1322 	if (ie2)
   1323 		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
   1324 	pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
   1325 	if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
   1326 		ret = os_snprintf(pos, end - pos, "[WEP]");
   1327 		if (ret < 0 || ret >= end - pos)
   1328 			return -1;
   1329 		pos += ret;
   1330 	}
   1331 	if (bss->caps & IEEE80211_CAP_IBSS) {
   1332 		ret = os_snprintf(pos, end - pos, "[IBSS]");
   1333 		if (ret < 0 || ret >= end - pos)
   1334 			return -1;
   1335 		pos += ret;
   1336 	}
   1337 	if (bss->caps & IEEE80211_CAP_ESS) {
   1338 		ret = os_snprintf(pos, end - pos, "[ESS]");
   1339 		if (ret < 0 || ret >= end - pos)
   1340 			return -1;
   1341 		pos += ret;
   1342 	}
   1343 	if (p2p) {
   1344 		ret = os_snprintf(pos, end - pos, "[P2P]");
   1345 		if (ret < 0 || ret >= end - pos)
   1346 			return -1;
   1347 		pos += ret;
   1348 	}
   1349 
   1350 	ret = os_snprintf(pos, end - pos, "\t%s",
   1351 			  wpa_ssid_txt(bss->ssid, bss->ssid_len));
   1352 	if (ret < 0 || ret >= end - pos)
   1353 		return -1;
   1354 	pos += ret;
   1355 
   1356 	ret = os_snprintf(pos, end - pos, "\n");
   1357 	if (ret < 0 || ret >= end - pos)
   1358 		return -1;
   1359 	pos += ret;
   1360 
   1361 	return pos - buf;
   1362 }
   1363 
   1364 
   1365 static int wpa_supplicant_ctrl_iface_scan_results(
   1366 	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
   1367 {
   1368 	char *pos, *end;
   1369 	struct wpa_bss *bss;
   1370 	int ret;
   1371 
   1372 	pos = buf;
   1373 	end = buf + buflen;
   1374 	ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
   1375 			  "flags / ssid\n");
   1376 	if (ret < 0 || ret >= end - pos)
   1377 		return pos - buf;
   1378 	pos += ret;
   1379 
   1380 	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
   1381 		ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
   1382 							    end - pos);
   1383 		if (ret < 0 || ret >= end - pos)
   1384 			return pos - buf;
   1385 		pos += ret;
   1386 	}
   1387 
   1388 	return pos - buf;
   1389 }
   1390 
   1391 
   1392 static int wpa_supplicant_ctrl_iface_select_network(
   1393 	struct wpa_supplicant *wpa_s, char *cmd)
   1394 {
   1395 	int id;
   1396 	struct wpa_ssid *ssid;
   1397 
   1398 	/* cmd: "<network id>" or "any" */
   1399 	if (os_strcmp(cmd, "any") == 0) {
   1400 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
   1401 		ssid = NULL;
   1402 	} else {
   1403 		id = atoi(cmd);
   1404 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
   1405 
   1406 		ssid = wpa_config_get_network(wpa_s->conf, id);
   1407 		if (ssid == NULL) {
   1408 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
   1409 				   "network id=%d", id);
   1410 			return -1;
   1411 		}
   1412 		if (ssid->disabled == 2) {
   1413 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
   1414 				   "SELECT_NETWORK with persistent P2P group");
   1415 			return -1;
   1416 		}
   1417 	}
   1418 
   1419 	wpa_supplicant_select_network(wpa_s, ssid);
   1420 
   1421 	return 0;
   1422 }
   1423 
   1424 
   1425 static int wpa_supplicant_ctrl_iface_enable_network(
   1426 	struct wpa_supplicant *wpa_s, char *cmd)
   1427 {
   1428 	int id;
   1429 	struct wpa_ssid *ssid;
   1430 
   1431 	/* cmd: "<network id>" or "all" */
   1432 	if (os_strcmp(cmd, "all") == 0) {
   1433 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
   1434 		ssid = NULL;
   1435 	} else {
   1436 		id = atoi(cmd);
   1437 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
   1438 
   1439 		ssid = wpa_config_get_network(wpa_s->conf, id);
   1440 		if (ssid == NULL) {
   1441 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
   1442 				   "network id=%d", id);
   1443 			return -1;
   1444 		}
   1445 		if (ssid->disabled == 2) {
   1446 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
   1447 				   "ENABLE_NETWORK with persistent P2P group");
   1448 			return -1;
   1449 		}
   1450 	}
   1451 	wpa_supplicant_enable_network(wpa_s, ssid);
   1452 
   1453 	return 0;
   1454 }
   1455 
   1456 
   1457 static int wpa_supplicant_ctrl_iface_disable_network(
   1458 	struct wpa_supplicant *wpa_s, char *cmd)
   1459 {
   1460 	int id;
   1461 	struct wpa_ssid *ssid;
   1462 
   1463 	/* cmd: "<network id>" or "all" */
   1464 	if (os_strcmp(cmd, "all") == 0) {
   1465 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
   1466 		ssid = NULL;
   1467 	} else {
   1468 		id = atoi(cmd);
   1469 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
   1470 
   1471 		ssid = wpa_config_get_network(wpa_s->conf, id);
   1472 		if (ssid == NULL) {
   1473 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
   1474 				   "network id=%d", id);
   1475 			return -1;
   1476 		}
   1477 		if (ssid->disabled == 2) {
   1478 			wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
   1479 				   "DISABLE_NETWORK with persistent P2P "
   1480 				   "group");
   1481 			return -1;
   1482 		}
   1483 	}
   1484 	wpa_supplicant_disable_network(wpa_s, ssid);
   1485 
   1486 	return 0;
   1487 }
   1488 
   1489 
   1490 static int wpa_supplicant_ctrl_iface_add_network(
   1491 	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
   1492 {
   1493 	struct wpa_ssid *ssid;
   1494 	int ret;
   1495 
   1496 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
   1497 
   1498 	ssid = wpa_config_add_network(wpa_s->conf);
   1499 	if (ssid == NULL)
   1500 		return -1;
   1501 
   1502 	wpas_notify_network_added(wpa_s, ssid);
   1503 
   1504 	ssid->disabled = 1;
   1505 	wpa_config_set_network_defaults(ssid);
   1506 
   1507 	ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
   1508 	if (ret < 0 || (size_t) ret >= buflen)
   1509 		return -1;
   1510 	return ret;
   1511 }
   1512 
   1513 
   1514 static int wpa_supplicant_ctrl_iface_remove_network(
   1515 	struct wpa_supplicant *wpa_s, char *cmd)
   1516 {
   1517 	int id;
   1518 	struct wpa_ssid *ssid;
   1519 
   1520 	/* cmd: "<network id>" or "all" */
   1521 	if (os_strcmp(cmd, "all") == 0) {
   1522 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
   1523 		ssid = wpa_s->conf->ssid;
   1524 		while (ssid) {
   1525 			struct wpa_ssid *remove_ssid = ssid;
   1526 			id = ssid->id;
   1527 			ssid = ssid->next;
   1528 			wpas_notify_network_removed(wpa_s, remove_ssid);
   1529 			wpa_config_remove_network(wpa_s->conf, id);
   1530 		}
   1531 		if (wpa_s->current_ssid) {
   1532 			eapol_sm_invalidate_cached_session(wpa_s->eapol);
   1533 			wpa_sm_set_config(wpa_s->wpa, NULL);
   1534 			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
   1535 			wpa_supplicant_disassociate(wpa_s,
   1536 				                    WLAN_REASON_DEAUTH_LEAVING);
   1537 		}
   1538 		return 0;
   1539 	}
   1540 
   1541 	id = atoi(cmd);
   1542 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
   1543 
   1544 	ssid = wpa_config_get_network(wpa_s->conf, id);
   1545 	if (ssid == NULL ||
   1546 	    wpa_config_remove_network(wpa_s->conf, id) < 0) {
   1547 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
   1548 			   "id=%d", id);
   1549 		return -1;
   1550 	}
   1551 
   1552 	if (ssid == wpa_s->current_ssid) {
   1553 		/*
   1554 		 * Invalidate the EAP session cache if the current network is
   1555 		 * removed.
   1556 		 */
   1557 		eapol_sm_invalidate_cached_session(wpa_s->eapol);
   1558 		wpa_sm_set_config(wpa_s->wpa, NULL);
   1559 		eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
   1560 
   1561 		wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
   1562 	}
   1563 
   1564 	return 0;
   1565 }
   1566 
   1567 
   1568 static int wpa_supplicant_ctrl_iface_set_network(
   1569 	struct wpa_supplicant *wpa_s, char *cmd)
   1570 {
   1571 	int id;
   1572 	struct wpa_ssid *ssid;
   1573 	char *name, *value;
   1574 
   1575 	/* cmd: "<network id> <variable name> <value>" */
   1576 	name = os_strchr(cmd, ' ');
   1577 	if (name == NULL)
   1578 		return -1;
   1579 	*name++ = '\0';
   1580 
   1581 	value = os_strchr(name, ' ');
   1582 	if (value == NULL)
   1583 		return -1;
   1584 	*value++ = '\0';
   1585 
   1586 	id = atoi(cmd);
   1587 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
   1588 		   id, name);
   1589 	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
   1590 			      (u8 *) value, os_strlen(value));
   1591 
   1592 	ssid = wpa_config_get_network(wpa_s->conf, id);
   1593 	if (ssid == NULL) {
   1594 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
   1595 			   "id=%d", id);
   1596 		return -1;
   1597 	}
   1598 
   1599 	if (wpa_config_set(ssid, name, value, 0) < 0) {
   1600 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
   1601 			   "variable '%s'", name);
   1602 		return -1;
   1603 	}
   1604 
   1605 	if (wpa_s->current_ssid == ssid) {
   1606 		/*
   1607 		 * Invalidate the EAP session cache if anything in the current
   1608 		 * configuration changes.
   1609 		 */
   1610 		eapol_sm_invalidate_cached_session(wpa_s->eapol);
   1611 	}
   1612 
   1613 	if ((os_strcmp(name, "psk") == 0 &&
   1614 	     value[0] == '"' && ssid->ssid_len) ||
   1615 	    (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
   1616 		wpa_config_update_psk(ssid);
   1617 	else if (os_strcmp(name, "priority") == 0)
   1618 		wpa_config_update_prio_list(wpa_s->conf);
   1619 
   1620 	return 0;
   1621 }
   1622 
   1623 
   1624 static int wpa_supplicant_ctrl_iface_get_network(
   1625 	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
   1626 {
   1627 	int id;
   1628 	size_t res;
   1629 	struct wpa_ssid *ssid;
   1630 	char *name, *value;
   1631 
   1632 	/* cmd: "<network id> <variable name>" */
   1633 	name = os_strchr(cmd, ' ');
   1634 	if (name == NULL || buflen == 0)
   1635 		return -1;
   1636 	*name++ = '\0';
   1637 
   1638 	id = atoi(cmd);
   1639 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
   1640 		   id, name);
   1641 
   1642 	ssid = wpa_config_get_network(wpa_s->conf, id);
   1643 	if (ssid == NULL) {
   1644 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
   1645 			   "id=%d", id);
   1646 		return -1;
   1647 	}
   1648 
   1649 	value = wpa_config_get_no_key(ssid, name);
   1650 	if (value == NULL) {
   1651 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
   1652 			   "variable '%s'", name);
   1653 		return -1;
   1654 	}
   1655 
   1656 	res = os_strlcpy(buf, value, buflen);
   1657 	if (res >= buflen) {
   1658 		os_free(value);
   1659 		return -1;
   1660 	}
   1661 
   1662 	os_free(value);
   1663 
   1664 	return res;
   1665 }
   1666 
   1667 
   1668 #ifndef CONFIG_NO_CONFIG_WRITE
   1669 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
   1670 {
   1671 	int ret;
   1672 
   1673 	if (!wpa_s->conf->update_config) {
   1674 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
   1675 			   "to update configuration (update_config=0)");
   1676 		return -1;
   1677 	}
   1678 
   1679 	ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
   1680 	if (ret) {
   1681 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
   1682 			   "update configuration");
   1683 	} else {
   1684 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
   1685 			   " updated");
   1686 	}
   1687 
   1688 	return ret;
   1689 }
   1690 #endif /* CONFIG_NO_CONFIG_WRITE */
   1691 
   1692 
   1693 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
   1694 					      struct wpa_driver_capa *capa,
   1695 					      char *buf, size_t buflen)
   1696 {
   1697 	int ret, first = 1;
   1698 	char *pos, *end;
   1699 	size_t len;
   1700 
   1701 	pos = buf;
   1702 	end = pos + buflen;
   1703 
   1704 	if (res < 0) {
   1705 		if (strict)
   1706 			return 0;
   1707 		len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
   1708 		if (len >= buflen)
   1709 			return -1;
   1710 		return len;
   1711 	}
   1712 
   1713 	if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
   1714 		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
   1715 		if (ret < 0 || ret >= end - pos)
   1716 			return pos - buf;
   1717 		pos += ret;
   1718 		first = 0;
   1719 	}
   1720 
   1721 	if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
   1722 		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
   1723 		if (ret < 0 || ret >= end - pos)
   1724 			return pos - buf;
   1725 		pos += ret;
   1726 		first = 0;
   1727 	}
   1728 
   1729 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
   1730 		ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
   1731 		if (ret < 0 || ret >= end - pos)
   1732 			return pos - buf;
   1733 		pos += ret;
   1734 		first = 0;
   1735 	}
   1736 
   1737 	return pos - buf;
   1738 }
   1739 
   1740 
   1741 static int ctrl_iface_get_capability_group(int res, char *strict,
   1742 					   struct wpa_driver_capa *capa,
   1743 					   char *buf, size_t buflen)
   1744 {
   1745 	int ret, first = 1;
   1746 	char *pos, *end;
   1747 	size_t len;
   1748 
   1749 	pos = buf;
   1750 	end = pos + buflen;
   1751 
   1752 	if (res < 0) {
   1753 		if (strict)
   1754 			return 0;
   1755 		len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
   1756 		if (len >= buflen)
   1757 			return -1;
   1758 		return len;
   1759 	}
   1760 
   1761 	if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
   1762 		ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
   1763 		if (ret < 0 || ret >= end - pos)
   1764 			return pos - buf;
   1765 		pos += ret;
   1766 		first = 0;
   1767 	}
   1768 
   1769 	if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
   1770 		ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
   1771 		if (ret < 0 || ret >= end - pos)
   1772 			return pos - buf;
   1773 		pos += ret;
   1774 		first = 0;
   1775 	}
   1776 
   1777 	if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
   1778 		ret = os_snprintf(pos, end - pos, "%sWEP104",
   1779 				  first ? "" : " ");
   1780 		if (ret < 0 || ret >= end - pos)
   1781 			return pos - buf;
   1782 		pos += ret;
   1783 		first = 0;
   1784 	}
   1785 
   1786 	if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
   1787 		ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
   1788 		if (ret < 0 || ret >= end - pos)
   1789 			return pos - buf;
   1790 		pos += ret;
   1791 		first = 0;
   1792 	}
   1793 
   1794 	return pos - buf;
   1795 }
   1796 
   1797 
   1798 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
   1799 					      struct wpa_driver_capa *capa,
   1800 					      char *buf, size_t buflen)
   1801 {
   1802 	int ret;
   1803 	char *pos, *end;
   1804 	size_t len;
   1805 
   1806 	pos = buf;
   1807 	end = pos + buflen;
   1808 
   1809 	if (res < 0) {
   1810 		if (strict)
   1811 			return 0;
   1812 		len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
   1813 				 "NONE", buflen);
   1814 		if (len >= buflen)
   1815 			return -1;
   1816 		return len;
   1817 	}
   1818 
   1819 	ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
   1820 	if (ret < 0 || ret >= end - pos)
   1821 		return pos - buf;
   1822 	pos += ret;
   1823 
   1824 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
   1825 			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
   1826 		ret = os_snprintf(pos, end - pos, " WPA-EAP");
   1827 		if (ret < 0 || ret >= end - pos)
   1828 			return pos - buf;
   1829 		pos += ret;
   1830 	}
   1831 
   1832 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
   1833 			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
   1834 		ret = os_snprintf(pos, end - pos, " WPA-PSK");
   1835 		if (ret < 0 || ret >= end - pos)
   1836 			return pos - buf;
   1837 		pos += ret;
   1838 	}
   1839 
   1840 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
   1841 		ret = os_snprintf(pos, end - pos, " WPA-NONE");
   1842 		if (ret < 0 || ret >= end - pos)
   1843 			return pos - buf;
   1844 		pos += ret;
   1845 	}
   1846 
   1847 	return pos - buf;
   1848 }
   1849 
   1850 
   1851 static int ctrl_iface_get_capability_proto(int res, char *strict,
   1852 					   struct wpa_driver_capa *capa,
   1853 					   char *buf, size_t buflen)
   1854 {
   1855 	int ret, first = 1;
   1856 	char *pos, *end;
   1857 	size_t len;
   1858 
   1859 	pos = buf;
   1860 	end = pos + buflen;
   1861 
   1862 	if (res < 0) {
   1863 		if (strict)
   1864 			return 0;
   1865 		len = os_strlcpy(buf, "RSN WPA", buflen);
   1866 		if (len >= buflen)
   1867 			return -1;
   1868 		return len;
   1869 	}
   1870 
   1871 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
   1872 			      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
   1873 		ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
   1874 		if (ret < 0 || ret >= end - pos)
   1875 			return pos - buf;
   1876 		pos += ret;
   1877 		first = 0;
   1878 	}
   1879 
   1880 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
   1881 			      WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
   1882 		ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
   1883 		if (ret < 0 || ret >= end - pos)
   1884 			return pos - buf;
   1885 		pos += ret;
   1886 		first = 0;
   1887 	}
   1888 
   1889 	return pos - buf;
   1890 }
   1891 
   1892 
   1893 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
   1894 					      struct wpa_driver_capa *capa,
   1895 					      char *buf, size_t buflen)
   1896 {
   1897 	int ret, first = 1;
   1898 	char *pos, *end;
   1899 	size_t len;
   1900 
   1901 	pos = buf;
   1902 	end = pos + buflen;
   1903 
   1904 	if (res < 0) {
   1905 		if (strict)
   1906 			return 0;
   1907 		len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
   1908 		if (len >= buflen)
   1909 			return -1;
   1910 		return len;
   1911 	}
   1912 
   1913 	if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
   1914 		ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
   1915 		if (ret < 0 || ret >= end - pos)
   1916 			return pos - buf;
   1917 		pos += ret;
   1918 		first = 0;
   1919 	}
   1920 
   1921 	if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
   1922 		ret = os_snprintf(pos, end - pos, "%sSHARED",
   1923 				  first ? "" : " ");
   1924 		if (ret < 0 || ret >= end - pos)
   1925 			return pos - buf;
   1926 		pos += ret;
   1927 		first = 0;
   1928 	}
   1929 
   1930 	if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
   1931 		ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
   1932 		if (ret < 0 || ret >= end - pos)
   1933 			return pos - buf;
   1934 		pos += ret;
   1935 		first = 0;
   1936 	}
   1937 
   1938 	return pos - buf;
   1939 }
   1940 
   1941 
   1942 static int wpa_supplicant_ctrl_iface_get_capability(
   1943 	struct wpa_supplicant *wpa_s, const char *_field, char *buf,
   1944 	size_t buflen)
   1945 {
   1946 	struct wpa_driver_capa capa;
   1947 	int res;
   1948 	char *strict;
   1949 	char field[30];
   1950 	size_t len;
   1951 
   1952 	/* Determine whether or not strict checking was requested */
   1953 	len = os_strlcpy(field, _field, sizeof(field));
   1954 	if (len >= sizeof(field))
   1955 		return -1;
   1956 	strict = os_strchr(field, ' ');
   1957 	if (strict != NULL) {
   1958 		*strict++ = '\0';
   1959 		if (os_strcmp(strict, "strict") != 0)
   1960 			return -1;
   1961 	}
   1962 
   1963 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
   1964 		field, strict ? strict : "");
   1965 
   1966 	if (os_strcmp(field, "eap") == 0) {
   1967 		return eap_get_names(buf, buflen);
   1968 	}
   1969 
   1970 	res = wpa_drv_get_capa(wpa_s, &capa);
   1971 
   1972 	if (os_strcmp(field, "pairwise") == 0)
   1973 		return ctrl_iface_get_capability_pairwise(res, strict, &capa,
   1974 							  buf, buflen);
   1975 
   1976 	if (os_strcmp(field, "group") == 0)
   1977 		return ctrl_iface_get_capability_group(res, strict, &capa,
   1978 						       buf, buflen);
   1979 
   1980 	if (os_strcmp(field, "key_mgmt") == 0)
   1981 		return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
   1982 							  buf, buflen);
   1983 
   1984 	if (os_strcmp(field, "proto") == 0)
   1985 		return ctrl_iface_get_capability_proto(res, strict, &capa,
   1986 						       buf, buflen);
   1987 
   1988 	if (os_strcmp(field, "auth_alg") == 0)
   1989 		return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
   1990 							  buf, buflen);
   1991 
   1992 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
   1993 		   field);
   1994 
   1995 	return -1;
   1996 }
   1997 
   1998 
   1999 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
   2000 					 const char *cmd, char *buf,
   2001 					 size_t buflen)
   2002 {
   2003 	u8 bssid[ETH_ALEN];
   2004 	size_t i;
   2005 	struct wpa_bss *bss;
   2006 	int ret;
   2007 	char *pos, *end;
   2008 	const u8 *ie, *ie2;
   2009 
   2010 	if (os_strcmp(cmd, "FIRST") == 0)
   2011 		bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
   2012 	else if (os_strncmp(cmd, "ID-", 3) == 0) {
   2013 		i = atoi(cmd + 3);
   2014 		bss = wpa_bss_get_id(wpa_s, i);
   2015 	} else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
   2016 		i = atoi(cmd + 5);
   2017 		bss = wpa_bss_get_id(wpa_s, i);
   2018 		if (bss) {
   2019 			struct dl_list *next = bss->list_id.next;
   2020 			if (next == &wpa_s->bss_id)
   2021 				bss = NULL;
   2022 			else
   2023 				bss = dl_list_entry(next, struct wpa_bss,
   2024 						    list_id);
   2025 		}
   2026 	} else if (hwaddr_aton(cmd, bssid) == 0)
   2027 		bss = wpa_bss_get_bssid(wpa_s, bssid);
   2028 	else {
   2029 		struct wpa_bss *tmp;
   2030 		i = atoi(cmd);
   2031 		bss = NULL;
   2032 		dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
   2033 		{
   2034 			if (i-- == 0) {
   2035 				bss = tmp;
   2036 				break;
   2037 			}
   2038 		}
   2039 	}
   2040 
   2041 	if (bss == NULL)
   2042 		return 0;
   2043 
   2044 	pos = buf;
   2045 	end = buf + buflen;
   2046 	ret = os_snprintf(pos, end - pos,
   2047 			  "id=%u\n"
   2048 			  "bssid=" MACSTR "\n"
   2049 			  "freq=%d\n"
   2050 			  "beacon_int=%d\n"
   2051 			  "capabilities=0x%04x\n"
   2052 			  "qual=%d\n"
   2053 			  "noise=%d\n"
   2054 			  "level=%d\n"
   2055 			  "tsf=%016llu\n"
   2056 			  "ie=",
   2057 			  bss->id,
   2058 			  MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
   2059 			  bss->caps, bss->qual, bss->noise, bss->level,
   2060 			  (unsigned long long) bss->tsf);
   2061 	if (ret < 0 || ret >= end - pos)
   2062 		return pos - buf;
   2063 	pos += ret;
   2064 
   2065 	ie = (const u8 *) (bss + 1);
   2066 	for (i = 0; i < bss->ie_len; i++) {
   2067 		ret = os_snprintf(pos, end - pos, "%02x", *ie++);
   2068 		if (ret < 0 || ret >= end - pos)
   2069 			return pos - buf;
   2070 		pos += ret;
   2071 	}
   2072 	if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
   2073 		ret = os_snprintf(pos, end - pos, "[P2P]");
   2074 		if (ret < 0 || ret >= end - pos)
   2075 			return pos - buf;
   2076 		pos += ret;
   2077 	}
   2078 
   2079 	ret = os_snprintf(pos, end - pos, "\n");
   2080 	if (ret < 0 || ret >= end - pos)
   2081 		return pos - buf;
   2082 	pos += ret;
   2083 
   2084 	ret = os_snprintf(pos, end - pos, "flags=");
   2085 	if (ret < 0 || ret >= end - pos)
   2086 		return pos - buf;
   2087 	pos += ret;
   2088 
   2089 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
   2090 	if (ie)
   2091 		pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
   2092 	ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
   2093 	if (ie2)
   2094 		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
   2095 	pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
   2096 	if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
   2097 		ret = os_snprintf(pos, end - pos, "[WEP]");
   2098 		if (ret < 0 || ret >= end - pos)
   2099 			return pos - buf;
   2100 		pos += ret;
   2101 	}
   2102 	if (bss->caps & IEEE80211_CAP_IBSS) {
   2103 		ret = os_snprintf(pos, end - pos, "[IBSS]");
   2104 		if (ret < 0 || ret >= end - pos)
   2105 			return pos - buf;
   2106 		pos += ret;
   2107 	}
   2108 	if (bss->caps & IEEE80211_CAP_ESS) {
   2109 		ret = os_snprintf(pos, end - pos, "[ESS]");
   2110 		if (ret < 0 || ret >= end - pos)
   2111 			return pos - buf;
   2112 		pos += ret;
   2113 	}
   2114 
   2115 	ret = os_snprintf(pos, end - pos, "\n");
   2116 	if (ret < 0 || ret >= end - pos)
   2117 		return pos - buf;
   2118 	pos += ret;
   2119 
   2120 	ret = os_snprintf(pos, end - pos, "ssid=%s\n",
   2121 			  wpa_ssid_txt(bss->ssid, bss->ssid_len));
   2122 	if (ret < 0 || ret >= end - pos)
   2123 		return pos - buf;
   2124 	pos += ret;
   2125 
   2126 #ifdef CONFIG_WPS
   2127 	ie = (const u8 *) (bss + 1);
   2128 	ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
   2129 	if (ret < 0 || ret >= end - pos)
   2130 		return pos - buf;
   2131 	pos += ret;
   2132 #endif /* CONFIG_WPS */
   2133 
   2134 #ifdef CONFIG_P2P
   2135 	ie = (const u8 *) (bss + 1);
   2136 	ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
   2137 	if (ret < 0 || ret >= end - pos)
   2138 		return pos - buf;
   2139 	pos += ret;
   2140 #endif /* CONFIG_P2P */
   2141 
   2142 	return pos - buf;
   2143 }
   2144 
   2145 
   2146 static int wpa_supplicant_ctrl_iface_ap_scan(
   2147 	struct wpa_supplicant *wpa_s, char *cmd)
   2148 {
   2149 	int ap_scan = atoi(cmd);
   2150 	return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
   2151 }
   2152 
   2153 
   2154 static int wpa_supplicant_ctrl_iface_scan_interval(
   2155 	struct wpa_supplicant *wpa_s, char *cmd)
   2156 {
   2157 	int scan_int = atoi(cmd);
   2158 	if (scan_int < 0)
   2159 		return -1;
   2160 	wpa_s->scan_interval = scan_int;
   2161 	return 0;
   2162 }
   2163 
   2164 
   2165 static int wpa_supplicant_ctrl_iface_bss_expire_age(
   2166 	struct wpa_supplicant *wpa_s, char *cmd)
   2167 {
   2168 	int expire_age = atoi(cmd);
   2169 	return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
   2170 }
   2171 
   2172 
   2173 static int wpa_supplicant_ctrl_iface_bss_expire_count(
   2174 	struct wpa_supplicant *wpa_s, char *cmd)
   2175 {
   2176 	int expire_count = atoi(cmd);
   2177 	return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
   2178 }
   2179 
   2180 
   2181 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
   2182 {
   2183 	wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
   2184 	/* MLME-DELETEKEYS.request */
   2185 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
   2186 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
   2187 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
   2188 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
   2189 #ifdef CONFIG_IEEE80211W
   2190 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
   2191 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
   2192 #endif /* CONFIG_IEEE80211W */
   2193 
   2194 	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
   2195 			0);
   2196 	/* MLME-SETPROTECTION.request(None) */
   2197 	wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
   2198 				   MLME_SETPROTECTION_PROTECT_TYPE_NONE,
   2199 				   MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
   2200 	wpa_sm_drop_sa(wpa_s->wpa);
   2201 }
   2202 
   2203 
   2204 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
   2205 					  char *addr)
   2206 {
   2207 	u8 bssid[ETH_ALEN];
   2208 	struct wpa_bss *bss;
   2209 	struct wpa_ssid *ssid = wpa_s->current_ssid;
   2210 
   2211 	if (hwaddr_aton(addr, bssid)) {
   2212 		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
   2213 			   "address '%s'", addr);
   2214 		return -1;
   2215 	}
   2216 
   2217 	wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
   2218 
   2219 	bss = wpa_bss_get_bssid(wpa_s, bssid);
   2220 	if (!bss) {
   2221 		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
   2222 			   "from BSS table");
   2223 		return -1;
   2224 	}
   2225 
   2226 	/*
   2227 	 * TODO: Find best network configuration block from configuration to
   2228 	 * allow roaming to other networks
   2229 	 */
   2230 
   2231 	if (!ssid) {
   2232 		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
   2233 			   "configuration known for the target AP");
   2234 		return -1;
   2235 	}
   2236 
   2237 	wpa_s->reassociate = 1;
   2238 	wpa_supplicant_connect(wpa_s, bss, ssid);
   2239 
   2240 	return 0;
   2241 }
   2242 
   2243 
   2244 #ifdef CONFIG_P2P
   2245 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
   2246 {
   2247 	unsigned int timeout = atoi(cmd);
   2248 	enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
   2249 
   2250 	if (os_strstr(cmd, "type=social"))
   2251 		type = P2P_FIND_ONLY_SOCIAL;
   2252 	else if (os_strstr(cmd, "type=progressive"))
   2253 		type = P2P_FIND_PROGRESSIVE;
   2254 
   2255 	return wpas_p2p_find(wpa_s, timeout, type, 0, NULL);
   2256 }
   2257 
   2258 
   2259 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
   2260 			    char *buf, size_t buflen)
   2261 {
   2262 	u8 addr[ETH_ALEN];
   2263 	char *pos, *pos2;
   2264 	char *pin = NULL;
   2265 	enum p2p_wps_method wps_method;
   2266 	int new_pin;
   2267 	int ret;
   2268 	int persistent_group;
   2269 	int join;
   2270 	int auth;
   2271 	int go_intent = -1;
   2272 	int freq = 0;
   2273 
   2274 	/* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent]
   2275 	 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
   2276 
   2277 	if (hwaddr_aton(cmd, addr))
   2278 		return -1;
   2279 
   2280 	pos = cmd + 17;
   2281 	if (*pos != ' ')
   2282 		return -1;
   2283 	pos++;
   2284 
   2285 	persistent_group = os_strstr(pos, " persistent") != NULL;
   2286 	join = os_strstr(pos, " join") != NULL;
   2287 	auth = os_strstr(pos, " auth") != NULL;
   2288 
   2289 	pos2 = os_strstr(pos, " go_intent=");
   2290 	if (pos2) {
   2291 		pos2 += 11;
   2292 		go_intent = atoi(pos2);
   2293 		if (go_intent < 0 || go_intent > 15)
   2294 			return -1;
   2295 	}
   2296 
   2297 	pos2 = os_strstr(pos, " freq=");
   2298 	if (pos2) {
   2299 		pos2 += 6;
   2300 		freq = atoi(pos2);
   2301 		if (freq <= 0)
   2302 			return -1;
   2303 	}
   2304 
   2305 	if (os_strncmp(pos, "pin", 3) == 0) {
   2306 		/* Request random PIN (to be displayed) and enable the PIN */
   2307 		wps_method = WPS_PIN_DISPLAY;
   2308 	} else if (os_strncmp(pos, "pbc", 3) == 0) {
   2309 		wps_method = WPS_PBC;
   2310 	} else {
   2311 		pin = pos;
   2312 		pos = os_strchr(pin, ' ');
   2313 		wps_method = WPS_PIN_KEYPAD;
   2314 		if (pos) {
   2315 			*pos++ = '\0';
   2316 			if (os_strncmp(pos, "label", 5) == 0)
   2317 				wps_method = WPS_PIN_LABEL;
   2318 			else if (os_strncmp(pos, "display", 7) == 0)
   2319 				wps_method = WPS_PIN_DISPLAY;
   2320 		}
   2321 	}
   2322 
   2323 	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
   2324 				   persistent_group, join, auth, go_intent,
   2325 				   freq);
   2326 	if (new_pin == -2) {
   2327 		os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
   2328 		return 25;
   2329 	}
   2330 	if (new_pin == -3) {
   2331 		os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
   2332 		return 25;
   2333 	}
   2334 	if (new_pin < 0)
   2335 		return -1;
   2336 	if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
   2337 		ret = os_snprintf(buf, buflen, "%08d", new_pin);
   2338 		if (ret < 0 || (size_t) ret >= buflen)
   2339 			return -1;
   2340 		return ret;
   2341 	}
   2342 
   2343 	os_memcpy(buf, "OK\n", 3);
   2344 	return 3;
   2345 }
   2346 
   2347 
   2348 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
   2349 {
   2350 	unsigned int timeout = atoi(cmd);
   2351 	return wpas_p2p_listen(wpa_s, timeout);
   2352 }
   2353 
   2354 
   2355 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
   2356 {
   2357 	u8 addr[ETH_ALEN];
   2358 	char *pos;
   2359 
   2360 	/* <addr> <config method> */
   2361 
   2362 	if (hwaddr_aton(cmd, addr))
   2363 		return -1;
   2364 
   2365 	pos = cmd + 17;
   2366 	if (*pos != ' ')
   2367 		return -1;
   2368 	pos++;
   2369 
   2370 	return wpas_p2p_prov_disc(wpa_s, addr, pos);
   2371 }
   2372 
   2373 
   2374 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
   2375 			      size_t buflen)
   2376 {
   2377 	struct wpa_ssid *ssid = wpa_s->current_ssid;
   2378 
   2379 #ifdef ANDROID_BRCM_P2P_PATCH
   2380 	struct wpa_supplicant *ifs = NULL;
   2381 
   2382 	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
   2383 		if((ifs->ap_iface) &&
   2384 			(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO)) {
   2385 			ssid = ifs->current_ssid;
   2386 		}
   2387 	}
   2388 #endif
   2389 	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
   2390 	    ssid->passphrase == NULL)
   2391 		return -1;
   2392 
   2393 	os_strlcpy(buf, ssid->passphrase, buflen);
   2394 	return os_strlen(buf);
   2395 }
   2396 
   2397 
   2398 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
   2399 				  char *buf, size_t buflen)
   2400 {
   2401 	u64 ref;
   2402 	int res;
   2403 	u8 dst_buf[ETH_ALEN], *dst;
   2404 	struct wpabuf *tlvs;
   2405 	char *pos;
   2406 	size_t len;
   2407 
   2408 	if (hwaddr_aton(cmd, dst_buf))
   2409 		return -1;
   2410 	dst = dst_buf;
   2411 	if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
   2412 	    dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
   2413 		dst = NULL;
   2414 	pos = cmd + 17;
   2415 	if (*pos != ' ')
   2416 		return -1;
   2417 	pos++;
   2418 
   2419 	if (os_strncmp(pos, "upnp ", 5) == 0) {
   2420 		u8 version;
   2421 		pos += 5;
   2422 		if (hexstr2bin(pos, &version, 1) < 0)
   2423 			return -1;
   2424 		pos += 2;
   2425 		if (*pos != ' ')
   2426 			return -1;
   2427 		pos++;
   2428 		ref = (unsigned long) wpas_p2p_sd_request_upnp(wpa_s, dst,
   2429 							       version, pos);
   2430 	} else {
   2431 		len = os_strlen(pos);
   2432 		if (len & 1)
   2433 			return -1;
   2434 		len /= 2;
   2435 		tlvs = wpabuf_alloc(len);
   2436 		if (tlvs == NULL)
   2437 			return -1;
   2438 		if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
   2439 			wpabuf_free(tlvs);
   2440 			return -1;
   2441 		}
   2442 
   2443 		ref = (unsigned long) wpas_p2p_sd_request(wpa_s, dst, tlvs);
   2444 		wpabuf_free(tlvs);
   2445 	}
   2446 	res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
   2447 	if (res < 0 || (unsigned) res >= buflen)
   2448 		return -1;
   2449 	return res;
   2450 }
   2451 
   2452 
   2453 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
   2454 					 char *cmd)
   2455 {
   2456 	long long unsigned val;
   2457 	u64 req;
   2458 	if (sscanf(cmd, "%llx", &val) != 1)
   2459 		return -1;
   2460 	req = val;
   2461 	return wpas_p2p_sd_cancel_request(wpa_s, (void *) (unsigned long) req);
   2462 }
   2463 
   2464 
   2465 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
   2466 {
   2467 	int freq;
   2468 	u8 dst[ETH_ALEN];
   2469 	u8 dialog_token;
   2470 	struct wpabuf *resp_tlvs;
   2471 	char *pos, *pos2;
   2472 	size_t len;
   2473 
   2474 	pos = os_strchr(cmd, ' ');
   2475 	if (pos == NULL)
   2476 		return -1;
   2477 	*pos++ = '\0';
   2478 	freq = atoi(cmd);
   2479 	if (freq == 0)
   2480 		return -1;
   2481 
   2482 	if (hwaddr_aton(pos, dst))
   2483 		return -1;
   2484 	pos += 17;
   2485 	if (*pos != ' ')
   2486 		return -1;
   2487 	pos++;
   2488 
   2489 	pos2 = os_strchr(pos, ' ');
   2490 	if (pos2 == NULL)
   2491 		return -1;
   2492 	*pos2++ = '\0';
   2493 	dialog_token = atoi(pos);
   2494 
   2495 	len = os_strlen(pos2);
   2496 	if (len & 1)
   2497 		return -1;
   2498 	len /= 2;
   2499 	resp_tlvs = wpabuf_alloc(len);
   2500 	if (resp_tlvs == NULL)
   2501 		return -1;
   2502 	if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
   2503 		wpabuf_free(resp_tlvs);
   2504 		return -1;
   2505 	}
   2506 
   2507 	wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
   2508 	wpabuf_free(resp_tlvs);
   2509 	return 0;
   2510 }
   2511 
   2512 
   2513 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
   2514 				       char *cmd)
   2515 {
   2516 	wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
   2517 	return 0;
   2518 }
   2519 
   2520 
   2521 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
   2522 					char *cmd)
   2523 {
   2524 	char *pos;
   2525 	size_t len;
   2526 	struct wpabuf *query, *resp;
   2527 
   2528 	pos = os_strchr(cmd, ' ');
   2529 	if (pos == NULL)
   2530 		return -1;
   2531 	*pos++ = '\0';
   2532 
   2533 	len = os_strlen(cmd);
   2534 	if (len & 1)
   2535 		return -1;
   2536 	len /= 2;
   2537 	query = wpabuf_alloc(len);
   2538 	if (query == NULL)
   2539 		return -1;
   2540 	if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
   2541 		wpabuf_free(query);
   2542 		return -1;
   2543 	}
   2544 
   2545 	len = os_strlen(pos);
   2546 	if (len & 1) {
   2547 		wpabuf_free(query);
   2548 		return -1;
   2549 	}
   2550 	len /= 2;
   2551 	resp = wpabuf_alloc(len);
   2552 	if (resp == NULL) {
   2553 		wpabuf_free(query);
   2554 		return -1;
   2555 	}
   2556 	if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
   2557 		wpabuf_free(query);
   2558 		wpabuf_free(resp);
   2559 		return -1;
   2560 	}
   2561 
   2562 	if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
   2563 		wpabuf_free(query);
   2564 		wpabuf_free(resp);
   2565 		return -1;
   2566 	}
   2567 	return 0;
   2568 }
   2569 
   2570 
   2571 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
   2572 {
   2573 	char *pos;
   2574 	u8 version;
   2575 
   2576 	pos = os_strchr(cmd, ' ');
   2577 	if (pos == NULL)
   2578 		return -1;
   2579 	*pos++ = '\0';
   2580 
   2581 	if (hexstr2bin(cmd, &version, 1) < 0)
   2582 		return -1;
   2583 
   2584 	return wpas_p2p_service_add_upnp(wpa_s, version, pos);
   2585 }
   2586 
   2587 
   2588 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
   2589 {
   2590 	char *pos;
   2591 
   2592 	pos = os_strchr(cmd, ' ');
   2593 	if (pos == NULL)
   2594 		return -1;
   2595 	*pos++ = '\0';
   2596 
   2597 	if (os_strcmp(cmd, "bonjour") == 0)
   2598 		return p2p_ctrl_service_add_bonjour(wpa_s, pos);
   2599 	if (os_strcmp(cmd, "upnp") == 0)
   2600 		return p2p_ctrl_service_add_upnp(wpa_s, pos);
   2601 	wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
   2602 	return -1;
   2603 }
   2604 
   2605 
   2606 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
   2607 					char *cmd)
   2608 {
   2609 	size_t len;
   2610 	struct wpabuf *query;
   2611 	int ret;
   2612 
   2613 	len = os_strlen(cmd);
   2614 	if (len & 1)
   2615 		return -1;
   2616 	len /= 2;
   2617 	query = wpabuf_alloc(len);
   2618 	if (query == NULL)
   2619 		return -1;
   2620 	if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
   2621 		wpabuf_free(query);
   2622 		return -1;
   2623 	}
   2624 
   2625 	ret = wpas_p2p_service_del_bonjour(wpa_s, query);
   2626 	wpabuf_free(query);
   2627 	return ret;
   2628 }
   2629 
   2630 
   2631 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
   2632 {
   2633 	char *pos;
   2634 	u8 version;
   2635 
   2636 	pos = os_strchr(cmd, ' ');
   2637 	if (pos == NULL)
   2638 		return -1;
   2639 	*pos++ = '\0';
   2640 
   2641 	if (hexstr2bin(cmd, &version, 1) < 0)
   2642 		return -1;
   2643 
   2644 	return wpas_p2p_service_del_upnp(wpa_s, version, pos);
   2645 }
   2646 
   2647 
   2648 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
   2649 {
   2650 	char *pos;
   2651 
   2652 	pos = os_strchr(cmd, ' ');
   2653 	if (pos == NULL)
   2654 		return -1;
   2655 	*pos++ = '\0';
   2656 
   2657 	if (os_strcmp(cmd, "bonjour") == 0)
   2658 		return p2p_ctrl_service_del_bonjour(wpa_s, pos);
   2659 	if (os_strcmp(cmd, "upnp") == 0)
   2660 		return p2p_ctrl_service_del_upnp(wpa_s, pos);
   2661 	wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
   2662 	return -1;
   2663 }
   2664 
   2665 
   2666 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
   2667 {
   2668 	u8 addr[ETH_ALEN];
   2669 
   2670 	/* <addr> */
   2671 
   2672 	if (hwaddr_aton(cmd, addr))
   2673 		return -1;
   2674 
   2675 	return wpas_p2p_reject(wpa_s, addr);
   2676 }
   2677 
   2678 
   2679 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
   2680 {
   2681 	char *pos;
   2682 	int id;
   2683 	struct wpa_ssid *ssid;
   2684 	u8 peer[ETH_ALEN];
   2685 
   2686 	id = atoi(cmd);
   2687 	pos = os_strstr(cmd, " peer=");
   2688 	if (pos) {
   2689 		pos += 6;
   2690 		if (hwaddr_aton(pos, peer))
   2691 			return -1;
   2692 	}
   2693 	ssid = wpa_config_get_network(wpa_s->conf, id);
   2694 	if (ssid == NULL || ssid->disabled != 2) {
   2695 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
   2696 			   "for persistent P2P group",
   2697 			   id);
   2698 		return -1;
   2699 	}
   2700 
   2701 	return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL);
   2702 }
   2703 
   2704 
   2705 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
   2706 {
   2707 	char *pos;
   2708 	u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
   2709 
   2710 	pos = os_strstr(cmd, " peer=");
   2711 	if (!pos)
   2712 		return -1;
   2713 
   2714 	*pos = '\0';
   2715 	pos += 6;
   2716 	if (hwaddr_aton(pos, peer)) {
   2717 		wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
   2718 		return -1;
   2719 	}
   2720 
   2721 	pos = os_strstr(pos, " go_dev_addr=");
   2722 	if (pos) {
   2723 		pos += 13;
   2724 		if (hwaddr_aton(pos, go_dev_addr)) {
   2725 			wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
   2726 				   pos);
   2727 			return -1;
   2728 		}
   2729 		go_dev = go_dev_addr;
   2730 	}
   2731 
   2732 	return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
   2733 }
   2734 
   2735 
   2736 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
   2737 {
   2738 	if (os_strncmp(cmd, "persistent=", 11) == 0)
   2739 		return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
   2740 	if (os_strncmp(cmd, "group=", 6) == 0)
   2741 		return p2p_ctrl_invite_group(wpa_s, cmd + 6);
   2742 
   2743 	return -1;
   2744 }
   2745 
   2746 
   2747 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
   2748 					 char *cmd, int freq)
   2749 {
   2750 	int id;
   2751 	struct wpa_ssid *ssid;
   2752 
   2753 	id = atoi(cmd);
   2754 	ssid = wpa_config_get_network(wpa_s->conf, id);
   2755 	if (ssid == NULL || ssid->disabled != 2) {
   2756 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
   2757 			   "for persistent P2P group",
   2758 			   id);
   2759 		return -1;
   2760 	}
   2761 
   2762 	return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq);
   2763 }
   2764 
   2765 
   2766 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
   2767 {
   2768 	int freq = 0;
   2769 	char *pos;
   2770 
   2771 	pos = os_strstr(cmd, "freq=");
   2772 	if (pos)
   2773 		freq = atoi(pos + 5);
   2774 
   2775 	if (os_strncmp(cmd, "persistent=", 11) == 0)
   2776 		return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq);
   2777 	if (os_strcmp(cmd, "persistent") == 0 ||
   2778 	    os_strncmp(cmd, "persistent ", 11) == 0)
   2779 		return wpas_p2p_group_add(wpa_s, 1, freq);
   2780 	if (os_strncmp(cmd, "freq=", 5) == 0)
   2781 		return wpas_p2p_group_add(wpa_s, 0, freq);
   2782 
   2783 	wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
   2784 		   cmd);
   2785 	return -1;
   2786 }
   2787 
   2788 
   2789 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
   2790 			 char *buf, size_t buflen)
   2791 {
   2792 	u8 addr[ETH_ALEN], *addr_ptr;
   2793 	int next;
   2794 
   2795 	if (!wpa_s->global->p2p)
   2796 		return -1;
   2797 
   2798 	if (os_strcmp(cmd, "FIRST") == 0) {
   2799 		addr_ptr = NULL;
   2800 		next = 0;
   2801 	} else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
   2802 		if (hwaddr_aton(cmd + 5, addr) < 0)
   2803 			return -1;
   2804 		addr_ptr = addr;
   2805 		next = 1;
   2806 	} else {
   2807 		if (hwaddr_aton(cmd, addr) < 0)
   2808 			return -1;
   2809 		addr_ptr = addr;
   2810 		next = 0;
   2811 	}
   2812 
   2813 	return p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next,
   2814 				 buf, buflen);
   2815 }
   2816 
   2817 #ifdef ANDROID_BRCM_P2P_PATCH
   2818 struct wpa_supplicant* p2p_get_apif(struct wpa_supplicant* wpa_s)
   2819 {
   2820 	struct wpa_supplicant* iface;
   2821 	for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
   2822 		if (iface->ap_iface)
   2823 			return iface;
   2824 	return wpa_s;
   2825 }
   2826 struct wpa_supplicant* p2p_get_clientif(struct wpa_supplicant* wpa_s)
   2827 {
   2828 	struct wpa_supplicant* iface;
   2829 	for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
   2830 		if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
   2831 			return iface;
   2832 	return wpa_s;
   2833 }
   2834 #endif
   2835 
   2836 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
   2837 {
   2838 	char *param;
   2839 
   2840 	if (wpa_s->global->p2p == NULL)
   2841 		return -1;
   2842 
   2843 	param = os_strchr(cmd, ' ');
   2844 	if (param == NULL)
   2845 		return -1;
   2846 	*param++ = '\0';
   2847 
   2848 	if (os_strcmp(cmd, "discoverability") == 0) {
   2849 		p2p_set_client_discoverability(wpa_s->global->p2p,
   2850 					       atoi(param));
   2851 		return 0;
   2852 	}
   2853 
   2854 	if (os_strcmp(cmd, "managed") == 0) {
   2855 		p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
   2856 		return 0;
   2857 	}
   2858 
   2859 	if (os_strcmp(cmd, "listen_channel") == 0) {
   2860 		return p2p_set_listen_channel(wpa_s->global->p2p, 81,
   2861 					      atoi(param));
   2862 	}
   2863 
   2864 	if (os_strcmp(cmd, "ssid_postfix") == 0) {
   2865 		return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
   2866 					    os_strlen(param));
   2867 	}
   2868 
   2869 	if (os_strcmp(cmd, "noa") == 0) {
   2870 		char *pos;
   2871 		int count, start, duration;
   2872 		/* GO NoA parameters: count,start_offset(ms),duration(ms) */
   2873 		count = atoi(param);
   2874 		pos = os_strchr(param, ',');
   2875 		if (pos == NULL)
   2876 			return -1;
   2877 		pos++;
   2878 		start = atoi(pos);
   2879 		pos = os_strchr(pos, ',');
   2880 		if (pos == NULL)
   2881 			return -1;
   2882 		pos++;
   2883 		duration = atoi(pos);
   2884 		if (count < 0 || count > 255 || start < 0 || duration < 0)
   2885 			return -1;
   2886 		if (count == 0 && duration > 0)
   2887 			return -1;
   2888 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
   2889 			   "start=%d duration=%d", count, start, duration);
   2890 #ifdef ANDROID_BRCM_P2P_PATCH
   2891 		return wpas_p2p_set_noa(p2p_get_apif(wpa_s), count, start, duration);
   2892 #else
   2893 		return wpas_p2p_set_noa(wpa_s, count, start, duration);
   2894 #endif
   2895 	}
   2896 
   2897 	if (os_strcmp(cmd, "ps") == 0)
   2898 #ifdef ANDROID_BRCM_P2P_PATCH
   2899 		return wpas_drv_set_p2p_powersave(p2p_get_clientif(wpa_s), atoi(param), -1, -1);
   2900 #else
   2901 		return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
   2902 #endif
   2903 
   2904 	if (os_strcmp(cmd, "oppps") == 0)
   2905 #ifdef ANDROID_BRCM_P2P_PATCH
   2906 		return wpas_drv_set_p2p_powersave(p2p_get_apif(wpa_s), -1, atoi(param), -1);
   2907 #else
   2908 		return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
   2909 #endif
   2910 
   2911 	if (os_strcmp(cmd, "ctwindow") == 0)
   2912 #ifdef ANDROID_BRCM_P2P_PATCH
   2913 		return wpa_drv_set_p2p_powersave(p2p_get_apif(wpa_s), -1, -1, atoi(param));
   2914 #else
   2915 		return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
   2916 #endif
   2917 
   2918 	if (os_strcmp(cmd, "disabled") == 0) {
   2919 		wpa_s->global->p2p_disabled = atoi(param);
   2920 		wpa_printf(MSG_DEBUG, "P2P functionality %s",
   2921 			   wpa_s->global->p2p_disabled ?
   2922 			   "disabled" : "enabled");
   2923 		if (wpa_s->global->p2p_disabled) {
   2924 			wpas_p2p_stop_find(wpa_s);
   2925 			os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
   2926 			p2p_flush(wpa_s->global->p2p);
   2927 		}
   2928 		return 0;
   2929 	}
   2930 
   2931 	if (os_strcmp(cmd, "disabled") == 0) {
   2932 		wpa_s->global->p2p_disabled = atoi(param);
   2933 		wpa_printf(MSG_DEBUG, "P2P functionality %s",
   2934 			   wpa_s->global->p2p_disabled ?
   2935 			   "disabled" : "enabled");
   2936 		if (wpa_s->global->p2p_disabled) {
   2937 			wpas_p2p_stop_find(wpa_s);
   2938 			os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
   2939 			p2p_flush(wpa_s->global->p2p);
   2940 		}
   2941 		return 0;
   2942 	}
   2943 
   2944 	if (os_strcmp(cmd, "force_long_sd") == 0) {
   2945 		wpa_s->force_long_sd = atoi(param);
   2946 		return 0;
   2947 	}
   2948 
   2949 	if (os_strcmp(cmd, "peer_filter") == 0) {
   2950 		u8 addr[ETH_ALEN];
   2951 		if (hwaddr_aton(param, addr))
   2952 			return -1;
   2953 		p2p_set_peer_filter(wpa_s->global->p2p, addr);
   2954 		return 0;
   2955 	}
   2956 
   2957 	if (os_strcmp(cmd, "cross_connect") == 0)
   2958 		return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
   2959 
   2960 	if (os_strcmp(cmd, "go_apsd") == 0) {
   2961 		if (os_strcmp(param, "disable") == 0)
   2962 			wpa_s->set_ap_uapsd = 0;
   2963 		else {
   2964 			wpa_s->set_ap_uapsd = 1;
   2965 			wpa_s->ap_uapsd = atoi(param);
   2966 		}
   2967 		return 0;
   2968 	}
   2969 
   2970 	if (os_strcmp(cmd, "client_apsd") == 0) {
   2971 		if (os_strcmp(param, "disable") == 0)
   2972 			wpa_s->set_sta_uapsd = 0;
   2973 		else {
   2974 			int be, bk, vi, vo;
   2975 			char *pos;
   2976 			/* format: BE,BK,VI,VO;max SP Length */
   2977 			be = atoi(param);
   2978 			pos = os_strchr(param, ',');
   2979 			if (pos == NULL)
   2980 				return -1;
   2981 			pos++;
   2982 			bk = atoi(pos);
   2983 			pos = os_strchr(pos, ',');
   2984 			if (pos == NULL)
   2985 				return -1;
   2986 			pos++;
   2987 			vi = atoi(pos);
   2988 			pos = os_strchr(pos, ',');
   2989 			if (pos == NULL)
   2990 				return -1;
   2991 			pos++;
   2992 			vo = atoi(pos);
   2993 			/* ignore max SP Length for now */
   2994 
   2995 			wpa_s->set_sta_uapsd = 1;
   2996 			wpa_s->sta_uapsd = 0;
   2997 			if (be)
   2998 				wpa_s->sta_uapsd |= BIT(0);
   2999 			if (bk)
   3000 				wpa_s->sta_uapsd |= BIT(1);
   3001 			if (vi)
   3002 				wpa_s->sta_uapsd |= BIT(2);
   3003 			if (vo)
   3004 				wpa_s->sta_uapsd |= BIT(3);
   3005 		}
   3006 		return 0;
   3007 	}
   3008 
   3009 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
   3010 		   cmd);
   3011 
   3012 	return -1;
   3013 }
   3014 
   3015 
   3016 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
   3017 {
   3018 	char *pos, *pos2;
   3019 	unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
   3020 
   3021 	if (cmd[0]) {
   3022 		pos = os_strchr(cmd, ' ');
   3023 		if (pos == NULL)
   3024 			return -1;
   3025 		*pos++ = '\0';
   3026 		dur1 = atoi(cmd);
   3027 
   3028 		pos2 = os_strchr(pos, ' ');
   3029 		if (pos2)
   3030 			*pos2++ = '\0';
   3031 		int1 = atoi(pos);
   3032 	} else
   3033 		pos2 = NULL;
   3034 
   3035 	if (pos2) {
   3036 		pos = os_strchr(pos2, ' ');
   3037 		if (pos == NULL)
   3038 			return -1;
   3039 		*pos++ = '\0';
   3040 		dur2 = atoi(pos2);
   3041 		int2 = atoi(pos);
   3042 	}
   3043 
   3044 	return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
   3045 }
   3046 
   3047 
   3048 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
   3049 {
   3050 	char *pos;
   3051 	unsigned int period = 0, interval = 0;
   3052 
   3053 	if (cmd[0]) {
   3054 		pos = os_strchr(cmd, ' ');
   3055 		if (pos == NULL)
   3056 			return -1;
   3057 		*pos++ = '\0';
   3058 		period = atoi(cmd);
   3059 		interval = atoi(pos);
   3060 	}
   3061 
   3062 	return wpas_p2p_ext_listen(wpa_s, period, interval);
   3063 }
   3064 
   3065 #endif /* CONFIG_P2P */
   3066 
   3067 
   3068 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
   3069 	struct wpa_supplicant *wpa_s, char *cmd)
   3070 {
   3071 	wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
   3072 	return 0;
   3073 }
   3074 
   3075 
   3076 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
   3077 				      size_t buflen)
   3078 {
   3079 	struct wpa_signal_info si;
   3080 	int ret;
   3081 
   3082 	ret = wpa_drv_signal_poll(wpa_s, &si);
   3083 	if (ret)
   3084 		return -1;
   3085 
   3086 	ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n"
   3087 			  "NOISE=%d\nFREQUENCY=%u\n",
   3088 			  si.current_signal, si.current_txrate / 1000,
   3089 			  si.current_noise, si.frequency);
   3090 	if (ret < 0 || (unsigned int) ret > buflen)
   3091 		return -1;
   3092 	return ret;
   3093 }
   3094 
   3095 
   3096 static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
   3097 				     char *buf, size_t buflen)
   3098 {
   3099 	int ret;
   3100 
   3101 	ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
   3102 	if (ret == 0)
   3103 		ret = sprintf(buf, "%s\n", "OK");
   3104 	return ret;
   3105 }
   3106 
   3107 
   3108 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
   3109 					 char *buf, size_t *resp_len)
   3110 {
   3111 	char *reply;
   3112 	const int reply_size = 4096;
   3113 	int ctrl_rsp = 0;
   3114 	int reply_len;
   3115 
   3116 	if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
   3117 	    os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
   3118 		wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
   3119 				      (const u8 *) buf, os_strlen(buf));
   3120 	} else {
   3121 		int level = MSG_DEBUG;
   3122 		if (os_strcmp(buf, "PING") == 0)
   3123 			level = MSG_EXCESSIVE;
   3124 		wpa_hexdump_ascii(level, "RX ctrl_iface",
   3125 				  (const u8 *) buf, os_strlen(buf));
   3126 	}
   3127 
   3128 	reply = os_malloc(reply_size);
   3129 	if (reply == NULL) {
   3130 		*resp_len = 1;
   3131 		return NULL;
   3132 	}
   3133 
   3134 	os_memcpy(reply, "OK\n", 3);
   3135 	reply_len = 3;
   3136 
   3137 	if (os_strcmp(buf, "PING") == 0) {
   3138 		os_memcpy(reply, "PONG\n", 5);
   3139 		reply_len = 5;
   3140 	} else if (os_strncmp(buf, "RELOG", 5) == 0) {
   3141 		if (wpa_debug_reopen_file() < 0)
   3142 			reply_len = -1;
   3143 	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
   3144 		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
   3145 	} else if (os_strcmp(buf, "MIB") == 0) {
   3146 		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
   3147 		if (reply_len >= 0) {
   3148 			int res;
   3149 			res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
   3150 					       reply_size - reply_len);
   3151 			if (res < 0)
   3152 				reply_len = -1;
   3153 			else
   3154 				reply_len += res;
   3155 		}
   3156 	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
   3157 		reply_len = wpa_supplicant_ctrl_iface_status(
   3158 			wpa_s, buf + 6, reply, reply_size);
   3159 	} else if (os_strcmp(buf, "PMKSA") == 0) {
   3160 		reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
   3161 						    reply_size);
   3162 	} else if (os_strncmp(buf, "SET ", 4) == 0) {
   3163 		if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
   3164 			reply_len = -1;
   3165 	} else if (os_strncmp(buf, "GET ", 4) == 0) {
   3166 		reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
   3167 							  reply, reply_size);
   3168 	} else if (os_strcmp(buf, "LOGON") == 0) {
   3169 		eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
   3170 	} else if (os_strcmp(buf, "LOGOFF") == 0) {
   3171 		eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
   3172 	} else if (os_strcmp(buf, "REASSOCIATE") == 0) {
   3173 		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
   3174 			reply_len = -1;
   3175 		else {
   3176 			wpa_s->disconnected = 0;
   3177 			wpa_s->reassociate = 1;
   3178 			wpa_supplicant_req_scan(wpa_s, 0, 0);
   3179 		}
   3180 	} else if (os_strcmp(buf, "RECONNECT") == 0) {
   3181 		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
   3182 			reply_len = -1;
   3183 		else if (wpa_s->disconnected) {
   3184 			wpa_s->disconnected = 0;
   3185 			wpa_s->reassociate = 1;
   3186 			wpa_supplicant_req_scan(wpa_s, 0, 0);
   3187 		}
   3188 #ifdef IEEE8021X_EAPOL
   3189 	} else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
   3190 		if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
   3191 			reply_len = -1;
   3192 #endif /* IEEE8021X_EAPOL */
   3193 #ifdef CONFIG_PEERKEY
   3194 	} else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
   3195 		if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
   3196 			reply_len = -1;
   3197 #endif /* CONFIG_PEERKEY */
   3198 #ifdef CONFIG_IEEE80211R
   3199 	} else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
   3200 		if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
   3201 			reply_len = -1;
   3202 #endif /* CONFIG_IEEE80211R */
   3203 #ifdef CONFIG_WPS
   3204 	} else if (os_strcmp(buf, "WPS_PBC") == 0) {
   3205 		int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL);
   3206 		if (res == -2) {
   3207 			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
   3208 			reply_len = 17;
   3209 		} else if (res)
   3210 			reply_len = -1;
   3211 	} else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
   3212 		int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8);
   3213 		if (res == -2) {
   3214 			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
   3215 			reply_len = 17;
   3216 		} else if (res)
   3217 			reply_len = -1;
   3218 	} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
   3219 		reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
   3220 							      reply,
   3221 							      reply_size);
   3222 	} else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
   3223 		reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
   3224 			wpa_s, buf + 14, reply, reply_size);
   3225 	} else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
   3226 		if (wpas_wps_cancel(wpa_s))
   3227 			reply_len = -1;
   3228 #ifdef CONFIG_WPS_OOB
   3229 	} else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
   3230 		if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
   3231 			reply_len = -1;
   3232 #endif /* CONFIG_WPS_OOB */
   3233 	} else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
   3234 		if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
   3235 			reply_len = -1;
   3236 #ifdef CONFIG_AP
   3237 	} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
   3238 		reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
   3239 			wpa_s, buf + 11, reply, reply_size);
   3240 #endif /* CONFIG_AP */
   3241 #ifdef CONFIG_WPS_ER
   3242 	} else if (os_strcmp(buf, "WPS_ER_START") == 0) {
   3243 		if (wpas_wps_er_start(wpa_s, NULL))
   3244 			reply_len = -1;
   3245 	} else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
   3246 		if (wpas_wps_er_start(wpa_s, buf + 13))
   3247 			reply_len = -1;
   3248 	} else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
   3249 		if (wpas_wps_er_stop(wpa_s))
   3250 			reply_len = -1;
   3251 	} else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
   3252 		if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
   3253 			reply_len = -1;
   3254 	} else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
   3255 		int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
   3256 		if (ret == -2) {
   3257 			os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
   3258 			reply_len = 17;
   3259 		} else if (ret == -3) {
   3260 			os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
   3261 			reply_len = 18;
   3262 		} else if (ret == -4) {
   3263 			os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
   3264 			reply_len = 20;
   3265 		} else if (ret)
   3266 			reply_len = -1;
   3267 	} else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
   3268 		if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
   3269 			reply_len = -1;
   3270 	} else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
   3271 		if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
   3272 								buf + 18))
   3273 			reply_len = -1;
   3274 	} else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
   3275 		if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
   3276 			reply_len = -1;
   3277 #endif /* CONFIG_WPS_ER */
   3278 #endif /* CONFIG_WPS */
   3279 #ifdef CONFIG_IBSS_RSN
   3280 	} else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
   3281 		if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
   3282 			reply_len = -1;
   3283 #endif /* CONFIG_IBSS_RSN */
   3284 #ifdef CONFIG_P2P
   3285 	} else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
   3286 		if (p2p_ctrl_find(wpa_s, buf + 9))
   3287 			reply_len = -1;
   3288 	} else if (os_strcmp(buf, "P2P_FIND") == 0) {
   3289 		if (p2p_ctrl_find(wpa_s, ""))
   3290 			reply_len = -1;
   3291 	} else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
   3292 		wpas_p2p_stop_find(wpa_s);
   3293 	} else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
   3294 		reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
   3295 					     reply_size);
   3296 	} else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
   3297 		if (p2p_ctrl_listen(wpa_s, buf + 11))
   3298 			reply_len = -1;
   3299 	} else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
   3300 		if (p2p_ctrl_listen(wpa_s, ""))
   3301 			reply_len = -1;
   3302 	} else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
   3303 		if (wpas_p2p_group_remove(wpa_s, buf + 17))
   3304 			reply_len = -1;
   3305 	} else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
   3306 		if (wpas_p2p_group_add(wpa_s, 0, 0))
   3307 			reply_len = -1;
   3308 	} else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
   3309 		if (p2p_ctrl_group_add(wpa_s, buf + 14))
   3310 			reply_len = -1;
   3311 	} else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
   3312 		if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
   3313 			reply_len = -1;
   3314 	} else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
   3315 		reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
   3316 	} else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
   3317 		reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
   3318 						   reply_size);
   3319 	} else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
   3320 		if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
   3321 			reply_len = -1;
   3322 	} else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
   3323 		if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
   3324 			reply_len = -1;
   3325 	} else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
   3326 		wpas_p2p_sd_service_update(wpa_s);
   3327 	} else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
   3328 		if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
   3329 			reply_len = -1;
   3330 	} else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
   3331 		wpas_p2p_service_flush(wpa_s);
   3332 	} else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
   3333 		if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
   3334 			reply_len = -1;
   3335 	} else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
   3336 		if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
   3337 			reply_len = -1;
   3338 	} else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
   3339 		if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
   3340 			reply_len = -1;
   3341 	} else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
   3342 		if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
   3343 			reply_len = -1;
   3344 	} else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
   3345 		reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
   3346 					      reply_size);
   3347 	} else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
   3348 		if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
   3349 			reply_len = -1;
   3350 	} else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
   3351 		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
   3352 		wpa_s->force_long_sd = 0;
   3353 		if (wpa_s->global->p2p)
   3354 			p2p_flush(wpa_s->global->p2p);
   3355 	} else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
   3356 		if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
   3357 			reply_len = -1;
   3358 	} else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
   3359 		if (wpas_p2p_cancel(wpa_s))
   3360 			reply_len = -1;
   3361 	} else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
   3362 	#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
   3363 		/* We have to send presence command to p2p interface if p2p_interface is started
   3364 		 * otherwise we can send it to primary interface
   3365 		*/
   3366 		struct wpa_supplicant* ifs;
   3367 		for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
   3368 			if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
   3369 				wpa_s = ifs;
   3370 				break;
   3371 			}
   3372 		}
   3373 	#endif /* defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_P2P */
   3374 		if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
   3375 			reply_len = -1;
   3376 	} else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
   3377 		if (p2p_ctrl_presence_req(wpa_s, "") < 0)
   3378 			reply_len = -1;
   3379 	} else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
   3380 		if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
   3381 			reply_len = -1;
   3382 	} else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
   3383 		if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
   3384 			reply_len = -1;
   3385 #endif /* CONFIG_P2P */
   3386 	} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
   3387 	{
   3388 		if (wpa_supplicant_ctrl_iface_ctrl_rsp(
   3389 			    wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
   3390 			reply_len = -1;
   3391 		else
   3392 			ctrl_rsp = 1;
   3393 	} else if (os_strcmp(buf, "RECONFIGURE") == 0) {
   3394 		if (wpa_supplicant_reload_configuration(wpa_s))
   3395 			reply_len = -1;
   3396 	} else if (os_strcmp(buf, "TERMINATE") == 0) {
   3397 		wpa_supplicant_terminate_proc(wpa_s->global);
   3398 	} else if (os_strncmp(buf, "BSSID ", 6) == 0) {
   3399 		if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
   3400 			reply_len = -1;
   3401 	} else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
   3402 		reply_len = wpa_supplicant_ctrl_iface_log_level(wpa_s, buf + 9,
   3403 							reply, reply_size);
   3404 	} else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
   3405 		reply_len = wpa_supplicant_ctrl_iface_blacklist(wpa_s, buf + 9,
   3406 							reply, reply_size);
   3407 	} else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
   3408 		reply_len = wpa_supplicant_ctrl_iface_list_networks(
   3409 			wpa_s, reply, reply_size);
   3410 	} else if (os_strcmp(buf, "DISCONNECT") == 0) {
   3411 		wpa_s->reassociate = 0;
   3412 		wpa_s->disconnected = 1;
   3413 		wpa_supplicant_deauthenticate(wpa_s,
   3414 					      WLAN_REASON_DEAUTH_LEAVING);
   3415 	} else if (os_strcmp(buf, "SCAN") == 0) {
   3416 		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
   3417 			reply_len = -1;
   3418 		else {
   3419 			if (!wpa_s->scanning &&
   3420 			    ((wpa_s->wpa_state <= WPA_SCANNING) ||
   3421 			     (wpa_s->wpa_state == WPA_COMPLETED))) {
   3422 				wpa_s->scan_req = 2;
   3423 				wpa_supplicant_req_scan(wpa_s, 0, 0);
   3424 			} else {
   3425 				wpa_printf(MSG_DEBUG, "Ongoing scan action - "
   3426 					   "reject new request");
   3427 				reply_len = os_snprintf(reply, reply_size,
   3428 							"FAIL-BUSY\n");
   3429 			}
   3430 		}
   3431 	} else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
   3432 		reply_len = wpa_supplicant_ctrl_iface_scan_results(
   3433 			wpa_s, reply, reply_size);
   3434 	} else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
   3435 		if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
   3436 			reply_len = -1;
   3437 	} else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
   3438 		if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
   3439 			reply_len = -1;
   3440 	} else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
   3441 		if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
   3442 			reply_len = -1;
   3443 	} else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
   3444 		reply_len = wpa_supplicant_ctrl_iface_add_network(
   3445 			wpa_s, reply, reply_size);
   3446 	} else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
   3447 		if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
   3448 			reply_len = -1;
   3449 	} else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
   3450 		if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
   3451 			reply_len = -1;
   3452 	} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
   3453 		reply_len = wpa_supplicant_ctrl_iface_get_network(
   3454 			wpa_s, buf + 12, reply, reply_size);
   3455 #ifndef CONFIG_NO_CONFIG_WRITE
   3456 	} else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
   3457 		if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
   3458 			reply_len = -1;
   3459 #endif /* CONFIG_NO_CONFIG_WRITE */
   3460 	} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
   3461 		reply_len = wpa_supplicant_ctrl_iface_get_capability(
   3462 			wpa_s, buf + 15, reply, reply_size);
   3463 	} else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
   3464 		if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
   3465 			reply_len = -1;
   3466 	} else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) {
   3467 		if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14))
   3468 			reply_len = -1;
   3469 	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
   3470 		reply_len = wpa_supplicant_global_iface_list(
   3471 			wpa_s->global, reply, reply_size);
   3472 	} else if (os_strcmp(buf, "INTERFACES") == 0) {
   3473 		reply_len = wpa_supplicant_global_iface_interfaces(
   3474 			wpa_s->global, reply, reply_size);
   3475 	} else if (os_strncmp(buf, "BSS ", 4) == 0) {
   3476 		reply_len = wpa_supplicant_ctrl_iface_bss(
   3477 			wpa_s, buf + 4, reply, reply_size);
   3478 #ifdef CONFIG_AP
   3479 	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
   3480 		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
   3481 	} else if (os_strncmp(buf, "STA ", 4) == 0) {
   3482 		reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
   3483 					      reply_size);
   3484 	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
   3485 		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
   3486 						   reply_size);
   3487 #endif /* CONFIG_AP */
   3488 	} else if (os_strcmp(buf, "SUSPEND") == 0) {
   3489 		wpas_notify_suspend(wpa_s->global);
   3490 	} else if (os_strcmp(buf, "RESUME") == 0) {
   3491 		wpas_notify_resume(wpa_s->global);
   3492 	} else if (os_strcmp(buf, "DROP_SA") == 0) {
   3493 		wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
   3494 	} else if (os_strncmp(buf, "ROAM ", 5) == 0) {
   3495 		if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
   3496 			reply_len = -1;
   3497 	} else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
   3498 		if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
   3499 			reply_len = -1;
   3500 	} else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
   3501 		if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
   3502 			reply_len = -1;
   3503 	} else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
   3504 		if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s,
   3505 							       buf + 17))
   3506 			reply_len = -1;
   3507 #ifdef CONFIG_TDLS
   3508 	} else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
   3509 		if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
   3510 			reply_len = -1;
   3511 	} else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
   3512 		if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
   3513 			reply_len = -1;
   3514 	} else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
   3515 		if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
   3516 			reply_len = -1;
   3517 #endif /* CONFIG_TDLS */
   3518 	} else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
   3519 		reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
   3520 						       reply_size);
   3521 	} else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
   3522 		reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
   3523 						      reply_size);
   3524 	} else {
   3525 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
   3526 		reply_len = 16;
   3527 	}
   3528 
   3529 	if (reply_len < 0) {
   3530 		os_memcpy(reply, "FAIL\n", 5);
   3531 		reply_len = 5;
   3532 	}
   3533 
   3534 	if (ctrl_rsp)
   3535 		eapol_sm_notify_ctrl_response(wpa_s->eapol);
   3536 
   3537 	*resp_len = reply_len;
   3538 	return reply;
   3539 }
   3540 
   3541 
   3542 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
   3543 					   char *cmd)
   3544 {
   3545 	struct wpa_interface iface;
   3546 	char *pos;
   3547 
   3548 	/*
   3549 	 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
   3550 	 * TAB<bridge_ifname>
   3551 	 */
   3552 	wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
   3553 
   3554 	os_memset(&iface, 0, sizeof(iface));
   3555 
   3556 	do {
   3557 		iface.ifname = pos = cmd;
   3558 		pos = os_strchr(pos, '\t');
   3559 		if (pos)
   3560 			*pos++ = '\0';
   3561 		if (iface.ifname[0] == '\0')
   3562 			return -1;
   3563 		if (pos == NULL)
   3564 			break;
   3565 
   3566 		iface.confname = pos;
   3567 		pos = os_strchr(pos, '\t');
   3568 		if (pos)
   3569 			*pos++ = '\0';
   3570 		if (iface.confname[0] == '\0')
   3571 			iface.confname = NULL;
   3572 		if (pos == NULL)
   3573 			break;
   3574 
   3575 		iface.driver = pos;
   3576 		pos = os_strchr(pos, '\t');
   3577 		if (pos)
   3578 			*pos++ = '\0';
   3579 		if (iface.driver[0] == '\0')
   3580 			iface.driver = NULL;
   3581 		if (pos == NULL)
   3582 			break;
   3583 
   3584 		iface.ctrl_interface = pos;
   3585 		pos = os_strchr(pos, '\t');
   3586 		if (pos)
   3587 			*pos++ = '\0';
   3588 		if (iface.ctrl_interface[0] == '\0')
   3589 			iface.ctrl_interface = NULL;
   3590 		if (pos == NULL)
   3591 			break;
   3592 
   3593 		iface.driver_param = pos;
   3594 		pos = os_strchr(pos, '\t');
   3595 		if (pos)
   3596 			*pos++ = '\0';
   3597 		if (iface.driver_param[0] == '\0')
   3598 			iface.driver_param = NULL;
   3599 		if (pos == NULL)
   3600 			break;
   3601 
   3602 		iface.bridge_ifname = pos;
   3603 		pos = os_strchr(pos, '\t');
   3604 		if (pos)
   3605 			*pos++ = '\0';
   3606 		if (iface.bridge_ifname[0] == '\0')
   3607 			iface.bridge_ifname = NULL;
   3608 		if (pos == NULL)
   3609 			break;
   3610 	} while (0);
   3611 
   3612 	if (wpa_supplicant_get_iface(global, iface.ifname))
   3613 		return -1;
   3614 
   3615 	return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
   3616 }
   3617 
   3618 
   3619 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
   3620 					      char *cmd)
   3621 {
   3622 	struct wpa_supplicant *wpa_s;
   3623 
   3624 	wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
   3625 
   3626 	wpa_s = wpa_supplicant_get_iface(global, cmd);
   3627 	if (wpa_s == NULL)
   3628 		return -1;
   3629 	return wpa_supplicant_remove_iface(global, wpa_s, 0);
   3630 }
   3631 
   3632 
   3633 static void wpa_free_iface_info(struct wpa_interface_info *iface)
   3634 {
   3635 	struct wpa_interface_info *prev;
   3636 
   3637 	while (iface) {
   3638 		prev = iface;
   3639 		iface = iface->next;
   3640 
   3641 		os_free(prev->ifname);
   3642 		os_free(prev->desc);
   3643 		os_free(prev);
   3644 	}
   3645 }
   3646 
   3647 
   3648 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
   3649 					    char *buf, int len)
   3650 {
   3651 	int i, res;
   3652 	struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
   3653 	char *pos, *end;
   3654 
   3655 	for (i = 0; wpa_drivers[i]; i++) {
   3656 		struct wpa_driver_ops *drv = wpa_drivers[i];
   3657 		if (drv->get_interfaces == NULL)
   3658 			continue;
   3659 		tmp = drv->get_interfaces(global->drv_priv[i]);
   3660 		if (tmp == NULL)
   3661 			continue;
   3662 
   3663 		if (last == NULL)
   3664 			iface = last = tmp;
   3665 		else
   3666 			last->next = tmp;
   3667 		while (last->next)
   3668 			last = last->next;
   3669 	}
   3670 
   3671 	pos = buf;
   3672 	end = buf + len;
   3673 	for (tmp = iface; tmp; tmp = tmp->next) {
   3674 		res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
   3675 				  tmp->drv_name, tmp->ifname,
   3676 				  tmp->desc ? tmp->desc : "");
   3677 		if (res < 0 || res >= end - pos) {
   3678 			*pos = '\0';
   3679 			break;
   3680 		}
   3681 		pos += res;
   3682 	}
   3683 
   3684 	wpa_free_iface_info(iface);
   3685 
   3686 	return pos - buf;
   3687 }
   3688 
   3689 
   3690 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
   3691 						  char *buf, int len)
   3692 {
   3693 	int res;
   3694 	char *pos, *end;
   3695 	struct wpa_supplicant *wpa_s;
   3696 
   3697 	wpa_s = global->ifaces;
   3698 	pos = buf;
   3699 	end = buf + len;
   3700 
   3701 	while (wpa_s) {
   3702 		res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
   3703 		if (res < 0 || res >= end - pos) {
   3704 			*pos = '\0';
   3705 			break;
   3706 		}
   3707 		pos += res;
   3708 		wpa_s = wpa_s->next;
   3709 	}
   3710 	return pos - buf;
   3711 }
   3712 
   3713 
   3714 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
   3715 						char *buf, size_t *resp_len)
   3716 {
   3717 	char *reply;
   3718 	const int reply_size = 2048;
   3719 	int reply_len;
   3720 
   3721 	wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
   3722 			  (const u8 *) buf, os_strlen(buf));
   3723 
   3724 	reply = os_malloc(reply_size);
   3725 	if (reply == NULL) {
   3726 		*resp_len = 1;
   3727 		return NULL;
   3728 	}
   3729 
   3730 	os_memcpy(reply, "OK\n", 3);
   3731 	reply_len = 3;
   3732 
   3733 	if (os_strcmp(buf, "PING") == 0) {
   3734 		os_memcpy(reply, "PONG\n", 5);
   3735 		reply_len = 5;
   3736 	} else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
   3737 		if (wpa_supplicant_global_iface_add(global, buf + 14))
   3738 			reply_len = -1;
   3739 	} else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
   3740 		if (wpa_supplicant_global_iface_remove(global, buf + 17))
   3741 			reply_len = -1;
   3742 	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
   3743 		reply_len = wpa_supplicant_global_iface_list(
   3744 			global, reply, reply_size);
   3745 	} else if (os_strcmp(buf, "INTERFACES") == 0) {
   3746 		reply_len = wpa_supplicant_global_iface_interfaces(
   3747 			global, reply, reply_size);
   3748 	} else if (os_strcmp(buf, "TERMINATE") == 0) {
   3749 		wpa_supplicant_terminate_proc(global);
   3750 	} else if (os_strcmp(buf, "SUSPEND") == 0) {
   3751 		wpas_notify_suspend(global);
   3752 	} else if (os_strcmp(buf, "RESUME") == 0) {
   3753 		wpas_notify_resume(global);
   3754 	} else {
   3755 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
   3756 		reply_len = 16;
   3757 	}
   3758 
   3759 	if (reply_len < 0) {
   3760 		os_memcpy(reply, "FAIL\n", 5);
   3761 		reply_len = 5;
   3762 	}
   3763 
   3764 	*resp_len = reply_len;
   3765 	return reply;
   3766 }
   3767