Home | History | Annotate | Download | only in 1.2
      1 /*
      2  * hidl interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2016, Jouni Malinen <j (at) w1.fi>
      4  * Copyright (c) 2004-2016, Roshan Pius <rpius (at) google.com>
      5  * Copyright (C) 2017 Sony Mobile Communications Inc.
      6  *
      7  * This software may be distributed under the terms of the BSD license.
      8  * See README for more details.
      9  */
     10 
     11 #include "hidl_manager.h"
     12 #include "hidl_return_util.h"
     13 #include "iface_config_utils.h"
     14 #include "misc_utils.h"
     15 #include "p2p_iface.h"
     16 #include "sta_network.h"
     17 
     18 extern "C"
     19 {
     20 #include "ap.h"
     21 #include "wps_supplicant.h"
     22 #include "wifi_display.h"
     23 #include "utils/eloop.h"
     24 #include "wpa_supplicant_i.h"
     25 #include "driver_i.h"
     26 }
     27 
     28 #define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
     29 
     30 namespace {
     31 const char kConfigMethodStrPbc[] = "pbc";
     32 const char kConfigMethodStrDisplay[] = "display";
     33 const char kConfigMethodStrKeypad[] = "keypad";
     34 constexpr char kSetMiracastMode[] = "MIRACAST ";
     35 constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
     36 constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
     37 
     38 std::function<void()> pending_join_scan_callback = NULL;
     39 std::function<void()> pending_scan_res_join_callback = NULL;
     40 
     41 using android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
     42 using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
     43 uint8_t convertHidlMiracastModeToInternal(
     44     ISupplicantP2pIface::MiracastMode mode)
     45 {
     46 	switch (mode) {
     47 	case ISupplicantP2pIface::MiracastMode::DISABLED:
     48 		return 0;
     49 	case ISupplicantP2pIface::MiracastMode::SOURCE:
     50 		return 1;
     51 	case ISupplicantP2pIface::MiracastMode::SINK:
     52 		return 2;
     53 	};
     54 	WPA_ASSERT(false);
     55 }
     56 
     57 /**
     58  * Check if the provided ssid is valid or not.
     59  *
     60  * Returns 1 if valid, 0 otherwise.
     61  */
     62 int isSsidValid(const std::vector<uint8_t>& ssid)
     63 {
     64 	if (ssid.size() == 0 ||
     65 	    ssid.size() >
     66 		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
     67 					  SSID_MAX_LEN_IN_BYTES)) {
     68 		return 0;
     69 	}
     70 	return 1;
     71 }
     72 
     73 /**
     74  * Check if the provided psk passhrase is valid or not.
     75  *
     76  * Returns 1 if valid, 0 otherwise.
     77  */
     78 int isPskPassphraseValid(const std::string &psk)
     79 {
     80 	if (psk.size() <
     81 		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
     82 					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
     83 	    psk.size() >
     84 		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
     85 					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
     86 		return 0;
     87 	}
     88 	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
     89 		return 0;
     90 	}
     91 	return 1;
     92 }
     93 
     94 void setBandScanFreqsList(
     95     struct wpa_supplicant *wpa_s,
     96     enum hostapd_hw_mode band,
     97     struct wpa_driver_scan_params *params)
     98 {
     99 	/* Include only supported channels for the specified band */
    100 	struct hostapd_hw_modes *mode;
    101 	int count, i;
    102 
    103 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
    104 	if (mode == NULL) {
    105 		/* No channels supported in this band. */
    106 		return;
    107 	}
    108 
    109 	params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
    110 	if (params->freqs == NULL)
    111 		return;
    112 	for (count = 0, i = 0; i < mode->num_channels; i++) {
    113 		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
    114 			continue;
    115 		params->freqs[count++] = mode->channels[i].freq;
    116 	}
    117 }
    118 /*
    119  * isAnyEtherAddr - match any ether address
    120  *
    121  */
    122 int isAnyEtherAddr(const u8 *a)
    123 {
    124 	// 02:00:00:00:00:00
    125 	return (a[0] == 2) && !(a[1] | a[2] | a[3] | a[4] | a[5]);
    126 }
    127 
    128 /**
    129  * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
    130  * @wpa_s: Pointer to wpa_supplicant data
    131  * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
    132  * @ssid: SSID
    133  * @ssid_len: Length of @ssid
    134  * Returns: Pointer to the BSS entry or %NULL if not found
    135  */
    136 struct wpa_bss* findBssBySsid(
    137     struct wpa_supplicant *wpa_s, const u8 *bssid,
    138     const u8 *ssid, size_t ssid_len)
    139 {
    140 	struct wpa_bss *bss;
    141 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
    142 		if ((isAnyEtherAddr(bssid) ||
    143 		    os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
    144 		    bss->ssid_len == ssid_len &&
    145 		    os_memcmp(bss->ssid, ssid, ssid_len) == 0)
    146 			return bss;
    147 	}
    148 	return NULL;
    149 }
    150 
    151 struct wpa_ssid* addGroupClientNetwork(
    152     struct wpa_supplicant* wpa_s,
    153     uint8_t *group_owner_bssid,
    154     const std::vector<uint8_t>& ssid,
    155     const std::string& passphrase)
    156 {
    157 	struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
    158 	if (!wpa_network) {
    159 		return NULL;
    160 	}
    161 	// set general network defaults
    162 	wpa_config_set_network_defaults(wpa_network);
    163 
    164 	// set P2p network defaults
    165 	wpa_network->p2p_group = 1;
    166 	wpa_network->mode = wpa_ssid::wpas_mode::WPAS_MODE_INFRA;
    167 
    168 	wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
    169 	wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
    170 	wpa_network->proto = WPA_PROTO_RSN;
    171 	wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
    172 	wpa_network->group_cipher = WPA_CIPHER_CCMP;
    173 	wpa_network->disabled = 2;
    174 
    175 	// set necessary fields
    176 	os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
    177 	wpa_network->bssid_set = 1;
    178 
    179 	wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
    180 	if (wpa_network->ssid == NULL) {
    181 		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
    182 		return  NULL;
    183 	}
    184 	memcpy(wpa_network->ssid, ssid.data(), ssid.size());
    185 	wpa_network->ssid_len = ssid.size();
    186 
    187 	wpa_network->psk_set = 0;
    188 	wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
    189 	if (wpa_network->passphrase == NULL) {
    190 		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
    191 		return  NULL;
    192 	}
    193 	wpa_config_update_psk(wpa_network);
    194 
    195 	return wpa_network;
    196 
    197 }
    198 
    199 void joinScanWrapper(void *eloop_ctx, void *timeout_ctx)
    200 {
    201 	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *) eloop_ctx;
    202 
    203 	if (pending_join_scan_callback != NULL) {
    204 		pending_join_scan_callback();
    205 	}
    206 }
    207 
    208 void scanResJoinWrapper(
    209     struct wpa_supplicant *wpa_s,
    210     struct wpa_scan_results *scan_res)
    211 {
    212 	if (pending_scan_res_join_callback) {
    213 		pending_scan_res_join_callback();
    214 	}
    215 }
    216 
    217 int joinScanReq(
    218     struct wpa_supplicant* wpa_s,
    219     const std::vector<uint8_t>& ssid,
    220     int freq)
    221 {
    222 	int ret;
    223 	struct wpa_driver_scan_params params;
    224 	struct wpabuf *ies;
    225 	size_t ielen;
    226 	unsigned int bands;
    227 
    228 	os_memset(&params, 0, sizeof(params));
    229 	if (ssid.size() > 0) {
    230 		params.ssids[0].ssid = ssid.data();
    231 		params.ssids[0].ssid_len = ssid.size();
    232 	} else {
    233 		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
    234 		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
    235 	}
    236 	wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d (reinvoke)",
    237 	    wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq);
    238 
    239 	if (freq > 0) {
    240 		if (freq == 2 || freq == 5) {
    241 			if (wpa_s->hw.modes != NULL) {
    242 				switch (freq) {
    243 				case 2:
    244 					setBandScanFreqsList(wpa_s,
    245 					    HOSTAPD_MODE_IEEE80211G, &params);
    246 				break;
    247 				case 5:
    248 					setBandScanFreqsList(wpa_s,
    249 					    HOSTAPD_MODE_IEEE80211A, &params);
    250 				break;
    251 				}
    252 				if (!params.freqs) {
    253 					wpa_printf(MSG_ERROR,
    254 					    "P2P: No supported channels in %dG band.", freq);
    255 					return -1;
    256 				}
    257 			} else {
    258 				wpa_printf(MSG_DEBUG,
    259 				    "P2P: Unknown what %dG channels the driver supports.", freq);
    260 			}
    261 		} else {
    262 			if (0 == p2p_supported_freq_cli(wpa_s->global->p2p, freq)) {
    263 				wpa_printf(MSG_ERROR,
    264 				    "P2P: freq %d is not supported for a client.", freq);
    265 				return -1;
    266 			}
    267 
    268 			/*
    269 			 * Allocate memory for frequency array, allocate one extra
    270 			 * slot for the zero-terminator.
    271 			 */
    272 			params.freqs = (int *) os_calloc(2, sizeof(int));
    273 			if (params.freqs) {
    274 				params.freqs[0] = freq;
    275 			} else {
    276 				wpa_printf(MSG_ERROR,
    277 				    "P2P: Cannot allocate memory for scan params.");
    278 				return -1;
    279 			}
    280 		}
    281 	}
    282 
    283 	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
    284 	ies = wpabuf_alloc(ielen);
    285 	if (ies == NULL) {
    286 		if (params.freqs) {
    287 			os_free(params.freqs);
    288 		}
    289 		return -1;
    290 	}
    291 
    292 	bands = wpas_get_bands(wpa_s, params.freqs);
    293 	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
    294 
    295 	params.p2p_probe = 1;
    296 	params.extra_ies = (u8 *) wpabuf_head(ies);
    297 	params.extra_ies_len = wpabuf_len(ies);
    298 	if (wpa_s->clear_driver_scan_cache) {
    299 		wpa_printf(MSG_DEBUG,
    300 		    "Request driver to clear scan cache due to local BSS flush");
    301 		params.only_new_results = 1;
    302 	}
    303 
    304 	ret = wpa_drv_scan(wpa_s, &params);
    305 	if (!ret) {
    306 		os_get_reltime(&wpa_s->scan_trigger_time);
    307 		wpa_s->scan_res_handler = scanResJoinWrapper;
    308 		wpa_s->own_scan_requested = 1;
    309 		wpa_s->clear_driver_scan_cache = 0;
    310 	}
    311 
    312 	if (params.freqs) {
    313 		os_free(params.freqs);
    314 	}
    315 
    316 	wpabuf_free(ies);
    317 
    318 	return ret;
    319 }
    320 
    321 int joinGroup(
    322     struct wpa_supplicant* wpa_s,
    323     uint8_t *group_owner_bssid,
    324     const std::vector<uint8_t>& ssid,
    325     const std::string& passphrase)
    326 {
    327 	int ret = 0;
    328 	int vht = wpa_s->conf->p2p_go_vht;
    329 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
    330 
    331 	// Construct a network for adding group.
    332 	// Group client follows the persistent attribute of Group Owner.
    333 	// If joined group is persistent, it adds a persistent network on GroupStarted.
    334 	struct wpa_ssid *wpa_network = addGroupClientNetwork(
    335 	    wpa_s, group_owner_bssid, ssid, passphrase);
    336 	if (wpa_network == NULL) {
    337 		wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
    338 		return -1;
    339 	}
    340 
    341 	// this is temporary network only for establishing the connection.
    342 	wpa_network->temporary = 1;
    343 
    344 	if (wpas_p2p_group_add_persistent(
    345 		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
    346 		VHT_CHANWIDTH_USE_HT, 0, NULL, 0, 1)) {
    347 		ret = -1;
    348 	}
    349 
    350 	// Always remove this temporary network at the end.
    351 	wpa_config_remove_network(wpa_s->conf, wpa_network->id);
    352 	return ret;
    353 }
    354 
    355 void notifyGroupJoinFailure(
    356     struct wpa_supplicant* wpa_s)
    357 {
    358 	u8 zero_addr[ETH_ALEN] = {0};
    359 	std::vector<uint8_t> ssid = {'D', 'I', 'R', 'E','C', 'T', '-'};
    360 	std::string passphrase = "";
    361 	struct wpa_ssid *wpa_network = addGroupClientNetwork(
    362 	    wpa_s, zero_addr, ssid, passphrase);
    363 	if (wpa_network) {
    364 		wpa_network->temporary = 1;
    365 		wpas_notify_p2p_group_formation_failure(wpa_s, "Failed to find the group.");
    366 		wpas_notify_p2p_group_removed(
    367 		    wpa_s, wpa_network, "client");
    368 		wpa_config_remove_network(
    369 		    wpa_s->conf, wpa_network->id);
    370 	} else {
    371 		wpa_printf(MSG_ERROR,
    372 		    "P2P: Cannot construct a network.");
    373 	}
    374 }
    375 
    376 void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
    377 	wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
    378 }
    379 
    380 }  // namespace
    381 
    382 namespace android {
    383 namespace hardware {
    384 namespace wifi {
    385 namespace supplicant {
    386 namespace V1_2 {
    387 namespace implementation {
    388 using hidl_return_util::validateAndCall;
    389 
    390 P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
    391     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
    392 {}
    393 
    394 void P2pIface::invalidate() { is_valid_ = false; }
    395 bool P2pIface::isValid()
    396 {
    397 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
    398 }
    399 Return<void> P2pIface::getName(getName_cb _hidl_cb)
    400 {
    401 	return validateAndCall(
    402 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    403 	    &P2pIface::getNameInternal, _hidl_cb);
    404 }
    405 
    406 Return<void> P2pIface::getType(getType_cb _hidl_cb)
    407 {
    408 	return validateAndCall(
    409 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    410 	    &P2pIface::getTypeInternal, _hidl_cb);
    411 }
    412 
    413 Return<void> P2pIface::addNetwork(addNetwork_cb _hidl_cb)
    414 {
    415 	return validateAndCall(
    416 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    417 	    &P2pIface::addNetworkInternal, _hidl_cb);
    418 }
    419 
    420 Return<void> P2pIface::removeNetwork(
    421     SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
    422 {
    423 	return validateAndCall(
    424 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    425 	    &P2pIface::removeNetworkInternal, _hidl_cb, id);
    426 }
    427 
    428 Return<void> P2pIface::getNetwork(
    429     SupplicantNetworkId id, getNetwork_cb _hidl_cb)
    430 {
    431 	return validateAndCall(
    432 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    433 	    &P2pIface::getNetworkInternal, _hidl_cb, id);
    434 }
    435 
    436 Return<void> P2pIface::listNetworks(listNetworks_cb _hidl_cb)
    437 {
    438 	return validateAndCall(
    439 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    440 	    &P2pIface::listNetworksInternal, _hidl_cb);
    441 }
    442 
    443 Return<void> P2pIface::registerCallback(
    444     const sp<ISupplicantP2pIfaceCallback>& callback,
    445     registerCallback_cb _hidl_cb)
    446 {
    447 	return validateAndCall(
    448 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    449 	    &P2pIface::registerCallbackInternal, _hidl_cb, callback);
    450 }
    451 
    452 Return<void> P2pIface::getDeviceAddress(getDeviceAddress_cb _hidl_cb)
    453 {
    454 	return validateAndCall(
    455 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    456 	    &P2pIface::getDeviceAddressInternal, _hidl_cb);
    457 }
    458 
    459 Return<void> P2pIface::setSsidPostfix(
    460     const hidl_vec<uint8_t>& postfix, setSsidPostfix_cb _hidl_cb)
    461 {
    462 	return validateAndCall(
    463 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    464 	    &P2pIface::setSsidPostfixInternal, _hidl_cb, postfix);
    465 }
    466 
    467 Return<void> P2pIface::setGroupIdle(
    468     const hidl_string& group_ifname, uint32_t timeout_in_sec,
    469     setGroupIdle_cb _hidl_cb)
    470 {
    471 	return validateAndCall(
    472 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    473 	    &P2pIface::setGroupIdleInternal, _hidl_cb, group_ifname,
    474 	    timeout_in_sec);
    475 }
    476 
    477 Return<void> P2pIface::setPowerSave(
    478     const hidl_string& group_ifname, bool enable, setPowerSave_cb _hidl_cb)
    479 {
    480 	return validateAndCall(
    481 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    482 	    &P2pIface::setPowerSaveInternal, _hidl_cb, group_ifname, enable);
    483 }
    484 
    485 Return<void> P2pIface::find(uint32_t timeout_in_sec, find_cb _hidl_cb)
    486 {
    487 	return validateAndCall(
    488 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    489 	    &P2pIface::findInternal, _hidl_cb, timeout_in_sec);
    490 }
    491 
    492 Return<void> P2pIface::stopFind(stopFind_cb _hidl_cb)
    493 {
    494 	return validateAndCall(
    495 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    496 	    &P2pIface::stopFindInternal, _hidl_cb);
    497 }
    498 
    499 Return<void> P2pIface::flush(flush_cb _hidl_cb)
    500 {
    501 	return validateAndCall(
    502 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    503 	    &P2pIface::flushInternal, _hidl_cb);
    504 }
    505 
    506 Return<void> P2pIface::connect(
    507     const hidl_array<uint8_t, 6>& peer_address,
    508     ISupplicantP2pIface::WpsProvisionMethod provision_method,
    509     const hidl_string& pre_selected_pin, bool join_existing_group,
    510     bool persistent, uint32_t go_intent, connect_cb _hidl_cb)
    511 {
    512 	return validateAndCall(
    513 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    514 	    &P2pIface::connectInternal, _hidl_cb, peer_address,
    515 	    provision_method, pre_selected_pin, join_existing_group, persistent,
    516 	    go_intent);
    517 }
    518 
    519 Return<void> P2pIface::cancelConnect(cancelConnect_cb _hidl_cb)
    520 {
    521 	return validateAndCall(
    522 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    523 	    &P2pIface::cancelConnectInternal, _hidl_cb);
    524 }
    525 
    526 Return<void> P2pIface::provisionDiscovery(
    527     const hidl_array<uint8_t, 6>& peer_address,
    528     ISupplicantP2pIface::WpsProvisionMethod provision_method,
    529     provisionDiscovery_cb _hidl_cb)
    530 {
    531 	return validateAndCall(
    532 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    533 	    &P2pIface::provisionDiscoveryInternal, _hidl_cb, peer_address,
    534 	    provision_method);
    535 }
    536 
    537 Return<void> P2pIface::addGroup(
    538     bool persistent, SupplicantNetworkId persistent_network_id,
    539     addGroup_cb _hidl_cb)
    540 {
    541 	return validateAndCall(
    542 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    543 	    &P2pIface::addGroupInternal, _hidl_cb, persistent,
    544 	    persistent_network_id);
    545 }
    546 
    547 Return<void> P2pIface::removeGroup(
    548     const hidl_string& group_ifname, removeGroup_cb _hidl_cb)
    549 {
    550 	return validateAndCall(
    551 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    552 	    &P2pIface::removeGroupInternal, _hidl_cb, group_ifname);
    553 }
    554 
    555 Return<void> P2pIface::reject(
    556     const hidl_array<uint8_t, 6>& peer_address, reject_cb _hidl_cb)
    557 {
    558 	return validateAndCall(
    559 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    560 	    &P2pIface::rejectInternal, _hidl_cb, peer_address);
    561 }
    562 
    563 Return<void> P2pIface::invite(
    564     const hidl_string& group_ifname,
    565     const hidl_array<uint8_t, 6>& go_device_address,
    566     const hidl_array<uint8_t, 6>& peer_address, invite_cb _hidl_cb)
    567 {
    568 	return validateAndCall(
    569 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    570 	    &P2pIface::inviteInternal, _hidl_cb, group_ifname,
    571 	    go_device_address, peer_address);
    572 }
    573 
    574 Return<void> P2pIface::reinvoke(
    575     SupplicantNetworkId persistent_network_id,
    576     const hidl_array<uint8_t, 6>& peer_address, reinvoke_cb _hidl_cb)
    577 {
    578 	return validateAndCall(
    579 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    580 	    &P2pIface::reinvokeInternal, _hidl_cb, persistent_network_id,
    581 	    peer_address);
    582 }
    583 
    584 Return<void> P2pIface::configureExtListen(
    585     uint32_t period_in_millis, uint32_t interval_in_millis,
    586     configureExtListen_cb _hidl_cb)
    587 {
    588 	return validateAndCall(
    589 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    590 	    &P2pIface::configureExtListenInternal, _hidl_cb, period_in_millis,
    591 	    interval_in_millis);
    592 }
    593 
    594 Return<void> P2pIface::setListenChannel(
    595     uint32_t channel, uint32_t operating_class, setListenChannel_cb _hidl_cb)
    596 {
    597 	return validateAndCall(
    598 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    599 	    &P2pIface::setListenChannelInternal, _hidl_cb, channel,
    600 	    operating_class);
    601 }
    602 
    603 Return<void> P2pIface::setDisallowedFrequencies(
    604     const hidl_vec<FreqRange>& ranges, setDisallowedFrequencies_cb _hidl_cb)
    605 {
    606 	return validateAndCall(
    607 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    608 	    &P2pIface::setDisallowedFrequenciesInternal, _hidl_cb, ranges);
    609 }
    610 
    611 Return<void> P2pIface::getSsid(
    612     const hidl_array<uint8_t, 6>& peer_address, getSsid_cb _hidl_cb)
    613 {
    614 	return validateAndCall(
    615 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    616 	    &P2pIface::getSsidInternal, _hidl_cb, peer_address);
    617 }
    618 
    619 Return<void> P2pIface::getGroupCapability(
    620     const hidl_array<uint8_t, 6>& peer_address, getGroupCapability_cb _hidl_cb)
    621 {
    622 	return validateAndCall(
    623 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    624 	    &P2pIface::getGroupCapabilityInternal, _hidl_cb, peer_address);
    625 }
    626 
    627 Return<void> P2pIface::addBonjourService(
    628     const hidl_vec<uint8_t>& query, const hidl_vec<uint8_t>& response,
    629     addBonjourService_cb _hidl_cb)
    630 {
    631 	return validateAndCall(
    632 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    633 	    &P2pIface::addBonjourServiceInternal, _hidl_cb, query, response);
    634 }
    635 
    636 Return<void> P2pIface::removeBonjourService(
    637     const hidl_vec<uint8_t>& query, removeBonjourService_cb _hidl_cb)
    638 {
    639 	return validateAndCall(
    640 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    641 	    &P2pIface::removeBonjourServiceInternal, _hidl_cb, query);
    642 }
    643 
    644 Return<void> P2pIface::addUpnpService(
    645     uint32_t version, const hidl_string& service_name,
    646     addUpnpService_cb _hidl_cb)
    647 {
    648 	return validateAndCall(
    649 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    650 	    &P2pIface::addUpnpServiceInternal, _hidl_cb, version, service_name);
    651 }
    652 
    653 Return<void> P2pIface::removeUpnpService(
    654     uint32_t version, const hidl_string& service_name,
    655     removeUpnpService_cb _hidl_cb)
    656 {
    657 	return validateAndCall(
    658 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    659 	    &P2pIface::removeUpnpServiceInternal, _hidl_cb, version,
    660 	    service_name);
    661 }
    662 
    663 Return<void> P2pIface::flushServices(flushServices_cb _hidl_cb)
    664 {
    665 	return validateAndCall(
    666 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    667 	    &P2pIface::flushServicesInternal, _hidl_cb);
    668 }
    669 
    670 Return<void> P2pIface::requestServiceDiscovery(
    671     const hidl_array<uint8_t, 6>& peer_address, const hidl_vec<uint8_t>& query,
    672     requestServiceDiscovery_cb _hidl_cb)
    673 {
    674 	return validateAndCall(
    675 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    676 	    &P2pIface::requestServiceDiscoveryInternal, _hidl_cb, peer_address,
    677 	    query);
    678 }
    679 
    680 Return<void> P2pIface::cancelServiceDiscovery(
    681     uint64_t identifier, cancelServiceDiscovery_cb _hidl_cb)
    682 {
    683 	return validateAndCall(
    684 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    685 	    &P2pIface::cancelServiceDiscoveryInternal, _hidl_cb, identifier);
    686 }
    687 
    688 Return<void> P2pIface::setMiracastMode(
    689     ISupplicantP2pIface::MiracastMode mode, setMiracastMode_cb _hidl_cb)
    690 {
    691 	return validateAndCall(
    692 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    693 	    &P2pIface::setMiracastModeInternal, _hidl_cb, mode);
    694 }
    695 
    696 Return<void> P2pIface::startWpsPbc(
    697     const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
    698     startWpsPbc_cb _hidl_cb)
    699 {
    700 	return validateAndCall(
    701 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    702 	    &P2pIface::startWpsPbcInternal, _hidl_cb, group_ifname, bssid);
    703 }
    704 
    705 Return<void> P2pIface::startWpsPinKeypad(
    706     const hidl_string& group_ifname, const hidl_string& pin,
    707     startWpsPinKeypad_cb _hidl_cb)
    708 {
    709 	return validateAndCall(
    710 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    711 	    &P2pIface::startWpsPinKeypadInternal, _hidl_cb, group_ifname, pin);
    712 }
    713 
    714 Return<void> P2pIface::startWpsPinDisplay(
    715     const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
    716     startWpsPinDisplay_cb _hidl_cb)
    717 {
    718 	return validateAndCall(
    719 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    720 	    &P2pIface::startWpsPinDisplayInternal, _hidl_cb, group_ifname,
    721 	    bssid);
    722 }
    723 
    724 Return<void> P2pIface::cancelWps(
    725     const hidl_string& group_ifname, cancelWps_cb _hidl_cb)
    726 {
    727 	return validateAndCall(
    728 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    729 	    &P2pIface::cancelWpsInternal, _hidl_cb, group_ifname);
    730 }
    731 
    732 Return<void> P2pIface::setWpsDeviceName(
    733     const hidl_string& name, setWpsDeviceName_cb _hidl_cb)
    734 {
    735 	return validateAndCall(
    736 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    737 	    &P2pIface::setWpsDeviceNameInternal, _hidl_cb, name);
    738 }
    739 
    740 Return<void> P2pIface::setWpsDeviceType(
    741     const hidl_array<uint8_t, 8>& type, setWpsDeviceType_cb _hidl_cb)
    742 {
    743 	return validateAndCall(
    744 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    745 	    &P2pIface::setWpsDeviceTypeInternal, _hidl_cb, type);
    746 }
    747 
    748 Return<void> P2pIface::setWpsManufacturer(
    749     const hidl_string& manufacturer, setWpsManufacturer_cb _hidl_cb)
    750 {
    751 	return validateAndCall(
    752 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    753 	    &P2pIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
    754 }
    755 
    756 Return<void> P2pIface::setWpsModelName(
    757     const hidl_string& model_name, setWpsModelName_cb _hidl_cb)
    758 {
    759 	return validateAndCall(
    760 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    761 	    &P2pIface::setWpsModelNameInternal, _hidl_cb, model_name);
    762 }
    763 
    764 Return<void> P2pIface::setWpsModelNumber(
    765     const hidl_string& model_number, setWpsModelNumber_cb _hidl_cb)
    766 {
    767 	return validateAndCall(
    768 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    769 	    &P2pIface::setWpsModelNumberInternal, _hidl_cb, model_number);
    770 }
    771 
    772 Return<void> P2pIface::setWpsSerialNumber(
    773     const hidl_string& serial_number, setWpsSerialNumber_cb _hidl_cb)
    774 {
    775 	return validateAndCall(
    776 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    777 	    &P2pIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
    778 }
    779 
    780 Return<void> P2pIface::setWpsConfigMethods(
    781     uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
    782 {
    783 	return validateAndCall(
    784 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    785 	    &P2pIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
    786 }
    787 
    788 Return<void> P2pIface::enableWfd(bool enable, enableWfd_cb _hidl_cb)
    789 {
    790 	return validateAndCall(
    791 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    792 	    &P2pIface::enableWfdInternal, _hidl_cb, enable);
    793 }
    794 
    795 Return<void> P2pIface::setWfdDeviceInfo(
    796     const hidl_array<uint8_t, 6>& info, setWfdDeviceInfo_cb _hidl_cb)
    797 {
    798 	return validateAndCall(
    799 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    800 	    &P2pIface::setWfdDeviceInfoInternal, _hidl_cb, info);
    801 }
    802 
    803 Return<void> P2pIface::createNfcHandoverRequestMessage(
    804     createNfcHandoverRequestMessage_cb _hidl_cb)
    805 {
    806 	return validateAndCall(
    807 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    808 	    &P2pIface::createNfcHandoverRequestMessageInternal, _hidl_cb);
    809 }
    810 
    811 Return<void> P2pIface::createNfcHandoverSelectMessage(
    812     createNfcHandoverSelectMessage_cb _hidl_cb)
    813 {
    814 	return validateAndCall(
    815 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    816 	    &P2pIface::createNfcHandoverSelectMessageInternal, _hidl_cb);
    817 }
    818 
    819 Return<void> P2pIface::reportNfcHandoverResponse(
    820     const hidl_vec<uint8_t>& request, reportNfcHandoverResponse_cb _hidl_cb)
    821 {
    822 	return validateAndCall(
    823 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    824 	    &P2pIface::reportNfcHandoverResponseInternal, _hidl_cb, request);
    825 }
    826 
    827 Return<void> P2pIface::reportNfcHandoverInitiation(
    828     const hidl_vec<uint8_t>& select, reportNfcHandoverInitiation_cb _hidl_cb)
    829 {
    830 	return validateAndCall(
    831 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    832 	    &P2pIface::reportNfcHandoverInitiationInternal, _hidl_cb, select);
    833 }
    834 
    835 Return<void> P2pIface::saveConfig(saveConfig_cb _hidl_cb)
    836 {
    837 	return validateAndCall(
    838 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    839 	    &P2pIface::saveConfigInternal, _hidl_cb);
    840 }
    841 
    842 Return<void> P2pIface::addGroup_1_2(
    843     const hidl_vec<uint8_t>& ssid, const hidl_string& passphrase,
    844     bool persistent, uint32_t freq, const hidl_array<uint8_t, 6>& peer_address,
    845     bool join, addGroup_cb _hidl_cb)
    846 {
    847 	return validateAndCall(
    848 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    849 	    &P2pIface::addGroup_1_2Internal, _hidl_cb,
    850 	    ssid, passphrase, persistent, freq, peer_address, join);
    851 }
    852 
    853 Return<void> P2pIface::setMacRandomization(bool enable, setMacRandomization_cb _hidl_cb)
    854 {
    855 	return validateAndCall(
    856 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    857 	    &P2pIface::setMacRandomizationInternal, _hidl_cb, enable);
    858 }
    859 
    860 std::pair<SupplicantStatus, std::string> P2pIface::getNameInternal()
    861 {
    862 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
    863 }
    864 
    865 std::pair<SupplicantStatus, IfaceType> P2pIface::getTypeInternal()
    866 {
    867 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
    868 }
    869 
    870 std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
    871 P2pIface::addNetworkInternal()
    872 {
    873 	android::sp<ISupplicantP2pNetwork> network;
    874 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    875 	struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
    876 	if (!ssid) {
    877 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    878 	}
    879 	HidlManager* hidl_manager = HidlManager::getInstance();
    880 	if (!hidl_manager ||
    881 	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
    882 		wpa_s->ifname, ssid->id, &network)) {
    883 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    884 	}
    885 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
    886 }
    887 
    888 SupplicantStatus P2pIface::removeNetworkInternal(SupplicantNetworkId id)
    889 {
    890 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    891 	int result = wpa_supplicant_remove_network(wpa_s, id);
    892 	if (result == -1) {
    893 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
    894 	}
    895 	if (result != 0) {
    896 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    897 	}
    898 	return {SupplicantStatusCode::SUCCESS, ""};
    899 }
    900 
    901 std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
    902 P2pIface::getNetworkInternal(SupplicantNetworkId id)
    903 {
    904 	android::sp<ISupplicantP2pNetwork> network;
    905 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    906 	struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
    907 	if (!ssid) {
    908 		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
    909 			network};
    910 	}
    911 	HidlManager* hidl_manager = HidlManager::getInstance();
    912 	if (!hidl_manager ||
    913 	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
    914 		wpa_s->ifname, ssid->id, &network)) {
    915 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    916 	}
    917 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
    918 }
    919 
    920 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
    921 P2pIface::listNetworksInternal()
    922 {
    923 	std::vector<SupplicantNetworkId> network_ids;
    924 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    925 	for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
    926 	     wpa_ssid = wpa_ssid->next) {
    927 		network_ids.emplace_back(wpa_ssid->id);
    928 	}
    929 	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
    930 }
    931 
    932 SupplicantStatus P2pIface::registerCallbackInternal(
    933     const sp<ISupplicantP2pIfaceCallback>& callback)
    934 {
    935 	HidlManager* hidl_manager = HidlManager::getInstance();
    936 	if (!hidl_manager ||
    937 	    hidl_manager->addP2pIfaceCallbackHidlObject(ifname_, callback)) {
    938 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    939 	}
    940 	return {SupplicantStatusCode::SUCCESS, ""};
    941 }
    942 
    943 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
    944 P2pIface::getDeviceAddressInternal()
    945 {
    946 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    947 	std::array<uint8_t, 6> addr;
    948 	static_assert(ETH_ALEN == addr.size(), "Size mismatch");
    949 	os_memcpy(addr.data(), wpa_s->global->p2p_dev_addr, ETH_ALEN);
    950 	return {{SupplicantStatusCode::SUCCESS, ""}, addr};
    951 }
    952 
    953 SupplicantStatus P2pIface::setSsidPostfixInternal(
    954     const std::vector<uint8_t>& postfix)
    955 {
    956 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    957 	if (p2p_set_ssid_postfix(
    958 		wpa_s->global->p2p, postfix.data(), postfix.size())) {
    959 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    960 	}
    961 	return {SupplicantStatusCode::SUCCESS, ""};
    962 }
    963 
    964 SupplicantStatus P2pIface::setGroupIdleInternal(
    965     const std::string& group_ifname, uint32_t timeout_in_sec)
    966 {
    967 	struct wpa_supplicant* wpa_group_s =
    968 	    retrieveGroupIfacePtr(group_ifname);
    969 	if (!wpa_group_s) {
    970 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
    971 	}
    972 	wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
    973 	return {SupplicantStatusCode::SUCCESS, ""};
    974 }
    975 
    976 SupplicantStatus P2pIface::setPowerSaveInternal(
    977     const std::string& group_ifname, bool enable)
    978 {
    979 	struct wpa_supplicant* wpa_group_s =
    980 	    retrieveGroupIfacePtr(group_ifname);
    981 	if (!wpa_group_s) {
    982 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
    983 	}
    984 	if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
    985 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    986 	}
    987 	return {SupplicantStatusCode::SUCCESS, ""};
    988 }
    989 
    990 SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
    991 {
    992 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
    993 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    994 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
    995 	}
    996 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
    997 	if (wpas_p2p_find(
    998 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
    999 		nullptr, search_delay, 0, nullptr, 0)) {
   1000 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1001 	}
   1002 	return {SupplicantStatusCode::SUCCESS, ""};
   1003 }
   1004 
   1005 SupplicantStatus P2pIface::stopFindInternal()
   1006 {
   1007 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1008 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
   1009 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
   1010 	}
   1011 	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
   1012 		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
   1013 		pending_scan_res_join_callback = NULL;
   1014 		wpa_s->scan_res_handler = scanResJoinIgnore;
   1015 	}
   1016 	wpas_p2p_stop_find(wpa_s);
   1017 	return {SupplicantStatusCode::SUCCESS, ""};
   1018 }
   1019 
   1020 SupplicantStatus P2pIface::flushInternal()
   1021 {
   1022 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1023 	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
   1024 	wpa_s->force_long_sd = 0;
   1025 	wpas_p2p_stop_find(wpa_s);
   1026 	wpa_s->parent->p2ps_method_config_any = 0;
   1027 	if (wpa_s->global->p2p)
   1028 		p2p_flush(wpa_s->global->p2p);
   1029 	return {SupplicantStatusCode::SUCCESS, ""};
   1030 }
   1031 
   1032 // This method only implements support for subset (needed by Android framework)
   1033 // of parameters that can be specified for connect.
   1034 std::pair<SupplicantStatus, std::string> P2pIface::connectInternal(
   1035     const std::array<uint8_t, 6>& peer_address,
   1036     ISupplicantP2pIface::WpsProvisionMethod provision_method,
   1037     const std::string& pre_selected_pin, bool join_existing_group,
   1038     bool persistent, uint32_t go_intent)
   1039 {
   1040 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1041 	if (go_intent > 15) {
   1042 		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
   1043 	}
   1044 	int go_intent_signed = join_existing_group ? -1 : go_intent;
   1045 	p2p_wps_method wps_method = {};
   1046 	switch (provision_method) {
   1047 	case WpsProvisionMethod::PBC:
   1048 		wps_method = WPS_PBC;
   1049 		break;
   1050 	case WpsProvisionMethod::DISPLAY:
   1051 		wps_method = WPS_PIN_DISPLAY;
   1052 		break;
   1053 	case WpsProvisionMethod::KEYPAD:
   1054 		wps_method = WPS_PIN_KEYPAD;
   1055 		break;
   1056 	}
   1057 	int vht = wpa_s->conf->p2p_go_vht;
   1058 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
   1059 	const char* pin =
   1060 	    pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
   1061 	int new_pin = wpas_p2p_connect(
   1062 	    wpa_s, peer_address.data(), pin, wps_method, persistent, false,
   1063 	    join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
   1064 	    vht, VHT_CHANWIDTH_USE_HT, 0, nullptr, 0);
   1065 	if (new_pin < 0) {
   1066 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1067 	}
   1068 	std::string pin_ret;
   1069 	if (provision_method == WpsProvisionMethod::DISPLAY &&
   1070 	    pre_selected_pin.empty()) {
   1071 		pin_ret = misc_utils::convertWpsPinToString(new_pin);
   1072 	}
   1073 	return {{SupplicantStatusCode::SUCCESS, ""}, pin_ret};
   1074 }
   1075 
   1076 SupplicantStatus P2pIface::cancelConnectInternal()
   1077 {
   1078 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1079 	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
   1080 		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
   1081 		pending_scan_res_join_callback = NULL;
   1082 		wpa_s->scan_res_handler = scanResJoinIgnore;
   1083 	}
   1084 	if (wpas_p2p_cancel(wpa_s)) {
   1085 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1086 	}
   1087 	return {SupplicantStatusCode::SUCCESS, ""};
   1088 }
   1089 
   1090 SupplicantStatus P2pIface::provisionDiscoveryInternal(
   1091     const std::array<uint8_t, 6>& peer_address,
   1092     ISupplicantP2pIface::WpsProvisionMethod provision_method)
   1093 {
   1094 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1095 	p2ps_provision* prov_param;
   1096 	const char* config_method_str = nullptr;
   1097 	switch (provision_method) {
   1098 	case WpsProvisionMethod::PBC:
   1099 		config_method_str = kConfigMethodStrPbc;
   1100 		break;
   1101 	case WpsProvisionMethod::DISPLAY:
   1102 		config_method_str = kConfigMethodStrDisplay;
   1103 		break;
   1104 	case WpsProvisionMethod::KEYPAD:
   1105 		config_method_str = kConfigMethodStrKeypad;
   1106 		break;
   1107 	}
   1108 	if (wpas_p2p_prov_disc(
   1109 		wpa_s, peer_address.data(), config_method_str,
   1110 		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
   1111 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1112 	}
   1113 	return {SupplicantStatusCode::SUCCESS, ""};
   1114 }
   1115 
   1116 SupplicantStatus P2pIface::addGroupInternal(
   1117     bool persistent, SupplicantNetworkId persistent_network_id)
   1118 {
   1119 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1120 	int vht = wpa_s->conf->p2p_go_vht;
   1121 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
   1122 	struct wpa_ssid* ssid =
   1123 	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
   1124 	if (ssid == NULL) {
   1125 		if (wpas_p2p_group_add(
   1126 			wpa_s, persistent, 0, 0, ht40, vht,
   1127 			VHT_CHANWIDTH_USE_HT, 0)) {
   1128 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1129 		} else {
   1130 			return {SupplicantStatusCode::SUCCESS, ""};
   1131 		}
   1132 	} else if (ssid->disabled == 2) {
   1133 		if (wpas_p2p_group_add_persistent(
   1134 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
   1135 			VHT_CHANWIDTH_USE_HT, 0, NULL, 0, 0)) {
   1136 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
   1137 				""};
   1138 		} else {
   1139 			return {SupplicantStatusCode::SUCCESS, ""};
   1140 		}
   1141 	}
   1142 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1143 }
   1144 
   1145 SupplicantStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
   1146 {
   1147 	struct wpa_supplicant* wpa_group_s =
   1148 	    retrieveGroupIfacePtr(group_ifname);
   1149 	if (!wpa_group_s) {
   1150 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
   1151 	}
   1152 	if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
   1153 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1154 	}
   1155 	return {SupplicantStatusCode::SUCCESS, ""};
   1156 }
   1157 
   1158 SupplicantStatus P2pIface::rejectInternal(
   1159     const std::array<uint8_t, 6>& peer_address)
   1160 {
   1161 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1162 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
   1163 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
   1164 	}
   1165 	if (wpas_p2p_reject(wpa_s, peer_address.data())) {
   1166 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1167 	}
   1168 	return {SupplicantStatusCode::SUCCESS, ""};
   1169 }
   1170 
   1171 SupplicantStatus P2pIface::inviteInternal(
   1172     const std::string& group_ifname,
   1173     const std::array<uint8_t, 6>& go_device_address,
   1174     const std::array<uint8_t, 6>& peer_address)
   1175 {
   1176 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1177 	if (wpas_p2p_invite_group(
   1178 		wpa_s, group_ifname.c_str(), peer_address.data(),
   1179 		go_device_address.data())) {
   1180 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1181 	}
   1182 	return {SupplicantStatusCode::SUCCESS, ""};
   1183 }
   1184 
   1185 SupplicantStatus P2pIface::reinvokeInternal(
   1186     SupplicantNetworkId persistent_network_id,
   1187     const std::array<uint8_t, 6>& peer_address)
   1188 {
   1189 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1190 	int vht = wpa_s->conf->p2p_go_vht;
   1191 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
   1192 	struct wpa_ssid* ssid =
   1193 	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
   1194 	if (ssid == NULL || ssid->disabled != 2) {
   1195 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
   1196 	}
   1197 	if (wpas_p2p_invite(
   1198 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
   1199 		VHT_CHANWIDTH_USE_HT, 0, 0)) {
   1200 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1201 	}
   1202 	return {SupplicantStatusCode::SUCCESS, ""};
   1203 }
   1204 
   1205 SupplicantStatus P2pIface::configureExtListenInternal(
   1206     uint32_t period_in_millis, uint32_t interval_in_millis)
   1207 {
   1208 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1209 	if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
   1210 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1211 	}
   1212 	return {SupplicantStatusCode::SUCCESS, ""};
   1213 }
   1214 
   1215 SupplicantStatus P2pIface::setListenChannelInternal(
   1216     uint32_t channel, uint32_t operating_class)
   1217 {
   1218 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1219 	if (p2p_set_listen_channel(
   1220 		wpa_s->global->p2p, operating_class, channel, 1)) {
   1221 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1222 	}
   1223 	return {SupplicantStatusCode::SUCCESS, ""};
   1224 }
   1225 
   1226 SupplicantStatus P2pIface::setDisallowedFrequenciesInternal(
   1227     const std::vector<FreqRange>& ranges)
   1228 {
   1229 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1230 	using DestT = struct wpa_freq_range_list::wpa_freq_range;
   1231 	DestT* freq_ranges = nullptr;
   1232 	// Empty ranges is used to enable all frequencies.
   1233 	if (ranges.size() != 0) {
   1234 		freq_ranges = static_cast<DestT*>(
   1235 		    os_malloc(sizeof(DestT) * ranges.size()));
   1236 		if (!freq_ranges) {
   1237 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1238 		}
   1239 		uint32_t i = 0;
   1240 		for (const auto& range : ranges) {
   1241 			freq_ranges[i].min = range.min;
   1242 			freq_ranges[i].max = range.max;
   1243 			i++;
   1244 		}
   1245 	}
   1246 
   1247 	os_free(wpa_s->global->p2p_disallow_freq.range);
   1248 	wpa_s->global->p2p_disallow_freq.range = freq_ranges;
   1249 	wpa_s->global->p2p_disallow_freq.num = ranges.size();
   1250 	wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
   1251 	return {SupplicantStatusCode::SUCCESS, ""};
   1252 }
   1253 
   1254 std::pair<SupplicantStatus, std::vector<uint8_t>> P2pIface::getSsidInternal(
   1255     const std::array<uint8_t, 6>& peer_address)
   1256 {
   1257 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1258 	const struct p2p_peer_info* info =
   1259 	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
   1260 	if (!info) {
   1261 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1262 	}
   1263 	const struct p2p_device* dev =
   1264 	    reinterpret_cast<const struct p2p_device*>(
   1265 		(reinterpret_cast<const uint8_t*>(info)) -
   1266 		offsetof(struct p2p_device, info));
   1267 	std::vector<uint8_t> ssid;
   1268 	if (dev && dev->oper_ssid_len) {
   1269 		ssid.assign(
   1270 		    dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
   1271 	}
   1272 	return {{SupplicantStatusCode::SUCCESS, ""}, ssid};
   1273 }
   1274 
   1275 std::pair<SupplicantStatus, uint32_t> P2pIface::getGroupCapabilityInternal(
   1276     const std::array<uint8_t, 6>& peer_address)
   1277 {
   1278 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1279 	const struct p2p_peer_info* info =
   1280 	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
   1281 	if (!info) {
   1282 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1283 	}
   1284 	return {{SupplicantStatusCode::SUCCESS, ""}, info->group_capab};
   1285 }
   1286 
   1287 SupplicantStatus P2pIface::addBonjourServiceInternal(
   1288     const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
   1289 {
   1290 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1291 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
   1292 	auto response_buf = misc_utils::convertVectorToWpaBuf(response);
   1293 	if (!query_buf || !response_buf) {
   1294 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1295 	}
   1296 	if (wpas_p2p_service_add_bonjour(
   1297 		wpa_s, query_buf.get(), response_buf.get())) {
   1298 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1299 	}
   1300 	// If successful, the wpabuf is referenced internally and hence should
   1301 	// not be freed.
   1302 	query_buf.release();
   1303 	response_buf.release();
   1304 	return {SupplicantStatusCode::SUCCESS, ""};
   1305 }
   1306 
   1307 SupplicantStatus P2pIface::removeBonjourServiceInternal(
   1308     const std::vector<uint8_t>& query)
   1309 {
   1310 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1311 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
   1312 	if (!query_buf) {
   1313 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1314 	}
   1315 	if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
   1316 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1317 	}
   1318 	return {SupplicantStatusCode::SUCCESS, ""};
   1319 }
   1320 
   1321 SupplicantStatus P2pIface::addUpnpServiceInternal(
   1322     uint32_t version, const std::string& service_name)
   1323 {
   1324 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1325 	if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
   1326 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1327 	}
   1328 	return {SupplicantStatusCode::SUCCESS, ""};
   1329 }
   1330 
   1331 SupplicantStatus P2pIface::removeUpnpServiceInternal(
   1332     uint32_t version, const std::string& service_name)
   1333 {
   1334 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1335 	if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
   1336 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1337 	}
   1338 	return {SupplicantStatusCode::SUCCESS, ""};
   1339 }
   1340 
   1341 SupplicantStatus P2pIface::flushServicesInternal()
   1342 {
   1343 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1344 	wpas_p2p_service_flush(wpa_s);
   1345 	return {SupplicantStatusCode::SUCCESS, ""};
   1346 }
   1347 
   1348 std::pair<SupplicantStatus, uint64_t> P2pIface::requestServiceDiscoveryInternal(
   1349     const std::array<uint8_t, 6>& peer_address,
   1350     const std::vector<uint8_t>& query)
   1351 {
   1352 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1353 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
   1354 	if (!query_buf) {
   1355 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1356 	}
   1357 	const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
   1358 				      ? nullptr
   1359 				      : peer_address.data();
   1360 	uint64_t identifier =
   1361 	    wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
   1362 	if (identifier == 0) {
   1363 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1364 	}
   1365 	return {{SupplicantStatusCode::SUCCESS, ""}, identifier};
   1366 }
   1367 
   1368 SupplicantStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
   1369 {
   1370 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1371 	if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
   1372 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1373 	}
   1374 	return {SupplicantStatusCode::SUCCESS, ""};
   1375 }
   1376 
   1377 SupplicantStatus P2pIface::setMiracastModeInternal(
   1378     ISupplicantP2pIface::MiracastMode mode)
   1379 {
   1380 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1381 	uint8_t mode_internal = convertHidlMiracastModeToInternal(mode);
   1382 	const std::string cmd_str =
   1383 	    kSetMiracastMode + std::to_string(mode_internal);
   1384 	std::vector<char> cmd(
   1385 	    cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
   1386 	char driver_cmd_reply_buf[4096] = {};
   1387 	if (wpa_drv_driver_cmd(
   1388 		wpa_s, cmd.data(), driver_cmd_reply_buf,
   1389 		sizeof(driver_cmd_reply_buf))) {
   1390 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1391 	}
   1392 	return {SupplicantStatusCode::SUCCESS, ""};
   1393 }
   1394 
   1395 SupplicantStatus P2pIface::startWpsPbcInternal(
   1396     const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
   1397 {
   1398 	struct wpa_supplicant* wpa_group_s =
   1399 	    retrieveGroupIfacePtr(group_ifname);
   1400 	if (!wpa_group_s) {
   1401 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
   1402 	}
   1403 	const uint8_t* bssid_addr =
   1404 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
   1405 #ifdef CONFIG_AP
   1406 	if (wpa_group_s->ap_iface) {
   1407 		if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
   1408 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1409 		}
   1410 		return {SupplicantStatusCode::SUCCESS, ""};
   1411 	}
   1412 #endif /* CONFIG_AP */
   1413 	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
   1414 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1415 	}
   1416 	return {SupplicantStatusCode::SUCCESS, ""};
   1417 }
   1418 
   1419 SupplicantStatus P2pIface::startWpsPinKeypadInternal(
   1420     const std::string& group_ifname, const std::string& pin)
   1421 {
   1422 	struct wpa_supplicant* wpa_group_s =
   1423 	    retrieveGroupIfacePtr(group_ifname);
   1424 	if (!wpa_group_s) {
   1425 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
   1426 	}
   1427 #ifdef CONFIG_AP
   1428 	if (wpa_group_s->ap_iface) {
   1429 		if (wpa_supplicant_ap_wps_pin(
   1430 			wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
   1431 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1432 		}
   1433 		return {SupplicantStatusCode::SUCCESS, ""};
   1434 	}
   1435 #endif /* CONFIG_AP */
   1436 	if (wpas_wps_start_pin(
   1437 		wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
   1438 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1439 	}
   1440 	return {SupplicantStatusCode::SUCCESS, ""};
   1441 }
   1442 
   1443 std::pair<SupplicantStatus, std::string> P2pIface::startWpsPinDisplayInternal(
   1444     const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
   1445 {
   1446 	struct wpa_supplicant* wpa_group_s =
   1447 	    retrieveGroupIfacePtr(group_ifname);
   1448 	if (!wpa_group_s) {
   1449 		return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""}, ""};
   1450 	}
   1451 	const uint8_t* bssid_addr =
   1452 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
   1453 	int pin = wpas_wps_start_pin(
   1454 	    wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
   1455 	if (pin < 0) {
   1456 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
   1457 	}
   1458 	return {{SupplicantStatusCode::SUCCESS, ""},
   1459 		misc_utils::convertWpsPinToString(pin)};
   1460 }
   1461 
   1462 SupplicantStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
   1463 {
   1464 	struct wpa_supplicant* wpa_group_s =
   1465 	    retrieveGroupIfacePtr(group_ifname);
   1466 	if (!wpa_group_s) {
   1467 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
   1468 	}
   1469 	if (wpas_wps_cancel(wpa_group_s)) {
   1470 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1471 	}
   1472 	return {SupplicantStatusCode::SUCCESS, ""};
   1473 }
   1474 
   1475 SupplicantStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
   1476 {
   1477 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
   1478 }
   1479 
   1480 SupplicantStatus P2pIface::setWpsDeviceTypeInternal(
   1481     const std::array<uint8_t, 8>& type)
   1482 {
   1483 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
   1484 }
   1485 
   1486 SupplicantStatus P2pIface::setWpsManufacturerInternal(
   1487     const std::string& manufacturer)
   1488 {
   1489 	return iface_config_utils::setWpsManufacturer(
   1490 	    retrieveIfacePtr(), manufacturer);
   1491 }
   1492 
   1493 SupplicantStatus P2pIface::setWpsModelNameInternal(
   1494     const std::string& model_name)
   1495 {
   1496 	return iface_config_utils::setWpsModelName(
   1497 	    retrieveIfacePtr(), model_name);
   1498 }
   1499 
   1500 SupplicantStatus P2pIface::setWpsModelNumberInternal(
   1501     const std::string& model_number)
   1502 {
   1503 	return iface_config_utils::setWpsModelNumber(
   1504 	    retrieveIfacePtr(), model_number);
   1505 }
   1506 
   1507 SupplicantStatus P2pIface::setWpsSerialNumberInternal(
   1508     const std::string& serial_number)
   1509 {
   1510 	return iface_config_utils::setWpsSerialNumber(
   1511 	    retrieveIfacePtr(), serial_number);
   1512 }
   1513 
   1514 SupplicantStatus P2pIface::setWpsConfigMethodsInternal(uint16_t config_methods)
   1515 {
   1516 	return iface_config_utils::setWpsConfigMethods(
   1517 	    retrieveIfacePtr(), config_methods);
   1518 }
   1519 
   1520 SupplicantStatus P2pIface::enableWfdInternal(bool enable)
   1521 {
   1522 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1523 	wifi_display_enable(wpa_s->global, enable);
   1524 	return {SupplicantStatusCode::SUCCESS, ""};
   1525 }
   1526 
   1527 SupplicantStatus P2pIface::setWfdDeviceInfoInternal(
   1528     const std::array<uint8_t, 6>& info)
   1529 {
   1530 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1531 	std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
   1532 	wpa_snprintf_hex(
   1533 	    wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
   1534 	    info.size());
   1535 	// |wifi_display_subelem_set| expects the first 2 bytes
   1536 	// to hold the lenght of the subelement. In this case it's
   1537 	// fixed to 6, so prepend that.
   1538 	std::string wfd_device_info_set_cmd_str =
   1539 	    std::to_string(kWfdDeviceInfoSubelemId) + " " +
   1540 	    kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
   1541 	std::vector<char> wfd_device_info_set_cmd(
   1542 	    wfd_device_info_set_cmd_str.c_str(),
   1543 	    wfd_device_info_set_cmd_str.c_str() +
   1544 		wfd_device_info_set_cmd_str.size() + 1);
   1545 	if (wifi_display_subelem_set(
   1546 		wpa_s->global, wfd_device_info_set_cmd.data())) {
   1547 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1548 	}
   1549 	return {SupplicantStatusCode::SUCCESS, ""};
   1550 }
   1551 
   1552 std::pair<SupplicantStatus, std::vector<uint8_t>>
   1553 P2pIface::createNfcHandoverRequestMessageInternal()
   1554 {
   1555 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1556 	auto buf = misc_utils::createWpaBufUniquePtr(
   1557 	    wpas_p2p_nfc_handover_req(wpa_s, 1));
   1558 	if (!buf) {
   1559 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1560 	}
   1561 	return {{SupplicantStatusCode::SUCCESS, ""},
   1562 		misc_utils::convertWpaBufToVector(buf.get())};
   1563 }
   1564 
   1565 std::pair<SupplicantStatus, std::vector<uint8_t>>
   1566 P2pIface::createNfcHandoverSelectMessageInternal()
   1567 {
   1568 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1569 	auto buf = misc_utils::createWpaBufUniquePtr(
   1570 	    wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
   1571 	if (!buf) {
   1572 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
   1573 	}
   1574 	return {{SupplicantStatusCode::SUCCESS, ""},
   1575 		misc_utils::convertWpaBufToVector(buf.get())};
   1576 }
   1577 
   1578 SupplicantStatus P2pIface::reportNfcHandoverResponseInternal(
   1579     const std::vector<uint8_t>& request)
   1580 {
   1581 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1582 	auto req = misc_utils::convertVectorToWpaBuf(request);
   1583 	auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
   1584 	if (!req || !sel) {
   1585 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1586 	}
   1587 
   1588 	if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
   1589 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1590 	}
   1591 	return {SupplicantStatusCode::SUCCESS, ""};
   1592 }
   1593 
   1594 SupplicantStatus P2pIface::reportNfcHandoverInitiationInternal(
   1595     const std::vector<uint8_t>& select)
   1596 {
   1597 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1598 	auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
   1599 	auto sel = misc_utils::convertVectorToWpaBuf(select);
   1600 	if (!req || !sel) {
   1601 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1602 	}
   1603 
   1604 	if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
   1605 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1606 	}
   1607 	return {SupplicantStatusCode::SUCCESS, ""};
   1608 }
   1609 
   1610 SupplicantStatus P2pIface::saveConfigInternal()
   1611 {
   1612 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1613 	if (!wpa_s->conf->update_config) {
   1614 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1615 	}
   1616 	if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
   1617 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1618 	}
   1619 	return {SupplicantStatusCode::SUCCESS, ""};
   1620 }
   1621 
   1622 SupplicantStatus P2pIface::addGroup_1_2Internal(
   1623     const std::vector<uint8_t>& ssid, const std::string& passphrase,
   1624     bool persistent, uint32_t freq, const std::array<uint8_t, 6>& peer_address,
   1625     bool joinExistingGroup)
   1626 {
   1627 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1628 	int vht = wpa_s->conf->p2p_go_vht;
   1629 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
   1630 
   1631 	if (!isSsidValid(ssid)) {
   1632 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "SSID is invalid."};
   1633 	}
   1634 
   1635 	if (!isPskPassphraseValid(passphrase)) {
   1636 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "passphrase is invalid."};
   1637 	}
   1638 
   1639 	if (!joinExistingGroup) {
   1640 		if (wpa_s->global->p2p == NULL) {
   1641 			return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
   1642 		}
   1643 
   1644 		struct p2p_data *p2p = wpa_s->global->p2p;
   1645 		os_memcpy(p2p->ssid, ssid.data(), ssid.size());
   1646 		p2p->ssid_len = ssid.size();
   1647 		p2p->ssid_set = 1;
   1648 
   1649 		os_memset(p2p->passphrase, 0, sizeof(p2p->passphrase));
   1650 		os_memcpy(p2p->passphrase, passphrase.c_str(), passphrase.length());
   1651 		p2p->passphrase_set = 1;
   1652 
   1653 		if (wpas_p2p_group_add(
   1654 		    wpa_s, persistent, freq, 0, ht40, vht,
   1655 		    VHT_CHANWIDTH_USE_HT, 0)) {
   1656 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
   1657 		}
   1658 		return {SupplicantStatusCode::SUCCESS, ""};
   1659 	}
   1660 
   1661 	// The rest is for group join.
   1662 	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
   1663 	wpas_p2p_stop_find(wpa_s);
   1664 
   1665 	struct wpa_bss *bss = findBssBySsid(
   1666 	    wpa_s, peer_address.data(),
   1667 	    ssid.data(), ssid.size());
   1668 	if (bss != NULL) {
   1669 		wpa_printf(MSG_DEBUG, "P2P: Join group with Group Owner " MACSTR,
   1670 		    MAC2STR(bss->bssid));
   1671 		if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
   1672 			// no need to notify group join failure here,
   1673 			// it will be handled by wpas_p2p_group_add_persistent
   1674 			// called in joinGroup.
   1675 			return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to join a group."};
   1676 		}
   1677 		return {SupplicantStatusCode::SUCCESS, ""};
   1678 	}
   1679 
   1680 	wpa_printf(MSG_INFO, "No matched BSS exists, try to find it by scan");
   1681 
   1682 	if (pending_scan_res_join_callback != NULL) {
   1683 		wpa_printf(MSG_WARNING, "P2P: Renew scan result callback with new request.");
   1684 	}
   1685 
   1686 	pending_join_scan_callback =
   1687 	    [wpa_s, ssid, freq]() {
   1688 		int ret = joinScanReq(wpa_s, ssid, freq);
   1689 		// for BUSY case, the scan might be occupied by WiFi.
   1690 		// Do not give up immediately, but try again later.
   1691 		if (-EBUSY == ret) {
   1692 			// re-schedule this join scan and don't consume retry count.
   1693 			if (pending_scan_res_join_callback) {
   1694 				wpa_s->p2p_join_scan_count--;
   1695 				pending_scan_res_join_callback();
   1696 			}
   1697 		} else if (0 != ret) {
   1698 			notifyGroupJoinFailure(wpa_s);
   1699 			pending_scan_res_join_callback = NULL;
   1700 		}
   1701 	};
   1702 
   1703 	pending_scan_res_join_callback = [wpa_s, ssid, passphrase, peer_address, this]() {
   1704 		if (wpa_s->global->p2p_disabled) {
   1705 			return;
   1706 		}
   1707 
   1708 		wpa_printf(MSG_DEBUG, "P2P: Scan results received for join (reinvoke).");
   1709 
   1710 		struct wpa_bss *bss = findBssBySsid(
   1711 		    wpa_s, peer_address.data(), ssid.data(), ssid.size());
   1712 		if (bss) {
   1713 			if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
   1714 				wpa_printf(MSG_ERROR, "P2P: Failed to join a group.");
   1715 			}
   1716 			// no need to notify group join failure here,
   1717 			// it will be handled by wpas_p2p_group_add_persistent
   1718 			// called in joinGroup.
   1719 			pending_scan_res_join_callback = NULL;
   1720 			return;
   1721 		}
   1722 
   1723 		wpa_s->p2p_join_scan_count++;
   1724 		wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d.", wpa_s->p2p_join_scan_count);
   1725 		eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
   1726 		if (wpa_s->p2p_join_scan_count <= P2P_MAX_JOIN_SCAN_ATTEMPTS) {
   1727 			wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
   1728 			eloop_register_timeout(1, 0, joinScanWrapper, wpa_s, this);
   1729 			return;
   1730 		}
   1731 
   1732 		wpa_printf(MSG_ERROR, "P2P: Failed to find the group with "
   1733 		    "network name %s - stop join attempt",
   1734 		    ssid.data());
   1735 		notifyGroupJoinFailure(wpa_s);
   1736 		pending_scan_res_join_callback = NULL;
   1737 	};
   1738 
   1739 	wpa_s->p2p_join_scan_count = 0;
   1740 	pending_join_scan_callback();
   1741 	if (pending_scan_res_join_callback == NULL) {
   1742 		return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to start scan."};
   1743 	}
   1744 	return {SupplicantStatusCode::SUCCESS, ""};
   1745 }
   1746 
   1747 SupplicantStatus P2pIface::setMacRandomizationInternal(bool enable)
   1748 {
   1749 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
   1750 	bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
   1751 	u8 *addr = NULL;
   1752 
   1753 	// A dedicated p2p device is not managed by supplicant,
   1754 	// supplicant could not change its MAC address.
   1755 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) {
   1756 		wpa_printf(MSG_ERROR,
   1757 			"Dedicated P2P device don't support MAC randomization");
   1758 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "NotSupported"};
   1759 	}
   1760 
   1761 	// The same state, no change is needed.
   1762 	if (currentEnabledState == enable) {
   1763 		wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
   1764 		    (enable) ? "enabled" : "disabled");
   1765 		return {SupplicantStatusCode::SUCCESS, ""};
   1766 	}
   1767 
   1768 	if (enable) {
   1769 		wpa_s->conf->p2p_device_random_mac_addr = 1;
   1770 		wpa_s->conf->p2p_interface_random_mac_addr = 1;
   1771 
   1772 		// restore config if it failed to set up MAC address.
   1773 		if (wpas_p2p_mac_setup(wpa_s) < 0) {
   1774 			wpa_s->conf->p2p_device_random_mac_addr = 0;
   1775 			wpa_s->conf->p2p_interface_random_mac_addr = 0;
   1776 			return {SupplicantStatusCode::FAILURE_UNKNOWN,
   1777 			    "Failed to set up MAC address."};
   1778 		}
   1779 	} else {
   1780 		// disable random MAC will use original MAC address
   1781 		// regardless of any saved persistent groups.
   1782 		if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
   1783 			wpa_printf(MSG_ERROR, "Failed to restore MAC address");
   1784 			return {SupplicantStatusCode::FAILURE_UNKNOWN,
   1785 			    "Failed to restore MAC address."};
   1786 		}
   1787 
   1788 		if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
   1789 			wpa_printf(MSG_INFO, "Could not update MAC address information");
   1790 			return {SupplicantStatusCode::FAILURE_UNKNOWN,
   1791 			    "Failed to update MAC address."};
   1792 		}
   1793 		wpa_s->conf->p2p_device_random_mac_addr = 0;
   1794 		wpa_s->conf->p2p_interface_random_mac_addr = 0;
   1795 	}
   1796 
   1797 	// update internal data to send out correct device address in action frame.
   1798 	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
   1799 	os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
   1800 
   1801 	return {SupplicantStatusCode::SUCCESS, ""};
   1802 }
   1803 
   1804 /**
   1805  * Retrieve the underlying |wpa_supplicant| struct
   1806  * pointer for this iface.
   1807  * If the underlying iface is removed, then all RPC method calls on this object
   1808  * will return failure.
   1809  */
   1810 wpa_supplicant* P2pIface::retrieveIfacePtr()
   1811 {
   1812 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
   1813 }
   1814 
   1815 /**
   1816  * Retrieve the underlying |wpa_supplicant| struct
   1817  * pointer for this group iface.
   1818  */
   1819 wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
   1820 {
   1821 	return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
   1822 }
   1823 
   1824 }  // namespace implementation
   1825 }  // namespace V1_2
   1826 }  // namespace supplicant
   1827 }  // namespace wifi
   1828 }  // namespace hardware
   1829 }  // namespace android
   1830