• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hidl interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2004-2016, Roshan Pius <rpius@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;
convertHidlMiracastModeToInternal(ISupplicantP2pIface::MiracastMode mode)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  */
isSsidValid(const std::vector<uint8_t> & ssid)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  */
isPskPassphraseValid(const std::string & psk)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 
setBandScanFreqsList(struct wpa_supplicant * wpa_s,enum hostapd_hw_mode band,struct wpa_driver_scan_params * params)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  */
isAnyEtherAddr(const u8 * a)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  */
findBssBySsid(struct wpa_supplicant * wpa_s,const u8 * bssid,const u8 * ssid,size_t ssid_len)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 
addGroupClientNetwork(struct wpa_supplicant * wpa_s,uint8_t * group_owner_bssid,const std::vector<uint8_t> & ssid,const std::string & passphrase)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 
joinScanWrapper(void * eloop_ctx,void * timeout_ctx)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 
scanResJoinWrapper(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)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 
joinScanReq(struct wpa_supplicant * wpa_s,const std::vector<uint8_t> & ssid,int freq)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 
joinGroup(struct wpa_supplicant * wpa_s,uint8_t * group_owner_bssid,const std::vector<uint8_t> & ssid,const std::string & passphrase)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 
notifyGroupJoinFailure(struct wpa_supplicant * wpa_s)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 
scanResJoinIgnore(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)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 
P2pIface(struct wpa_global * wpa_global,const char ifname[])390 P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
391     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
392 {}
393 
invalidate()394 void P2pIface::invalidate() { is_valid_ = false; }
isValid()395 bool P2pIface::isValid()
396 {
397 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
398 }
getName(getName_cb _hidl_cb)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 
getType(getType_cb _hidl_cb)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 
addNetwork(addNetwork_cb _hidl_cb)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 
removeNetwork(SupplicantNetworkId id,removeNetwork_cb _hidl_cb)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 
getNetwork(SupplicantNetworkId id,getNetwork_cb _hidl_cb)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 
listNetworks(listNetworks_cb _hidl_cb)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 
registerCallback(const sp<ISupplicantP2pIfaceCallback> & callback,registerCallback_cb _hidl_cb)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 
getDeviceAddress(getDeviceAddress_cb _hidl_cb)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 
setSsidPostfix(const hidl_vec<uint8_t> & postfix,setSsidPostfix_cb _hidl_cb)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 
setGroupIdle(const hidl_string & group_ifname,uint32_t timeout_in_sec,setGroupIdle_cb _hidl_cb)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 
setPowerSave(const hidl_string & group_ifname,bool enable,setPowerSave_cb _hidl_cb)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 
find(uint32_t timeout_in_sec,find_cb _hidl_cb)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 
stopFind(stopFind_cb _hidl_cb)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 
flush(flush_cb _hidl_cb)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 
connect(const hidl_array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method,const hidl_string & pre_selected_pin,bool join_existing_group,bool persistent,uint32_t go_intent,connect_cb _hidl_cb)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 
cancelConnect(cancelConnect_cb _hidl_cb)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 
provisionDiscovery(const hidl_array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method,provisionDiscovery_cb _hidl_cb)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 
addGroup(bool persistent,SupplicantNetworkId persistent_network_id,addGroup_cb _hidl_cb)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 
removeGroup(const hidl_string & group_ifname,removeGroup_cb _hidl_cb)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 
reject(const hidl_array<uint8_t,6> & peer_address,reject_cb _hidl_cb)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 
invite(const hidl_string & group_ifname,const hidl_array<uint8_t,6> & go_device_address,const hidl_array<uint8_t,6> & peer_address,invite_cb _hidl_cb)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 
reinvoke(SupplicantNetworkId persistent_network_id,const hidl_array<uint8_t,6> & peer_address,reinvoke_cb _hidl_cb)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 
configureExtListen(uint32_t period_in_millis,uint32_t interval_in_millis,configureExtListen_cb _hidl_cb)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 
setListenChannel(uint32_t channel,uint32_t operating_class,setListenChannel_cb _hidl_cb)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 
setDisallowedFrequencies(const hidl_vec<FreqRange> & ranges,setDisallowedFrequencies_cb _hidl_cb)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 
getSsid(const hidl_array<uint8_t,6> & peer_address,getSsid_cb _hidl_cb)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 
getGroupCapability(const hidl_array<uint8_t,6> & peer_address,getGroupCapability_cb _hidl_cb)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 
addBonjourService(const hidl_vec<uint8_t> & query,const hidl_vec<uint8_t> & response,addBonjourService_cb _hidl_cb)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 
removeBonjourService(const hidl_vec<uint8_t> & query,removeBonjourService_cb _hidl_cb)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 
addUpnpService(uint32_t version,const hidl_string & service_name,addUpnpService_cb _hidl_cb)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 
removeUpnpService(uint32_t version,const hidl_string & service_name,removeUpnpService_cb _hidl_cb)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 
flushServices(flushServices_cb _hidl_cb)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 
requestServiceDiscovery(const hidl_array<uint8_t,6> & peer_address,const hidl_vec<uint8_t> & query,requestServiceDiscovery_cb _hidl_cb)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 
cancelServiceDiscovery(uint64_t identifier,cancelServiceDiscovery_cb _hidl_cb)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 
setMiracastMode(ISupplicantP2pIface::MiracastMode mode,setMiracastMode_cb _hidl_cb)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 
startWpsPbc(const hidl_string & group_ifname,const hidl_array<uint8_t,6> & bssid,startWpsPbc_cb _hidl_cb)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 
startWpsPinKeypad(const hidl_string & group_ifname,const hidl_string & pin,startWpsPinKeypad_cb _hidl_cb)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 
startWpsPinDisplay(const hidl_string & group_ifname,const hidl_array<uint8_t,6> & bssid,startWpsPinDisplay_cb _hidl_cb)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 
cancelWps(const hidl_string & group_ifname,cancelWps_cb _hidl_cb)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 
setWpsDeviceName(const hidl_string & name,setWpsDeviceName_cb _hidl_cb)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 
setWpsDeviceType(const hidl_array<uint8_t,8> & type,setWpsDeviceType_cb _hidl_cb)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 
setWpsManufacturer(const hidl_string & manufacturer,setWpsManufacturer_cb _hidl_cb)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 
setWpsModelName(const hidl_string & model_name,setWpsModelName_cb _hidl_cb)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 
setWpsModelNumber(const hidl_string & model_number,setWpsModelNumber_cb _hidl_cb)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 
setWpsSerialNumber(const hidl_string & serial_number,setWpsSerialNumber_cb _hidl_cb)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 
setWpsConfigMethods(uint16_t config_methods,setWpsConfigMethods_cb _hidl_cb)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 
enableWfd(bool enable,enableWfd_cb _hidl_cb)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 
setWfdDeviceInfo(const hidl_array<uint8_t,6> & info,setWfdDeviceInfo_cb _hidl_cb)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 
createNfcHandoverRequestMessage(createNfcHandoverRequestMessage_cb _hidl_cb)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 
createNfcHandoverSelectMessage(createNfcHandoverSelectMessage_cb _hidl_cb)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 
reportNfcHandoverResponse(const hidl_vec<uint8_t> & request,reportNfcHandoverResponse_cb _hidl_cb)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 
reportNfcHandoverInitiation(const hidl_vec<uint8_t> & select,reportNfcHandoverInitiation_cb _hidl_cb)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 
saveConfig(saveConfig_cb _hidl_cb)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 
addGroup_1_2(const hidl_vec<uint8_t> & ssid,const hidl_string & passphrase,bool persistent,uint32_t freq,const hidl_array<uint8_t,6> & peer_address,bool join,addGroup_cb _hidl_cb)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 
setMacRandomization(bool enable,setMacRandomization_cb _hidl_cb)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 
getNameInternal()860 std::pair<SupplicantStatus, std::string> P2pIface::getNameInternal()
861 {
862 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
863 }
864 
getTypeInternal()865 std::pair<SupplicantStatus, IfaceType> P2pIface::getTypeInternal()
866 {
867 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
868 }
869 
870 std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
addNetworkInternal()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 
removeNetworkInternal(SupplicantNetworkId id)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>>
getNetworkInternal(SupplicantNetworkId id)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>>
listNetworksInternal()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 
registerCallbackInternal(const sp<ISupplicantP2pIfaceCallback> & callback)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>>
getDeviceAddressInternal()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 
setSsidPostfixInternal(const std::vector<uint8_t> & postfix)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 
setGroupIdleInternal(const std::string & group_ifname,uint32_t timeout_in_sec)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 
setPowerSaveInternal(const std::string & group_ifname,bool enable)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 
findInternal(uint32_t timeout_in_sec)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 
stopFindInternal()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 
flushInternal()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.
connectInternal(const std::array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method,const std::string & pre_selected_pin,bool join_existing_group,bool persistent,uint32_t go_intent)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 
cancelConnectInternal()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 
provisionDiscoveryInternal(const std::array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method)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 
addGroupInternal(bool persistent,SupplicantNetworkId persistent_network_id)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 
removeGroupInternal(const std::string & group_ifname)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 
rejectInternal(const std::array<uint8_t,6> & peer_address)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 
inviteInternal(const std::string & group_ifname,const std::array<uint8_t,6> & go_device_address,const std::array<uint8_t,6> & peer_address)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 
reinvokeInternal(SupplicantNetworkId persistent_network_id,const std::array<uint8_t,6> & peer_address)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 
configureExtListenInternal(uint32_t period_in_millis,uint32_t interval_in_millis)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 
setListenChannelInternal(uint32_t channel,uint32_t operating_class)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 
setDisallowedFrequenciesInternal(const std::vector<FreqRange> & ranges)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 
getSsidInternal(const std::array<uint8_t,6> & peer_address)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 
getGroupCapabilityInternal(const std::array<uint8_t,6> & peer_address)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 
addBonjourServiceInternal(const std::vector<uint8_t> & query,const std::vector<uint8_t> & response)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 
removeBonjourServiceInternal(const std::vector<uint8_t> & query)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 
addUpnpServiceInternal(uint32_t version,const std::string & service_name)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 
removeUpnpServiceInternal(uint32_t version,const std::string & service_name)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 
flushServicesInternal()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 
requestServiceDiscoveryInternal(const std::array<uint8_t,6> & peer_address,const std::vector<uint8_t> & query)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 
cancelServiceDiscoveryInternal(uint64_t identifier)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 
setMiracastModeInternal(ISupplicantP2pIface::MiracastMode mode)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 
startWpsPbcInternal(const std::string & group_ifname,const std::array<uint8_t,6> & bssid)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 
startWpsPinKeypadInternal(const std::string & group_ifname,const std::string & pin)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 
startWpsPinDisplayInternal(const std::string & group_ifname,const std::array<uint8_t,6> & bssid)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 
cancelWpsInternal(const std::string & group_ifname)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 
setWpsDeviceNameInternal(const std::string & name)1475 SupplicantStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
1476 {
1477 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
1478 }
1479 
setWpsDeviceTypeInternal(const std::array<uint8_t,8> & type)1480 SupplicantStatus P2pIface::setWpsDeviceTypeInternal(
1481     const std::array<uint8_t, 8>& type)
1482 {
1483 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
1484 }
1485 
setWpsManufacturerInternal(const std::string & manufacturer)1486 SupplicantStatus P2pIface::setWpsManufacturerInternal(
1487     const std::string& manufacturer)
1488 {
1489 	return iface_config_utils::setWpsManufacturer(
1490 	    retrieveIfacePtr(), manufacturer);
1491 }
1492 
setWpsModelNameInternal(const std::string & model_name)1493 SupplicantStatus P2pIface::setWpsModelNameInternal(
1494     const std::string& model_name)
1495 {
1496 	return iface_config_utils::setWpsModelName(
1497 	    retrieveIfacePtr(), model_name);
1498 }
1499 
setWpsModelNumberInternal(const std::string & model_number)1500 SupplicantStatus P2pIface::setWpsModelNumberInternal(
1501     const std::string& model_number)
1502 {
1503 	return iface_config_utils::setWpsModelNumber(
1504 	    retrieveIfacePtr(), model_number);
1505 }
1506 
setWpsSerialNumberInternal(const std::string & serial_number)1507 SupplicantStatus P2pIface::setWpsSerialNumberInternal(
1508     const std::string& serial_number)
1509 {
1510 	return iface_config_utils::setWpsSerialNumber(
1511 	    retrieveIfacePtr(), serial_number);
1512 }
1513 
setWpsConfigMethodsInternal(uint16_t config_methods)1514 SupplicantStatus P2pIface::setWpsConfigMethodsInternal(uint16_t config_methods)
1515 {
1516 	return iface_config_utils::setWpsConfigMethods(
1517 	    retrieveIfacePtr(), config_methods);
1518 }
1519 
enableWfdInternal(bool enable)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 
setWfdDeviceInfoInternal(const std::array<uint8_t,6> & info)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>>
createNfcHandoverRequestMessageInternal()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>>
createNfcHandoverSelectMessageInternal()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 
reportNfcHandoverResponseInternal(const std::vector<uint8_t> & request)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 
reportNfcHandoverInitiationInternal(const std::vector<uint8_t> & select)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 
saveConfigInternal()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 
addGroup_1_2Internal(const std::vector<uint8_t> & ssid,const std::string & passphrase,bool persistent,uint32_t freq,const std::array<uint8_t,6> & peer_address,bool joinExistingGroup)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 
setMacRandomizationInternal(bool enable)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  */
retrieveIfacePtr()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  */
retrieveGroupIfacePtr(const std::string & group_ifname)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