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 
17 extern "C" {
18 #include "ap.h"
19 #include "wps_supplicant.h"
20 #include "wifi_display.h"
21 }
22 
23 namespace {
24 const char kConfigMethodStrPbc[] = "pbc";
25 const char kConfigMethodStrDisplay[] = "display";
26 const char kConfigMethodStrKeypad[] = "keypad";
27 constexpr char kSetMiracastMode[] = "MIRACAST ";
28 constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
29 constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
30 
31 using android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
convertHidlMiracastModeToInternal(ISupplicantP2pIface::MiracastMode mode)32 uint8_t convertHidlMiracastModeToInternal(
33     ISupplicantP2pIface::MiracastMode mode)
34 {
35 	switch (mode) {
36 	case ISupplicantP2pIface::MiracastMode::DISABLED:
37 		return 0;
38 	case ISupplicantP2pIface::MiracastMode::SOURCE:
39 		return 1;
40 	case ISupplicantP2pIface::MiracastMode::SINK:
41 		return 2;
42 	};
43 	WPA_ASSERT(false);
44 }
45 }  // namespace
46 
47 namespace android {
48 namespace hardware {
49 namespace wifi {
50 namespace supplicant {
51 namespace V1_1 {
52 namespace implementation {
53 using hidl_return_util::validateAndCall;
54 
P2pIface(struct wpa_global * wpa_global,const char ifname[])55 P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
56     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
57 {
58 }
59 
invalidate()60 void P2pIface::invalidate() { is_valid_ = false; }
isValid()61 bool P2pIface::isValid()
62 {
63 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
64 }
getName(getName_cb _hidl_cb)65 Return<void> P2pIface::getName(getName_cb _hidl_cb)
66 {
67 	return validateAndCall(
68 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
69 	    &P2pIface::getNameInternal, _hidl_cb);
70 }
71 
getType(getType_cb _hidl_cb)72 Return<void> P2pIface::getType(getType_cb _hidl_cb)
73 {
74 	return validateAndCall(
75 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
76 	    &P2pIface::getTypeInternal, _hidl_cb);
77 }
78 
addNetwork(addNetwork_cb _hidl_cb)79 Return<void> P2pIface::addNetwork(addNetwork_cb _hidl_cb)
80 {
81 	return validateAndCall(
82 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
83 	    &P2pIface::addNetworkInternal, _hidl_cb);
84 }
85 
removeNetwork(SupplicantNetworkId id,removeNetwork_cb _hidl_cb)86 Return<void> P2pIface::removeNetwork(
87     SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
88 {
89 	return validateAndCall(
90 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
91 	    &P2pIface::removeNetworkInternal, _hidl_cb, id);
92 }
93 
getNetwork(SupplicantNetworkId id,getNetwork_cb _hidl_cb)94 Return<void> P2pIface::getNetwork(
95     SupplicantNetworkId id, getNetwork_cb _hidl_cb)
96 {
97 	return validateAndCall(
98 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
99 	    &P2pIface::getNetworkInternal, _hidl_cb, id);
100 }
101 
listNetworks(listNetworks_cb _hidl_cb)102 Return<void> P2pIface::listNetworks(listNetworks_cb _hidl_cb)
103 {
104 	return validateAndCall(
105 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
106 	    &P2pIface::listNetworksInternal, _hidl_cb);
107 }
108 
registerCallback(const sp<ISupplicantP2pIfaceCallback> & callback,registerCallback_cb _hidl_cb)109 Return<void> P2pIface::registerCallback(
110     const sp<ISupplicantP2pIfaceCallback>& callback,
111     registerCallback_cb _hidl_cb)
112 {
113 	return validateAndCall(
114 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
115 	    &P2pIface::registerCallbackInternal, _hidl_cb, callback);
116 }
117 
getDeviceAddress(getDeviceAddress_cb _hidl_cb)118 Return<void> P2pIface::getDeviceAddress(getDeviceAddress_cb _hidl_cb)
119 {
120 	return validateAndCall(
121 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
122 	    &P2pIface::getDeviceAddressInternal, _hidl_cb);
123 }
124 
setSsidPostfix(const hidl_vec<uint8_t> & postfix,setSsidPostfix_cb _hidl_cb)125 Return<void> P2pIface::setSsidPostfix(
126     const hidl_vec<uint8_t>& postfix, setSsidPostfix_cb _hidl_cb)
127 {
128 	return validateAndCall(
129 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
130 	    &P2pIface::setSsidPostfixInternal, _hidl_cb, postfix);
131 }
132 
setGroupIdle(const hidl_string & group_ifname,uint32_t timeout_in_sec,setGroupIdle_cb _hidl_cb)133 Return<void> P2pIface::setGroupIdle(
134     const hidl_string& group_ifname, uint32_t timeout_in_sec,
135     setGroupIdle_cb _hidl_cb)
136 {
137 	return validateAndCall(
138 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
139 	    &P2pIface::setGroupIdleInternal, _hidl_cb, group_ifname,
140 	    timeout_in_sec);
141 }
142 
setPowerSave(const hidl_string & group_ifname,bool enable,setPowerSave_cb _hidl_cb)143 Return<void> P2pIface::setPowerSave(
144     const hidl_string& group_ifname, bool enable, setPowerSave_cb _hidl_cb)
145 {
146 	return validateAndCall(
147 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
148 	    &P2pIface::setPowerSaveInternal, _hidl_cb, group_ifname, enable);
149 }
150 
find(uint32_t timeout_in_sec,find_cb _hidl_cb)151 Return<void> P2pIface::find(uint32_t timeout_in_sec, find_cb _hidl_cb)
152 {
153 	return validateAndCall(
154 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
155 	    &P2pIface::findInternal, _hidl_cb, timeout_in_sec);
156 }
157 
stopFind(stopFind_cb _hidl_cb)158 Return<void> P2pIface::stopFind(stopFind_cb _hidl_cb)
159 {
160 	return validateAndCall(
161 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
162 	    &P2pIface::stopFindInternal, _hidl_cb);
163 }
164 
flush(flush_cb _hidl_cb)165 Return<void> P2pIface::flush(flush_cb _hidl_cb)
166 {
167 	return validateAndCall(
168 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
169 	    &P2pIface::flushInternal, _hidl_cb);
170 }
171 
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)172 Return<void> P2pIface::connect(
173     const hidl_array<uint8_t, 6>& peer_address,
174     ISupplicantP2pIface::WpsProvisionMethod provision_method,
175     const hidl_string& pre_selected_pin, bool join_existing_group,
176     bool persistent, uint32_t go_intent, connect_cb _hidl_cb)
177 {
178 	return validateAndCall(
179 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
180 	    &P2pIface::connectInternal, _hidl_cb, peer_address,
181 	    provision_method, pre_selected_pin, join_existing_group, persistent,
182 	    go_intent);
183 }
184 
cancelConnect(cancelConnect_cb _hidl_cb)185 Return<void> P2pIface::cancelConnect(cancelConnect_cb _hidl_cb)
186 {
187 	return validateAndCall(
188 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
189 	    &P2pIface::cancelConnectInternal, _hidl_cb);
190 }
191 
provisionDiscovery(const hidl_array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method,provisionDiscovery_cb _hidl_cb)192 Return<void> P2pIface::provisionDiscovery(
193     const hidl_array<uint8_t, 6>& peer_address,
194     ISupplicantP2pIface::WpsProvisionMethod provision_method,
195     provisionDiscovery_cb _hidl_cb)
196 {
197 	return validateAndCall(
198 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
199 	    &P2pIface::provisionDiscoveryInternal, _hidl_cb, peer_address,
200 	    provision_method);
201 }
202 
addGroup(bool persistent,SupplicantNetworkId persistent_network_id,addGroup_cb _hidl_cb)203 Return<void> P2pIface::addGroup(
204     bool persistent, SupplicantNetworkId persistent_network_id,
205     addGroup_cb _hidl_cb)
206 {
207 	return validateAndCall(
208 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
209 	    &P2pIface::addGroupInternal, _hidl_cb, persistent,
210 	    persistent_network_id);
211 }
212 
removeGroup(const hidl_string & group_ifname,removeGroup_cb _hidl_cb)213 Return<void> P2pIface::removeGroup(
214     const hidl_string& group_ifname, removeGroup_cb _hidl_cb)
215 {
216 	return validateAndCall(
217 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
218 	    &P2pIface::removeGroupInternal, _hidl_cb, group_ifname);
219 }
220 
reject(const hidl_array<uint8_t,6> & peer_address,reject_cb _hidl_cb)221 Return<void> P2pIface::reject(
222     const hidl_array<uint8_t, 6>& peer_address, reject_cb _hidl_cb)
223 {
224 	return validateAndCall(
225 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
226 	    &P2pIface::rejectInternal, _hidl_cb, peer_address);
227 }
228 
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)229 Return<void> P2pIface::invite(
230     const hidl_string& group_ifname,
231     const hidl_array<uint8_t, 6>& go_device_address,
232     const hidl_array<uint8_t, 6>& peer_address, invite_cb _hidl_cb)
233 {
234 	return validateAndCall(
235 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
236 	    &P2pIface::inviteInternal, _hidl_cb, group_ifname,
237 	    go_device_address, peer_address);
238 }
239 
reinvoke(SupplicantNetworkId persistent_network_id,const hidl_array<uint8_t,6> & peer_address,reinvoke_cb _hidl_cb)240 Return<void> P2pIface::reinvoke(
241     SupplicantNetworkId persistent_network_id,
242     const hidl_array<uint8_t, 6>& peer_address, reinvoke_cb _hidl_cb)
243 {
244 	return validateAndCall(
245 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
246 	    &P2pIface::reinvokeInternal, _hidl_cb, persistent_network_id,
247 	    peer_address);
248 }
249 
configureExtListen(uint32_t period_in_millis,uint32_t interval_in_millis,configureExtListen_cb _hidl_cb)250 Return<void> P2pIface::configureExtListen(
251     uint32_t period_in_millis, uint32_t interval_in_millis,
252     configureExtListen_cb _hidl_cb)
253 {
254 	return validateAndCall(
255 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
256 	    &P2pIface::configureExtListenInternal, _hidl_cb, period_in_millis,
257 	    interval_in_millis);
258 }
259 
setListenChannel(uint32_t channel,uint32_t operating_class,setListenChannel_cb _hidl_cb)260 Return<void> P2pIface::setListenChannel(
261     uint32_t channel, uint32_t operating_class, setListenChannel_cb _hidl_cb)
262 {
263 	return validateAndCall(
264 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
265 	    &P2pIface::setListenChannelInternal, _hidl_cb, channel,
266 	    operating_class);
267 }
268 
setDisallowedFrequencies(const hidl_vec<FreqRange> & ranges,setDisallowedFrequencies_cb _hidl_cb)269 Return<void> P2pIface::setDisallowedFrequencies(
270     const hidl_vec<FreqRange>& ranges, setDisallowedFrequencies_cb _hidl_cb)
271 {
272 	return validateAndCall(
273 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
274 	    &P2pIface::setDisallowedFrequenciesInternal, _hidl_cb, ranges);
275 }
276 
getSsid(const hidl_array<uint8_t,6> & peer_address,getSsid_cb _hidl_cb)277 Return<void> P2pIface::getSsid(
278     const hidl_array<uint8_t, 6>& peer_address, getSsid_cb _hidl_cb)
279 {
280 	return validateAndCall(
281 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
282 	    &P2pIface::getSsidInternal, _hidl_cb, peer_address);
283 }
284 
getGroupCapability(const hidl_array<uint8_t,6> & peer_address,getGroupCapability_cb _hidl_cb)285 Return<void> P2pIface::getGroupCapability(
286     const hidl_array<uint8_t, 6>& peer_address, getGroupCapability_cb _hidl_cb)
287 {
288 	return validateAndCall(
289 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
290 	    &P2pIface::getGroupCapabilityInternal, _hidl_cb, peer_address);
291 }
292 
addBonjourService(const hidl_vec<uint8_t> & query,const hidl_vec<uint8_t> & response,addBonjourService_cb _hidl_cb)293 Return<void> P2pIface::addBonjourService(
294     const hidl_vec<uint8_t>& query, const hidl_vec<uint8_t>& response,
295     addBonjourService_cb _hidl_cb)
296 {
297 	return validateAndCall(
298 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
299 	    &P2pIface::addBonjourServiceInternal, _hidl_cb, query, response);
300 }
301 
removeBonjourService(const hidl_vec<uint8_t> & query,removeBonjourService_cb _hidl_cb)302 Return<void> P2pIface::removeBonjourService(
303     const hidl_vec<uint8_t>& query, removeBonjourService_cb _hidl_cb)
304 {
305 	return validateAndCall(
306 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
307 	    &P2pIface::removeBonjourServiceInternal, _hidl_cb, query);
308 }
309 
addUpnpService(uint32_t version,const hidl_string & service_name,addUpnpService_cb _hidl_cb)310 Return<void> P2pIface::addUpnpService(
311     uint32_t version, const hidl_string& service_name,
312     addUpnpService_cb _hidl_cb)
313 {
314 	return validateAndCall(
315 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
316 	    &P2pIface::addUpnpServiceInternal, _hidl_cb, version, service_name);
317 }
318 
removeUpnpService(uint32_t version,const hidl_string & service_name,removeUpnpService_cb _hidl_cb)319 Return<void> P2pIface::removeUpnpService(
320     uint32_t version, const hidl_string& service_name,
321     removeUpnpService_cb _hidl_cb)
322 {
323 	return validateAndCall(
324 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
325 	    &P2pIface::removeUpnpServiceInternal, _hidl_cb, version,
326 	    service_name);
327 }
328 
flushServices(flushServices_cb _hidl_cb)329 Return<void> P2pIface::flushServices(flushServices_cb _hidl_cb)
330 {
331 	return validateAndCall(
332 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
333 	    &P2pIface::flushServicesInternal, _hidl_cb);
334 }
335 
requestServiceDiscovery(const hidl_array<uint8_t,6> & peer_address,const hidl_vec<uint8_t> & query,requestServiceDiscovery_cb _hidl_cb)336 Return<void> P2pIface::requestServiceDiscovery(
337     const hidl_array<uint8_t, 6>& peer_address, const hidl_vec<uint8_t>& query,
338     requestServiceDiscovery_cb _hidl_cb)
339 {
340 	return validateAndCall(
341 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
342 	    &P2pIface::requestServiceDiscoveryInternal, _hidl_cb, peer_address,
343 	    query);
344 }
345 
cancelServiceDiscovery(uint64_t identifier,cancelServiceDiscovery_cb _hidl_cb)346 Return<void> P2pIface::cancelServiceDiscovery(
347     uint64_t identifier, cancelServiceDiscovery_cb _hidl_cb)
348 {
349 	return validateAndCall(
350 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
351 	    &P2pIface::cancelServiceDiscoveryInternal, _hidl_cb, identifier);
352 }
353 
setMiracastMode(ISupplicantP2pIface::MiracastMode mode,setMiracastMode_cb _hidl_cb)354 Return<void> P2pIface::setMiracastMode(
355     ISupplicantP2pIface::MiracastMode mode, setMiracastMode_cb _hidl_cb)
356 {
357 	return validateAndCall(
358 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
359 	    &P2pIface::setMiracastModeInternal, _hidl_cb, mode);
360 }
361 
startWpsPbc(const hidl_string & group_ifname,const hidl_array<uint8_t,6> & bssid,startWpsPbc_cb _hidl_cb)362 Return<void> P2pIface::startWpsPbc(
363     const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
364     startWpsPbc_cb _hidl_cb)
365 {
366 	return validateAndCall(
367 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
368 	    &P2pIface::startWpsPbcInternal, _hidl_cb, group_ifname, bssid);
369 }
370 
startWpsPinKeypad(const hidl_string & group_ifname,const hidl_string & pin,startWpsPinKeypad_cb _hidl_cb)371 Return<void> P2pIface::startWpsPinKeypad(
372     const hidl_string& group_ifname, const hidl_string& pin,
373     startWpsPinKeypad_cb _hidl_cb)
374 {
375 	return validateAndCall(
376 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
377 	    &P2pIface::startWpsPinKeypadInternal, _hidl_cb, group_ifname, pin);
378 }
379 
startWpsPinDisplay(const hidl_string & group_ifname,const hidl_array<uint8_t,6> & bssid,startWpsPinDisplay_cb _hidl_cb)380 Return<void> P2pIface::startWpsPinDisplay(
381     const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
382     startWpsPinDisplay_cb _hidl_cb)
383 {
384 	return validateAndCall(
385 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
386 	    &P2pIface::startWpsPinDisplayInternal, _hidl_cb, group_ifname,
387 	    bssid);
388 }
389 
cancelWps(const hidl_string & group_ifname,cancelWps_cb _hidl_cb)390 Return<void> P2pIface::cancelWps(
391     const hidl_string& group_ifname, cancelWps_cb _hidl_cb)
392 {
393 	return validateAndCall(
394 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
395 	    &P2pIface::cancelWpsInternal, _hidl_cb, group_ifname);
396 }
397 
setWpsDeviceName(const hidl_string & name,setWpsDeviceName_cb _hidl_cb)398 Return<void> P2pIface::setWpsDeviceName(
399     const hidl_string& name, setWpsDeviceName_cb _hidl_cb)
400 {
401 	return validateAndCall(
402 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
403 	    &P2pIface::setWpsDeviceNameInternal, _hidl_cb, name);
404 }
405 
setWpsDeviceType(const hidl_array<uint8_t,8> & type,setWpsDeviceType_cb _hidl_cb)406 Return<void> P2pIface::setWpsDeviceType(
407     const hidl_array<uint8_t, 8>& type, setWpsDeviceType_cb _hidl_cb)
408 {
409 	return validateAndCall(
410 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
411 	    &P2pIface::setWpsDeviceTypeInternal, _hidl_cb, type);
412 }
413 
setWpsManufacturer(const hidl_string & manufacturer,setWpsManufacturer_cb _hidl_cb)414 Return<void> P2pIface::setWpsManufacturer(
415     const hidl_string& manufacturer, setWpsManufacturer_cb _hidl_cb)
416 {
417 	return validateAndCall(
418 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
419 	    &P2pIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
420 }
421 
setWpsModelName(const hidl_string & model_name,setWpsModelName_cb _hidl_cb)422 Return<void> P2pIface::setWpsModelName(
423     const hidl_string& model_name, setWpsModelName_cb _hidl_cb)
424 {
425 	return validateAndCall(
426 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
427 	    &P2pIface::setWpsModelNameInternal, _hidl_cb, model_name);
428 }
429 
setWpsModelNumber(const hidl_string & model_number,setWpsModelNumber_cb _hidl_cb)430 Return<void> P2pIface::setWpsModelNumber(
431     const hidl_string& model_number, setWpsModelNumber_cb _hidl_cb)
432 {
433 	return validateAndCall(
434 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
435 	    &P2pIface::setWpsModelNumberInternal, _hidl_cb, model_number);
436 }
437 
setWpsSerialNumber(const hidl_string & serial_number,setWpsSerialNumber_cb _hidl_cb)438 Return<void> P2pIface::setWpsSerialNumber(
439     const hidl_string& serial_number, setWpsSerialNumber_cb _hidl_cb)
440 {
441 	return validateAndCall(
442 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
443 	    &P2pIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
444 }
445 
setWpsConfigMethods(uint16_t config_methods,setWpsConfigMethods_cb _hidl_cb)446 Return<void> P2pIface::setWpsConfigMethods(
447     uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
448 {
449 	return validateAndCall(
450 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
451 	    &P2pIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
452 }
453 
enableWfd(bool enable,enableWfd_cb _hidl_cb)454 Return<void> P2pIface::enableWfd(bool enable, enableWfd_cb _hidl_cb)
455 {
456 	return validateAndCall(
457 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
458 	    &P2pIface::enableWfdInternal, _hidl_cb, enable);
459 }
460 
setWfdDeviceInfo(const hidl_array<uint8_t,6> & info,setWfdDeviceInfo_cb _hidl_cb)461 Return<void> P2pIface::setWfdDeviceInfo(
462     const hidl_array<uint8_t, 6>& info, setWfdDeviceInfo_cb _hidl_cb)
463 {
464 	return validateAndCall(
465 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
466 	    &P2pIface::setWfdDeviceInfoInternal, _hidl_cb, info);
467 }
468 
createNfcHandoverRequestMessage(createNfcHandoverRequestMessage_cb _hidl_cb)469 Return<void> P2pIface::createNfcHandoverRequestMessage(
470     createNfcHandoverRequestMessage_cb _hidl_cb)
471 {
472 	return validateAndCall(
473 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
474 	    &P2pIface::createNfcHandoverRequestMessageInternal, _hidl_cb);
475 }
476 
createNfcHandoverSelectMessage(createNfcHandoverSelectMessage_cb _hidl_cb)477 Return<void> P2pIface::createNfcHandoverSelectMessage(
478     createNfcHandoverSelectMessage_cb _hidl_cb)
479 {
480 	return validateAndCall(
481 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
482 	    &P2pIface::createNfcHandoverSelectMessageInternal, _hidl_cb);
483 }
484 
reportNfcHandoverResponse(const hidl_vec<uint8_t> & request,reportNfcHandoverResponse_cb _hidl_cb)485 Return<void> P2pIface::reportNfcHandoverResponse(
486     const hidl_vec<uint8_t>& request, reportNfcHandoverResponse_cb _hidl_cb)
487 {
488 	return validateAndCall(
489 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
490 	    &P2pIface::reportNfcHandoverResponseInternal, _hidl_cb, request);
491 }
492 
reportNfcHandoverInitiation(const hidl_vec<uint8_t> & select,reportNfcHandoverInitiation_cb _hidl_cb)493 Return<void> P2pIface::reportNfcHandoverInitiation(
494     const hidl_vec<uint8_t>& select, reportNfcHandoverInitiation_cb _hidl_cb)
495 {
496 	return validateAndCall(
497 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
498 	    &P2pIface::reportNfcHandoverInitiationInternal, _hidl_cb, select);
499 }
500 
saveConfig(saveConfig_cb _hidl_cb)501 Return<void> P2pIface::saveConfig(saveConfig_cb _hidl_cb)
502 {
503 	return validateAndCall(
504 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
505 	    &P2pIface::saveConfigInternal, _hidl_cb);
506 }
507 
getNameInternal()508 std::pair<SupplicantStatus, std::string> P2pIface::getNameInternal()
509 {
510 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
511 }
512 
getTypeInternal()513 std::pair<SupplicantStatus, IfaceType> P2pIface::getTypeInternal()
514 {
515 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
516 }
517 
518 std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
addNetworkInternal()519 P2pIface::addNetworkInternal()
520 {
521 	android::sp<ISupplicantP2pNetwork> network;
522 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
523 	struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
524 	if (!ssid) {
525 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
526 	}
527 	HidlManager* hidl_manager = HidlManager::getInstance();
528 	if (!hidl_manager ||
529 	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
530 		wpa_s->ifname, ssid->id, &network)) {
531 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
532 	}
533 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
534 }
535 
removeNetworkInternal(SupplicantNetworkId id)536 SupplicantStatus P2pIface::removeNetworkInternal(SupplicantNetworkId id)
537 {
538 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
539 	int result = wpa_supplicant_remove_network(wpa_s, id);
540 	if (result == -1) {
541 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
542 	}
543 	if (result != 0) {
544 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
545 	}
546 	return {SupplicantStatusCode::SUCCESS, ""};
547 }
548 
549 std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
getNetworkInternal(SupplicantNetworkId id)550 P2pIface::getNetworkInternal(SupplicantNetworkId id)
551 {
552 	android::sp<ISupplicantP2pNetwork> network;
553 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
554 	struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
555 	if (!ssid) {
556 		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
557 			network};
558 	}
559 	HidlManager* hidl_manager = HidlManager::getInstance();
560 	if (!hidl_manager ||
561 	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
562 		wpa_s->ifname, ssid->id, &network)) {
563 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
564 	}
565 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
566 }
567 
568 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
listNetworksInternal()569 P2pIface::listNetworksInternal()
570 {
571 	std::vector<SupplicantNetworkId> network_ids;
572 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
573 	for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
574 	     wpa_ssid = wpa_ssid->next) {
575 		network_ids.emplace_back(wpa_ssid->id);
576 	}
577 	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
578 }
579 
registerCallbackInternal(const sp<ISupplicantP2pIfaceCallback> & callback)580 SupplicantStatus P2pIface::registerCallbackInternal(
581     const sp<ISupplicantP2pIfaceCallback>& callback)
582 {
583 	HidlManager* hidl_manager = HidlManager::getInstance();
584 	if (!hidl_manager ||
585 	    hidl_manager->addP2pIfaceCallbackHidlObject(ifname_, callback)) {
586 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
587 	}
588 	return {SupplicantStatusCode::SUCCESS, ""};
589 }
590 
591 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
getDeviceAddressInternal()592 P2pIface::getDeviceAddressInternal()
593 {
594 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
595 	std::array<uint8_t, 6> addr;
596 	static_assert(ETH_ALEN == addr.size(), "Size mismatch");
597 	os_memcpy(addr.data(), wpa_s->global->p2p_dev_addr, ETH_ALEN);
598 	return {{SupplicantStatusCode::SUCCESS, ""}, addr};
599 }
600 
setSsidPostfixInternal(const std::vector<uint8_t> & postfix)601 SupplicantStatus P2pIface::setSsidPostfixInternal(
602     const std::vector<uint8_t>& postfix)
603 {
604 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
605 	if (p2p_set_ssid_postfix(
606 		wpa_s->global->p2p, postfix.data(), postfix.size())) {
607 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
608 	}
609 	return {SupplicantStatusCode::SUCCESS, ""};
610 }
611 
setGroupIdleInternal(const std::string & group_ifname,uint32_t timeout_in_sec)612 SupplicantStatus P2pIface::setGroupIdleInternal(
613     const std::string& group_ifname, uint32_t timeout_in_sec)
614 {
615 	struct wpa_supplicant* wpa_group_s =
616 	    retrieveGroupIfacePtr(group_ifname);
617 	if (!wpa_group_s) {
618 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
619 	}
620 	wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
621 	return {SupplicantStatusCode::SUCCESS, ""};
622 }
623 
setPowerSaveInternal(const std::string & group_ifname,bool enable)624 SupplicantStatus P2pIface::setPowerSaveInternal(
625     const std::string& group_ifname, bool enable)
626 {
627 	struct wpa_supplicant* wpa_group_s =
628 	    retrieveGroupIfacePtr(group_ifname);
629 	if (!wpa_group_s) {
630 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
631 	}
632 	if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
633 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
634 	}
635 	return {SupplicantStatusCode::SUCCESS, ""};
636 }
637 
findInternal(uint32_t timeout_in_sec)638 SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
639 {
640 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
641 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
642 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
643 	}
644 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
645 	if (wpas_p2p_find(
646 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
647 		nullptr, search_delay, 0, nullptr, 0)) {
648 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
649 	}
650 	return {SupplicantStatusCode::SUCCESS, ""};
651 }
652 
stopFindInternal()653 SupplicantStatus P2pIface::stopFindInternal()
654 {
655 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
656 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
657 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
658 	}
659 	wpas_p2p_stop_find(wpa_s);
660 	return {SupplicantStatusCode::SUCCESS, ""};
661 }
662 
flushInternal()663 SupplicantStatus P2pIface::flushInternal()
664 {
665 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
666 	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
667 	wpa_s->force_long_sd = 0;
668 	wpas_p2p_stop_find(wpa_s);
669 	wpa_s->parent->p2ps_method_config_any = 0;
670 	if (wpa_s->global->p2p)
671 		p2p_flush(wpa_s->global->p2p);
672 	return {SupplicantStatusCode::SUCCESS, ""};
673 }
674 
675 // This method only implements support for subset (needed by Android framework)
676 // 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)677 std::pair<SupplicantStatus, std::string> P2pIface::connectInternal(
678     const std::array<uint8_t, 6>& peer_address,
679     ISupplicantP2pIface::WpsProvisionMethod provision_method,
680     const std::string& pre_selected_pin, bool join_existing_group,
681     bool persistent, uint32_t go_intent)
682 {
683 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
684 	if (go_intent > 15) {
685 		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
686 	}
687 	int go_intent_signed = join_existing_group ? -1 : go_intent;
688 	p2p_wps_method wps_method = {};
689 	switch (provision_method) {
690 	case WpsProvisionMethod::PBC:
691 		wps_method = WPS_PBC;
692 		break;
693 	case WpsProvisionMethod::DISPLAY:
694 		wps_method = WPS_PIN_DISPLAY;
695 		break;
696 	case WpsProvisionMethod::KEYPAD:
697 		wps_method = WPS_PIN_KEYPAD;
698 		break;
699 	}
700 	int vht = wpa_s->conf->p2p_go_vht;
701 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
702 	const char* pin = pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
703 	int new_pin = wpas_p2p_connect(
704 	    wpa_s, peer_address.data(), pin, wps_method,
705 	    persistent, false, join_existing_group, false, go_intent_signed, 0, 0, -1,
706 	    false, ht40, vht, VHT_CHANWIDTH_USE_HT, nullptr, 0);
707 	if (new_pin < 0) {
708 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
709 	}
710 	std::string pin_ret;
711 	if (provision_method == WpsProvisionMethod::DISPLAY &&
712 	    pre_selected_pin.empty()) {
713 		pin_ret = misc_utils::convertWpsPinToString(new_pin);
714 	}
715 	return {{SupplicantStatusCode::SUCCESS, ""}, pin_ret};
716 }
717 
cancelConnectInternal()718 SupplicantStatus P2pIface::cancelConnectInternal()
719 {
720 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
721 	if (wpas_p2p_cancel(wpa_s)) {
722 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
723 	}
724 	return {SupplicantStatusCode::SUCCESS, ""};
725 }
726 
provisionDiscoveryInternal(const std::array<uint8_t,6> & peer_address,ISupplicantP2pIface::WpsProvisionMethod provision_method)727 SupplicantStatus P2pIface::provisionDiscoveryInternal(
728     const std::array<uint8_t, 6>& peer_address,
729     ISupplicantP2pIface::WpsProvisionMethod provision_method)
730 {
731 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
732 	p2ps_provision* prov_param;
733 	const char* config_method_str = nullptr;
734 	switch (provision_method) {
735 	case WpsProvisionMethod::PBC:
736 		config_method_str = kConfigMethodStrPbc;
737 		break;
738 	case WpsProvisionMethod::DISPLAY:
739 		config_method_str = kConfigMethodStrDisplay;
740 		break;
741 	case WpsProvisionMethod::KEYPAD:
742 		config_method_str = kConfigMethodStrKeypad;
743 		break;
744 	}
745 	if (wpas_p2p_prov_disc(
746 		wpa_s, peer_address.data(), config_method_str,
747 		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
748 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
749 	}
750 	return {SupplicantStatusCode::SUCCESS, ""};
751 }
752 
addGroupInternal(bool persistent,SupplicantNetworkId persistent_network_id)753 SupplicantStatus P2pIface::addGroupInternal(
754     bool persistent, SupplicantNetworkId persistent_network_id)
755 {
756 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
757 	int vht = wpa_s->conf->p2p_go_vht;
758 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
759 	struct wpa_ssid* ssid =
760 	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
761 	if (ssid == NULL) {
762 		if (wpas_p2p_group_add(
763 			wpa_s, persistent, 0, 0, ht40, vht,
764 			VHT_CHANWIDTH_USE_HT)) {
765 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
766 		} else {
767 			return {SupplicantStatusCode::SUCCESS, ""};
768 		}
769 	} else if (ssid->disabled == 2) {
770 		if (wpas_p2p_group_add_persistent(
771 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
772 			VHT_CHANWIDTH_USE_HT, NULL, 0, 0)) {
773 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
774 				""};
775 		} else {
776 			return {SupplicantStatusCode::SUCCESS, ""};
777 		}
778 	}
779 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
780 }
781 
removeGroupInternal(const std::string & group_ifname)782 SupplicantStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
783 {
784 	struct wpa_supplicant* wpa_group_s =
785 	    retrieveGroupIfacePtr(group_ifname);
786 	if (!wpa_group_s) {
787 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
788 	}
789 	if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
790 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
791 	}
792 	return {SupplicantStatusCode::SUCCESS, ""};
793 }
794 
rejectInternal(const std::array<uint8_t,6> & peer_address)795 SupplicantStatus P2pIface::rejectInternal(
796     const std::array<uint8_t, 6>& peer_address)
797 {
798 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
799 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
800 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
801 	}
802 	if (wpas_p2p_reject(wpa_s, peer_address.data())) {
803 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
804 	}
805 	return {SupplicantStatusCode::SUCCESS, ""};
806 }
807 
inviteInternal(const std::string & group_ifname,const std::array<uint8_t,6> & go_device_address,const std::array<uint8_t,6> & peer_address)808 SupplicantStatus P2pIface::inviteInternal(
809     const std::string& group_ifname,
810     const std::array<uint8_t, 6>& go_device_address,
811     const std::array<uint8_t, 6>& peer_address)
812 {
813 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
814 	if (wpas_p2p_invite_group(
815 		wpa_s, group_ifname.c_str(), peer_address.data(),
816 		go_device_address.data())) {
817 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
818 	}
819 	return {SupplicantStatusCode::SUCCESS, ""};
820 }
821 
reinvokeInternal(SupplicantNetworkId persistent_network_id,const std::array<uint8_t,6> & peer_address)822 SupplicantStatus P2pIface::reinvokeInternal(
823     SupplicantNetworkId persistent_network_id,
824     const std::array<uint8_t, 6>& peer_address)
825 {
826 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
827 	int vht = wpa_s->conf->p2p_go_vht;
828 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
829 	struct wpa_ssid* ssid =
830 	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
831 	if (ssid == NULL || ssid->disabled != 2) {
832 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
833 	}
834 	if (wpas_p2p_invite(
835 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
836 		VHT_CHANWIDTH_USE_HT, 0)) {
837 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
838 	}
839 	return {SupplicantStatusCode::SUCCESS, ""};
840 }
841 
configureExtListenInternal(uint32_t period_in_millis,uint32_t interval_in_millis)842 SupplicantStatus P2pIface::configureExtListenInternal(
843     uint32_t period_in_millis, uint32_t interval_in_millis)
844 {
845 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
846 	if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
847 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
848 	}
849 	return {SupplicantStatusCode::SUCCESS, ""};
850 }
851 
setListenChannelInternal(uint32_t channel,uint32_t operating_class)852 SupplicantStatus P2pIface::setListenChannelInternal(
853     uint32_t channel, uint32_t operating_class)
854 {
855 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
856 	if (p2p_set_listen_channel(
857 		wpa_s->global->p2p, operating_class, channel, 1)) {
858 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
859 	}
860 	return {SupplicantStatusCode::SUCCESS, ""};
861 }
862 
setDisallowedFrequenciesInternal(const std::vector<FreqRange> & ranges)863 SupplicantStatus P2pIface::setDisallowedFrequenciesInternal(
864     const std::vector<FreqRange>& ranges)
865 {
866 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
867 	using DestT = struct wpa_freq_range_list::wpa_freq_range;
868 	DestT* freq_ranges = nullptr;
869 	// Empty ranges is used to enable all frequencies.
870 	if (ranges.size() != 0) {
871 		freq_ranges =
872 		    static_cast<DestT*>(os_malloc(sizeof(DestT) * ranges.size()));
873 		if (!freq_ranges) {
874 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
875 		}
876 		uint32_t i = 0;
877 		for (const auto& range : ranges) {
878 			freq_ranges[i].min = range.min;
879 			freq_ranges[i].max = range.max;
880 			i++;
881 		}
882 	}
883 
884 	os_free(wpa_s->global->p2p_disallow_freq.range);
885 	wpa_s->global->p2p_disallow_freq.range = freq_ranges;
886 	wpa_s->global->p2p_disallow_freq.num = ranges.size();
887 	wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
888 	return {SupplicantStatusCode::SUCCESS, ""};
889 }
890 
getSsidInternal(const std::array<uint8_t,6> & peer_address)891 std::pair<SupplicantStatus, std::vector<uint8_t>> P2pIface::getSsidInternal(
892     const std::array<uint8_t, 6>& peer_address)
893 {
894 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
895 	const struct p2p_peer_info* info =
896 	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
897 	if (!info) {
898 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
899 	}
900 	const struct p2p_device* dev =
901 	    reinterpret_cast<const struct p2p_device*>(
902 		(reinterpret_cast<const uint8_t*>(info)) -
903 		offsetof(struct p2p_device, info));
904 	std::vector<uint8_t> ssid;
905 	if (dev && dev->oper_ssid_len) {
906 		ssid.assign(
907 		    dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
908 	}
909 	return {{SupplicantStatusCode::SUCCESS, ""}, ssid};
910 }
911 
getGroupCapabilityInternal(const std::array<uint8_t,6> & peer_address)912 std::pair<SupplicantStatus, uint32_t> P2pIface::getGroupCapabilityInternal(
913     const std::array<uint8_t, 6>& peer_address)
914 {
915 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
916 	const struct p2p_peer_info* info =
917 	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
918 	if (!info) {
919 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
920 	}
921 	return {{SupplicantStatusCode::SUCCESS, ""}, info->group_capab};
922 }
923 
addBonjourServiceInternal(const std::vector<uint8_t> & query,const std::vector<uint8_t> & response)924 SupplicantStatus P2pIface::addBonjourServiceInternal(
925     const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
926 {
927 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
928 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
929 	auto response_buf = misc_utils::convertVectorToWpaBuf(response);
930 	if (!query_buf || !response_buf) {
931 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
932 	}
933 	if (wpas_p2p_service_add_bonjour(
934 		wpa_s, query_buf.get(), response_buf.get())) {
935 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
936 	}
937 	// If successful, the wpabuf is referenced internally and hence should
938 	// not be freed.
939 	query_buf.release();
940 	response_buf.release();
941 	return {SupplicantStatusCode::SUCCESS, ""};
942 }
943 
removeBonjourServiceInternal(const std::vector<uint8_t> & query)944 SupplicantStatus P2pIface::removeBonjourServiceInternal(
945     const std::vector<uint8_t>& query)
946 {
947 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
948 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
949 	if (!query_buf) {
950 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
951 	}
952 	if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
953 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
954 	}
955 	return {SupplicantStatusCode::SUCCESS, ""};
956 }
957 
addUpnpServiceInternal(uint32_t version,const std::string & service_name)958 SupplicantStatus P2pIface::addUpnpServiceInternal(
959     uint32_t version, const std::string& service_name)
960 {
961 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
962 	if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
963 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
964 	}
965 	return {SupplicantStatusCode::SUCCESS, ""};
966 }
967 
removeUpnpServiceInternal(uint32_t version,const std::string & service_name)968 SupplicantStatus P2pIface::removeUpnpServiceInternal(
969     uint32_t version, const std::string& service_name)
970 {
971 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
972 	if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
973 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
974 	}
975 	return {SupplicantStatusCode::SUCCESS, ""};
976 }
977 
flushServicesInternal()978 SupplicantStatus P2pIface::flushServicesInternal()
979 {
980 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
981 	wpas_p2p_service_flush(wpa_s);
982 	return {SupplicantStatusCode::SUCCESS, ""};
983 }
984 
requestServiceDiscoveryInternal(const std::array<uint8_t,6> & peer_address,const std::vector<uint8_t> & query)985 std::pair<SupplicantStatus, uint64_t> P2pIface::requestServiceDiscoveryInternal(
986     const std::array<uint8_t, 6>& peer_address,
987     const std::vector<uint8_t>& query)
988 {
989 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
990 	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
991 	if (!query_buf) {
992 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
993 	}
994 	const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
995 				      ? nullptr
996 				      : peer_address.data();
997 	uint64_t identifier =
998 	    wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
999 	if (identifier == 0) {
1000 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1001 	}
1002 	return {{SupplicantStatusCode::SUCCESS, ""}, identifier};
1003 }
1004 
cancelServiceDiscoveryInternal(uint64_t identifier)1005 SupplicantStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
1006 {
1007 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1008 	if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
1009 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1010 	}
1011 	return {SupplicantStatusCode::SUCCESS, ""};
1012 }
1013 
setMiracastModeInternal(ISupplicantP2pIface::MiracastMode mode)1014 SupplicantStatus P2pIface::setMiracastModeInternal(
1015     ISupplicantP2pIface::MiracastMode mode)
1016 {
1017 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1018 	uint8_t mode_internal = convertHidlMiracastModeToInternal(mode);
1019 	const std::string cmd_str =
1020 	    kSetMiracastMode + std::to_string(mode_internal);
1021 	std::vector<char> cmd(
1022 	    cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
1023 	char driver_cmd_reply_buf[4096] = {};
1024 	if (wpa_drv_driver_cmd(
1025 		wpa_s, cmd.data(), driver_cmd_reply_buf,
1026 		sizeof(driver_cmd_reply_buf))) {
1027 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1028 	}
1029 	return {SupplicantStatusCode::SUCCESS, ""};
1030 }
1031 
startWpsPbcInternal(const std::string & group_ifname,const std::array<uint8_t,6> & bssid)1032 SupplicantStatus P2pIface::startWpsPbcInternal(
1033     const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
1034 {
1035 	struct wpa_supplicant* wpa_group_s =
1036 	    retrieveGroupIfacePtr(group_ifname);
1037 	if (!wpa_group_s) {
1038 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
1039 	}
1040 	const uint8_t* bssid_addr =
1041 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1042 #ifdef CONFIG_AP
1043 	if (wpa_group_s->ap_iface) {
1044 		if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
1045 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1046 		}
1047 		return {SupplicantStatusCode::SUCCESS, ""};
1048 	}
1049 #endif /* CONFIG_AP */
1050 	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0)) {
1051 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1052 	}
1053 	return {SupplicantStatusCode::SUCCESS, ""};
1054 }
1055 
startWpsPinKeypadInternal(const std::string & group_ifname,const std::string & pin)1056 SupplicantStatus P2pIface::startWpsPinKeypadInternal(
1057     const std::string& group_ifname, const std::string& pin)
1058 {
1059 	struct wpa_supplicant* wpa_group_s =
1060 	    retrieveGroupIfacePtr(group_ifname);
1061 	if (!wpa_group_s) {
1062 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
1063 	}
1064 #ifdef CONFIG_AP
1065 	if (wpa_group_s->ap_iface) {
1066 		if (wpa_supplicant_ap_wps_pin(
1067 				wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
1068 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1069 		}
1070 		return {SupplicantStatusCode::SUCCESS, ""};
1071 	}
1072 #endif /* CONFIG_AP */
1073 	if (wpas_wps_start_pin(
1074 		wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
1075 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1076 	}
1077 	return {SupplicantStatusCode::SUCCESS, ""};
1078 }
1079 
startWpsPinDisplayInternal(const std::string & group_ifname,const std::array<uint8_t,6> & bssid)1080 std::pair<SupplicantStatus, std::string> P2pIface::startWpsPinDisplayInternal(
1081     const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
1082 {
1083 	struct wpa_supplicant* wpa_group_s =
1084 	    retrieveGroupIfacePtr(group_ifname);
1085 	if (!wpa_group_s) {
1086 		return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""}, ""};
1087 	}
1088 	const uint8_t* bssid_addr =
1089 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1090 	int pin = wpas_wps_start_pin(
1091 	    wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
1092 	if (pin < 0) {
1093 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
1094 	}
1095 	return {{SupplicantStatusCode::SUCCESS, ""},
1096 		misc_utils::convertWpsPinToString(pin)};
1097 }
1098 
cancelWpsInternal(const std::string & group_ifname)1099 SupplicantStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
1100 {
1101 	struct wpa_supplicant* wpa_group_s =
1102 	    retrieveGroupIfacePtr(group_ifname);
1103 	if (!wpa_group_s) {
1104 		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
1105 	}
1106 	if (wpas_wps_cancel(wpa_group_s)) {
1107 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1108 	}
1109 	return {SupplicantStatusCode::SUCCESS, ""};
1110 }
1111 
setWpsDeviceNameInternal(const std::string & name)1112 SupplicantStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
1113 {
1114 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
1115 }
1116 
setWpsDeviceTypeInternal(const std::array<uint8_t,8> & type)1117 SupplicantStatus P2pIface::setWpsDeviceTypeInternal(
1118     const std::array<uint8_t, 8>& type)
1119 {
1120 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
1121 }
1122 
setWpsManufacturerInternal(const std::string & manufacturer)1123 SupplicantStatus P2pIface::setWpsManufacturerInternal(
1124     const std::string& manufacturer)
1125 {
1126 	return iface_config_utils::setWpsManufacturer(
1127 	    retrieveIfacePtr(), manufacturer);
1128 }
1129 
setWpsModelNameInternal(const std::string & model_name)1130 SupplicantStatus P2pIface::setWpsModelNameInternal(
1131     const std::string& model_name)
1132 {
1133 	return iface_config_utils::setWpsModelName(
1134 	    retrieveIfacePtr(), model_name);
1135 }
1136 
setWpsModelNumberInternal(const std::string & model_number)1137 SupplicantStatus P2pIface::setWpsModelNumberInternal(
1138     const std::string& model_number)
1139 {
1140 	return iface_config_utils::setWpsModelNumber(
1141 	    retrieveIfacePtr(), model_number);
1142 }
1143 
setWpsSerialNumberInternal(const std::string & serial_number)1144 SupplicantStatus P2pIface::setWpsSerialNumberInternal(
1145     const std::string& serial_number)
1146 {
1147 	return iface_config_utils::setWpsSerialNumber(
1148 	    retrieveIfacePtr(), serial_number);
1149 }
1150 
setWpsConfigMethodsInternal(uint16_t config_methods)1151 SupplicantStatus P2pIface::setWpsConfigMethodsInternal(uint16_t config_methods)
1152 {
1153 	return iface_config_utils::setWpsConfigMethods(
1154 	    retrieveIfacePtr(), config_methods);
1155 }
1156 
enableWfdInternal(bool enable)1157 SupplicantStatus P2pIface::enableWfdInternal(bool enable)
1158 {
1159 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1160 	wifi_display_enable(wpa_s->global, enable);
1161 	return {SupplicantStatusCode::SUCCESS, ""};
1162 }
1163 
setWfdDeviceInfoInternal(const std::array<uint8_t,6> & info)1164 SupplicantStatus P2pIface::setWfdDeviceInfoInternal(
1165     const std::array<uint8_t, 6>& info)
1166 {
1167 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1168 	std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
1169 	wpa_snprintf_hex(
1170 	    wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
1171 	    info.size());
1172 	// |wifi_display_subelem_set| expects the first 2 bytes
1173 	// to hold the lenght of the subelement. In this case it's
1174 	// fixed to 6, so prepend that.
1175 	std::string wfd_device_info_set_cmd_str =
1176 	    std::to_string(kWfdDeviceInfoSubelemId) + " " +
1177 	    kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
1178 	std::vector<char> wfd_device_info_set_cmd(
1179 	    wfd_device_info_set_cmd_str.c_str(),
1180 	    wfd_device_info_set_cmd_str.c_str() +
1181 		wfd_device_info_set_cmd_str.size() + 1);
1182 	if (wifi_display_subelem_set(
1183 		wpa_s->global, wfd_device_info_set_cmd.data())) {
1184 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1185 	}
1186 	return {SupplicantStatusCode::SUCCESS, ""};
1187 }
1188 
1189 std::pair<SupplicantStatus, std::vector<uint8_t>>
createNfcHandoverRequestMessageInternal()1190 P2pIface::createNfcHandoverRequestMessageInternal()
1191 {
1192 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1193 	auto buf = misc_utils::createWpaBufUniquePtr(
1194 	    wpas_p2p_nfc_handover_req(wpa_s, 1));
1195 	if (!buf) {
1196 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1197 	}
1198 	return {{SupplicantStatusCode::SUCCESS, ""},
1199 		misc_utils::convertWpaBufToVector(buf.get())};
1200 }
1201 
1202 std::pair<SupplicantStatus, std::vector<uint8_t>>
createNfcHandoverSelectMessageInternal()1203 P2pIface::createNfcHandoverSelectMessageInternal()
1204 {
1205 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1206 	auto buf = misc_utils::createWpaBufUniquePtr(
1207 	    wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
1208 	if (!buf) {
1209 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1210 	}
1211 	return {{SupplicantStatusCode::SUCCESS, ""},
1212 		misc_utils::convertWpaBufToVector(buf.get())};
1213 }
1214 
reportNfcHandoverResponseInternal(const std::vector<uint8_t> & request)1215 SupplicantStatus P2pIface::reportNfcHandoverResponseInternal(
1216     const std::vector<uint8_t>& request)
1217 {
1218 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1219 	auto req = misc_utils::convertVectorToWpaBuf(request);
1220 	auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
1221 	if (!req || !sel) {
1222 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1223 	}
1224 
1225 	if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
1226 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1227 	}
1228 	return {SupplicantStatusCode::SUCCESS, ""};
1229 }
1230 
reportNfcHandoverInitiationInternal(const std::vector<uint8_t> & select)1231 SupplicantStatus P2pIface::reportNfcHandoverInitiationInternal(
1232     const std::vector<uint8_t>& select)
1233 {
1234 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1235 	auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
1236 	auto sel = misc_utils::convertVectorToWpaBuf(select);
1237 	if (!req || !sel) {
1238 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1239 	}
1240 
1241 	if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
1242 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1243 	}
1244 	return {SupplicantStatusCode::SUCCESS, ""};
1245 }
1246 
saveConfigInternal()1247 SupplicantStatus P2pIface::saveConfigInternal()
1248 {
1249 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1250 	if (!wpa_s->conf->update_config) {
1251 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1252 	}
1253 	if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
1254 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1255 	}
1256 	return {SupplicantStatusCode::SUCCESS, ""};
1257 }
1258 
1259 /**
1260  * Retrieve the underlying |wpa_supplicant| struct
1261  * pointer for this iface.
1262  * If the underlying iface is removed, then all RPC method calls on this object
1263  * will return failure.
1264  */
retrieveIfacePtr()1265 wpa_supplicant* P2pIface::retrieveIfacePtr()
1266 {
1267 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1268 }
1269 
1270 /**
1271  * Retrieve the underlying |wpa_supplicant| struct
1272  * pointer for this group iface.
1273  */
retrieveGroupIfacePtr(const std::string & group_ifname)1274 wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
1275 {
1276 	return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
1277 }
1278 
1279 }  // namespace implementation
1280 }  // namespace V1_1
1281 }  // namespace wifi
1282 }  // namespace supplicant
1283 }  // namespace hardware
1284 }  // namespace android
1285