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  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "hidl_manager.h"
11 #include "hidl_return_util.h"
12 #include "iface_config_utils.h"
13 #include "misc_utils.h"
14 #include "sta_iface.h"
15 
16 extern "C"
17 {
18 #include "utils/eloop.h"
19 #include "gas_query.h"
20 #include "interworking.h"
21 #include "hs20_supplicant.h"
22 #include "wps_supplicant.h"
23 #include "dpp_supplicant.h"
24 #include "dpp.h"
25 }
26 
27 namespace {
28 using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
29 using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
30 using android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface;
31 using android::hardware::wifi::supplicant::V1_2::implementation::HidlManager;
32 
33 constexpr uint32_t kMaxAnqpElems = 100;
34 constexpr char kGetMacAddress[] = "MACADDR";
35 constexpr char kStartRxFilter[] = "RXFILTER-START";
36 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
37 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
38 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
39 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
40 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
41 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
42 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
43 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
44 constexpr char kSetCountryCode[] = "COUNTRY";
45 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>(
46     ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS);
47 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
48 
convertHidlRxFilterTypeToInternal(ISupplicantStaIface::RxFilterType type)49 uint8_t convertHidlRxFilterTypeToInternal(
50     ISupplicantStaIface::RxFilterType type)
51 {
52 	switch (type) {
53 	case ISupplicantStaIface::RxFilterType::V4_MULTICAST:
54 		return 2;
55 	case ISupplicantStaIface::RxFilterType::V6_MULTICAST:
56 		return 3;
57 	};
58 	WPA_ASSERT(false);
59 }
60 
convertHidlBtCoexModeToInternal(ISupplicantStaIface::BtCoexistenceMode mode)61 uint8_t convertHidlBtCoexModeToInternal(
62     ISupplicantStaIface::BtCoexistenceMode mode)
63 {
64 	switch (mode) {
65 	case ISupplicantStaIface::BtCoexistenceMode::ENABLED:
66 		return 0;
67 	case ISupplicantStaIface::BtCoexistenceMode::DISABLED:
68 		return 1;
69 	case ISupplicantStaIface::BtCoexistenceMode::SENSE:
70 		return 2;
71 	};
72 	WPA_ASSERT(false);
73 }
74 
doZeroArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd)75 SupplicantStatus doZeroArgDriverCommand(
76     struct wpa_supplicant *wpa_s, const char *cmd)
77 {
78 	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
79 	char driver_cmd_reply_buf[4096] = {};
80 	if (wpa_drv_driver_cmd(
81 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
82 		sizeof(driver_cmd_reply_buf))) {
83 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
84 	}
85 	return {SupplicantStatusCode::SUCCESS, ""};
86 }
87 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,uint8_t arg)88 SupplicantStatus doOneArgDriverCommand(
89     struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
90 {
91 	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
92 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
93 }
94 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,const std::string & arg)95 SupplicantStatus doOneArgDriverCommand(
96     struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
97 {
98 	std::string cmd_str = std::string(cmd) + " " + arg;
99 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
100 }
101 
endExtRadioWork(struct wpa_radio_work * work)102 void endExtRadioWork(struct wpa_radio_work *work)
103 {
104 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
105 	work->wpa_s->ext_work_in_progress = 0;
106 	radio_work_done(work);
107 	os_free(ework);
108 }
109 
extRadioWorkTimeoutCb(void * eloop_ctx,void * timeout_ctx)110 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
111 {
112 	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
113 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
114 	wpa_dbg(
115 	    work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
116 	    ework->id, work->type);
117 
118 	HidlManager *hidl_manager = HidlManager::getInstance();
119 	WPA_ASSERT(hidl_manager);
120 	hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
121 
122 	endExtRadioWork(work);
123 }
124 
startExtRadioWork(struct wpa_radio_work * work)125 void startExtRadioWork(struct wpa_radio_work *work)
126 {
127 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
128 	work->wpa_s->ext_work_in_progress = 1;
129 	if (!ework->timeout) {
130 		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
131 	}
132 	eloop_register_timeout(
133 	    ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
134 }
135 
extRadioWorkStartCb(struct wpa_radio_work * work,int deinit)136 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
137 {
138 	// deinit==1 is invoked during interface removal. Since the HIDL
139 	// interface does not support interface addition/removal, we don't
140 	// need to handle this scenario.
141 	WPA_ASSERT(!deinit);
142 
143 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
144 	wpa_dbg(
145 	    work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
146 	    ework->id, ework->type);
147 
148 	HidlManager *hidl_manager = HidlManager::getInstance();
149 	WPA_ASSERT(hidl_manager);
150 	hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
151 
152 	startExtRadioWork(work);
153 }
154 
155 }  // namespace
156 
157 namespace android {
158 namespace hardware {
159 namespace wifi {
160 namespace supplicant {
161 namespace V1_2 {
162 namespace implementation {
163 using hidl_return_util::validateAndCall;
164 
165 using namespace android::hardware::wifi::supplicant::V1_0;
166 using namespace android::hardware::wifi::supplicant::V1_1;
167 using V1_0::ISupplicantStaIfaceCallback;
168 
StaIface(struct wpa_global * wpa_global,const char ifname[])169 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
170     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
171 {}
172 
invalidate()173 void StaIface::invalidate() { is_valid_ = false; }
isValid()174 bool StaIface::isValid()
175 {
176 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
177 }
178 
getName(getName_cb _hidl_cb)179 Return<void> StaIface::getName(getName_cb _hidl_cb)
180 {
181 	return validateAndCall(
182 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
183 	    &StaIface::getNameInternal, _hidl_cb);
184 }
185 
getType(getType_cb _hidl_cb)186 Return<void> StaIface::getType(getType_cb _hidl_cb)
187 {
188 	return validateAndCall(
189 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
190 	    &StaIface::getTypeInternal, _hidl_cb);
191 }
192 
addNetwork(addNetwork_cb _hidl_cb)193 Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
194 {
195 	return validateAndCall(
196 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
197 	    &StaIface::addNetworkInternal, _hidl_cb);
198 }
199 
removeNetwork(SupplicantNetworkId id,removeNetwork_cb _hidl_cb)200 Return<void> StaIface::removeNetwork(
201     SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
202 {
203 	return validateAndCall(
204 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
205 	    &StaIface::removeNetworkInternal, _hidl_cb, id);
206 }
207 
getNetwork(SupplicantNetworkId id,getNetwork_cb _hidl_cb)208 Return<void> StaIface::getNetwork(
209     SupplicantNetworkId id, getNetwork_cb _hidl_cb)
210 {
211 	return validateAndCall(
212 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
213 	    &StaIface::getNetworkInternal, _hidl_cb, id);
214 }
215 
listNetworks(listNetworks_cb _hidl_cb)216 Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb)
217 {
218 	return validateAndCall(
219 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
220 	    &StaIface::listNetworksInternal, _hidl_cb);
221 }
222 
registerCallback(const sp<ISupplicantStaIfaceCallback> & callback,registerCallback_cb _hidl_cb)223 Return<void> StaIface::registerCallback(
224     const sp<ISupplicantStaIfaceCallback> &callback,
225     registerCallback_cb _hidl_cb)
226 {
227 	return validateAndCall(
228 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
229 	    &StaIface::registerCallbackInternal, _hidl_cb, callback);
230 }
231 
registerCallback_1_1(const sp<V1_1::ISupplicantStaIfaceCallback> & callback,registerCallback_cb _hidl_cb)232 Return<void> StaIface::registerCallback_1_1(
233     const sp<V1_1::ISupplicantStaIfaceCallback> &callback,
234     registerCallback_cb _hidl_cb)
235 {
236 	sp<V1_0::ISupplicantStaIfaceCallback> callback_1_0 = callback;
237 	return validateAndCall(
238 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
239 	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_0);
240 }
241 
registerCallback_1_2(const sp<V1_2::ISupplicantStaIfaceCallback> & callback,registerCallback_cb _hidl_cb)242 Return<void> StaIface::registerCallback_1_2(
243     const sp<V1_2::ISupplicantStaIfaceCallback> &callback,
244     registerCallback_cb _hidl_cb)
245 {
246 	sp<V1_1::ISupplicantStaIfaceCallback> callback_1_1 = callback;
247 	return validateAndCall(
248 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
249 	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_1);
250 }
251 
reassociate(reassociate_cb _hidl_cb)252 Return<void> StaIface::reassociate(reassociate_cb _hidl_cb)
253 {
254 	return validateAndCall(
255 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
256 	    &StaIface::reassociateInternal, _hidl_cb);
257 }
258 
reconnect(reconnect_cb _hidl_cb)259 Return<void> StaIface::reconnect(reconnect_cb _hidl_cb)
260 {
261 	return validateAndCall(
262 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
263 	    &StaIface::reconnectInternal, _hidl_cb);
264 }
265 
disconnect(disconnect_cb _hidl_cb)266 Return<void> StaIface::disconnect(disconnect_cb _hidl_cb)
267 {
268 	return validateAndCall(
269 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
270 	    &StaIface::disconnectInternal, _hidl_cb);
271 }
272 
setPowerSave(bool enable,setPowerSave_cb _hidl_cb)273 Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
274 {
275 	return validateAndCall(
276 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
277 	    &StaIface::setPowerSaveInternal, _hidl_cb, enable);
278 }
279 
initiateTdlsDiscover(const hidl_array<uint8_t,6> & mac_address,initiateTdlsDiscover_cb _hidl_cb)280 Return<void> StaIface::initiateTdlsDiscover(
281     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb)
282 {
283 	return validateAndCall(
284 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
285 	    &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address);
286 }
287 
initiateTdlsSetup(const hidl_array<uint8_t,6> & mac_address,initiateTdlsSetup_cb _hidl_cb)288 Return<void> StaIface::initiateTdlsSetup(
289     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb)
290 {
291 	return validateAndCall(
292 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
293 	    &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address);
294 }
295 
initiateTdlsTeardown(const hidl_array<uint8_t,6> & mac_address,initiateTdlsTeardown_cb _hidl_cb)296 Return<void> StaIface::initiateTdlsTeardown(
297     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb)
298 {
299 	return validateAndCall(
300 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
301 	    &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address);
302 }
initiateAnqpQuery(const hidl_array<uint8_t,6> & mac_address,const hidl_vec<ISupplicantStaIface::AnqpInfoId> & info_elements,const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> & sub_types,initiateAnqpQuery_cb _hidl_cb)303 Return<void> StaIface::initiateAnqpQuery(
304     const hidl_array<uint8_t, 6> &mac_address,
305     const hidl_vec<ISupplicantStaIface::AnqpInfoId> &info_elements,
306     const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types,
307     initiateAnqpQuery_cb _hidl_cb)
308 {
309 	return validateAndCall(
310 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
311 	    &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address,
312 	    info_elements, sub_types);
313 }
314 
initiateHs20IconQuery(const hidl_array<uint8_t,6> & mac_address,const hidl_string & file_name,initiateHs20IconQuery_cb _hidl_cb)315 Return<void> StaIface::initiateHs20IconQuery(
316     const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name,
317     initiateHs20IconQuery_cb _hidl_cb)
318 {
319 	return validateAndCall(
320 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
321 	    &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address,
322 	    file_name);
323 }
324 
getMacAddress(getMacAddress_cb _hidl_cb)325 Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb)
326 {
327 	return validateAndCall(
328 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
329 	    &StaIface::getMacAddressInternal, _hidl_cb);
330 }
331 
startRxFilter(startRxFilter_cb _hidl_cb)332 Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb)
333 {
334 	return validateAndCall(
335 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
336 	    &StaIface::startRxFilterInternal, _hidl_cb);
337 }
338 
stopRxFilter(stopRxFilter_cb _hidl_cb)339 Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb)
340 {
341 	return validateAndCall(
342 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
343 	    &StaIface::stopRxFilterInternal, _hidl_cb);
344 }
345 
addRxFilter(ISupplicantStaIface::RxFilterType type,addRxFilter_cb _hidl_cb)346 Return<void> StaIface::addRxFilter(
347     ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb)
348 {
349 	return validateAndCall(
350 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
351 	    &StaIface::addRxFilterInternal, _hidl_cb, type);
352 }
353 
removeRxFilter(ISupplicantStaIface::RxFilterType type,removeRxFilter_cb _hidl_cb)354 Return<void> StaIface::removeRxFilter(
355     ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb)
356 {
357 	return validateAndCall(
358 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
359 	    &StaIface::removeRxFilterInternal, _hidl_cb, type);
360 }
361 
setBtCoexistenceMode(ISupplicantStaIface::BtCoexistenceMode mode,setBtCoexistenceMode_cb _hidl_cb)362 Return<void> StaIface::setBtCoexistenceMode(
363     ISupplicantStaIface::BtCoexistenceMode mode,
364     setBtCoexistenceMode_cb _hidl_cb)
365 {
366 	return validateAndCall(
367 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
368 	    &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode);
369 }
370 
setBtCoexistenceScanModeEnabled(bool enable,setBtCoexistenceScanModeEnabled_cb _hidl_cb)371 Return<void> StaIface::setBtCoexistenceScanModeEnabled(
372     bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb)
373 {
374 	return validateAndCall(
375 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
376 	    &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb,
377 	    enable);
378 }
379 
setSuspendModeEnabled(bool enable,setSuspendModeEnabled_cb _hidl_cb)380 Return<void> StaIface::setSuspendModeEnabled(
381     bool enable, setSuspendModeEnabled_cb _hidl_cb)
382 {
383 	return validateAndCall(
384 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
385 	    &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable);
386 }
387 
setCountryCode(const hidl_array<int8_t,2> & code,setCountryCode_cb _hidl_cb)388 Return<void> StaIface::setCountryCode(
389     const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb)
390 {
391 	return validateAndCall(
392 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
393 	    &StaIface::setCountryCodeInternal, _hidl_cb, code);
394 }
395 
startWpsRegistrar(const hidl_array<uint8_t,6> & bssid,const hidl_string & pin,startWpsRegistrar_cb _hidl_cb)396 Return<void> StaIface::startWpsRegistrar(
397     const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin,
398     startWpsRegistrar_cb _hidl_cb)
399 {
400 	return validateAndCall(
401 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
402 	    &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin);
403 }
404 
startWpsPbc(const hidl_array<uint8_t,6> & bssid,startWpsPbc_cb _hidl_cb)405 Return<void> StaIface::startWpsPbc(
406     const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb)
407 {
408 	return validateAndCall(
409 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
410 	    &StaIface::startWpsPbcInternal, _hidl_cb, bssid);
411 }
412 
startWpsPinKeypad(const hidl_string & pin,startWpsPinKeypad_cb _hidl_cb)413 Return<void> StaIface::startWpsPinKeypad(
414     const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb)
415 {
416 	return validateAndCall(
417 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
418 	    &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin);
419 }
420 
startWpsPinDisplay(const hidl_array<uint8_t,6> & bssid,startWpsPinDisplay_cb _hidl_cb)421 Return<void> StaIface::startWpsPinDisplay(
422     const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb)
423 {
424 	return validateAndCall(
425 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
426 	    &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid);
427 }
428 
cancelWps(cancelWps_cb _hidl_cb)429 Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb)
430 {
431 	return validateAndCall(
432 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
433 	    &StaIface::cancelWpsInternal, _hidl_cb);
434 }
435 
setWpsDeviceName(const hidl_string & name,setWpsDeviceName_cb _hidl_cb)436 Return<void> StaIface::setWpsDeviceName(
437     const hidl_string &name, setWpsDeviceName_cb _hidl_cb)
438 {
439 	return validateAndCall(
440 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
441 	    &StaIface::setWpsDeviceNameInternal, _hidl_cb, name);
442 }
443 
setWpsDeviceType(const hidl_array<uint8_t,8> & type,setWpsDeviceType_cb _hidl_cb)444 Return<void> StaIface::setWpsDeviceType(
445     const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb)
446 {
447 	return validateAndCall(
448 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
449 	    &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type);
450 }
451 
setWpsManufacturer(const hidl_string & manufacturer,setWpsManufacturer_cb _hidl_cb)452 Return<void> StaIface::setWpsManufacturer(
453     const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb)
454 {
455 	return validateAndCall(
456 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
457 	    &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
458 }
459 
setWpsModelName(const hidl_string & model_name,setWpsModelName_cb _hidl_cb)460 Return<void> StaIface::setWpsModelName(
461     const hidl_string &model_name, setWpsModelName_cb _hidl_cb)
462 {
463 	return validateAndCall(
464 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
465 	    &StaIface::setWpsModelNameInternal, _hidl_cb, model_name);
466 }
467 
setWpsModelNumber(const hidl_string & model_number,setWpsModelNumber_cb _hidl_cb)468 Return<void> StaIface::setWpsModelNumber(
469     const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb)
470 {
471 	return validateAndCall(
472 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
473 	    &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number);
474 }
475 
setWpsSerialNumber(const hidl_string & serial_number,setWpsSerialNumber_cb _hidl_cb)476 Return<void> StaIface::setWpsSerialNumber(
477     const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb)
478 {
479 	return validateAndCall(
480 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
481 	    &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
482 }
483 
setWpsConfigMethods(uint16_t config_methods,setWpsConfigMethods_cb _hidl_cb)484 Return<void> StaIface::setWpsConfigMethods(
485     uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
486 {
487 	return validateAndCall(
488 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
489 	    &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
490 }
491 
setExternalSim(bool useExternalSim,setExternalSim_cb _hidl_cb)492 Return<void> StaIface::setExternalSim(
493     bool useExternalSim, setExternalSim_cb _hidl_cb)
494 {
495 	return validateAndCall(
496 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
497 	    &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim);
498 }
499 
addExtRadioWork(const hidl_string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec,addExtRadioWork_cb _hidl_cb)500 Return<void> StaIface::addExtRadioWork(
501     const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec,
502     addExtRadioWork_cb _hidl_cb)
503 {
504 	return validateAndCall(
505 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
506 	    &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz,
507 	    timeout_in_sec);
508 }
509 
removeExtRadioWork(uint32_t id,removeExtRadioWork_cb _hidl_cb)510 Return<void> StaIface::removeExtRadioWork(
511     uint32_t id, removeExtRadioWork_cb _hidl_cb)
512 {
513 	return validateAndCall(
514 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
515 	    &StaIface::removeExtRadioWorkInternal, _hidl_cb, id);
516 }
517 
enableAutoReconnect(bool enable,enableAutoReconnect_cb _hidl_cb)518 Return<void> StaIface::enableAutoReconnect(
519     bool enable, enableAutoReconnect_cb _hidl_cb)
520 {
521 	return validateAndCall(
522 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
523 	    &StaIface::enableAutoReconnectInternal, _hidl_cb, enable);
524 }
525 
getKeyMgmtCapabilities(getKeyMgmtCapabilities_cb _hidl_cb)526 Return<void> StaIface::getKeyMgmtCapabilities(
527     getKeyMgmtCapabilities_cb _hidl_cb)
528 {
529 	return validateAndCall(
530 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
531 	    &StaIface::getKeyMgmtCapabilitiesInternal, _hidl_cb);
532 }
533 
addDppPeerUri(const hidl_string & uri,addDppPeerUri_cb _hidl_cb)534 Return<void> StaIface::addDppPeerUri(const hidl_string& uri,
535 		addDppPeerUri_cb _hidl_cb)
536 {
537 	return validateAndCall(
538 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
539 	    &StaIface::addDppPeerUriInternal, _hidl_cb, uri);
540 }
541 
removeDppUri(uint32_t bootstrap_id,removeDppUri_cb _hidl_cb)542 Return<void> StaIface::removeDppUri(uint32_t bootstrap_id,
543 		removeDppUri_cb _hidl_cb)
544 {
545 	return validateAndCall(
546 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
547 	    &StaIface::removeDppUriInternal, _hidl_cb, bootstrap_id);
548 }
549 
startDppConfiguratorInitiator(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id,const hidl_string & ssid,const hidl_string & password,const hidl_string & psk,DppNetRole net_role,DppAkm security_akm,startDppConfiguratorInitiator_cb _hidl_cb)550 Return<void> StaIface::startDppConfiguratorInitiator(uint32_t peer_bootstrap_id,
551 		uint32_t own_bootstrap_id, const hidl_string& ssid,
552 		const hidl_string& password, const hidl_string& psk,
553 		DppNetRole net_role, DppAkm security_akm,
554 		startDppConfiguratorInitiator_cb _hidl_cb)
555 {
556 	return validateAndCall(
557 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
558 	    &StaIface::startDppConfiguratorInitiatorInternal, _hidl_cb, peer_bootstrap_id,
559 		own_bootstrap_id, ssid, password, psk, net_role, security_akm);
560 }
561 
startDppEnrolleeInitiator(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id,startDppConfiguratorInitiator_cb _hidl_cb)562 Return<void> StaIface::startDppEnrolleeInitiator(uint32_t peer_bootstrap_id,
563 		uint32_t own_bootstrap_id, startDppConfiguratorInitiator_cb _hidl_cb)
564 {
565 	return validateAndCall(
566 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
567 	    &StaIface::startDppEnrolleeInitiatorInternal, _hidl_cb, peer_bootstrap_id,
568 		own_bootstrap_id);
569 }
570 
stopDppInitiator(stopDppInitiator_cb _hidl_cb)571 Return<void> StaIface::stopDppInitiator(stopDppInitiator_cb _hidl_cb)
572 {
573 	return validateAndCall(
574 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
575 	    &StaIface::stopDppInitiatorInternal, _hidl_cb);
576 }
577 
getNameInternal()578 std::pair<SupplicantStatus, std::string> StaIface::getNameInternal()
579 {
580 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
581 }
582 
getTypeInternal()583 std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal()
584 {
585 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
586 }
587 
588 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
addNetworkInternal()589 StaIface::addNetworkInternal()
590 {
591 	android::sp<ISupplicantStaNetwork> network;
592 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
593 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
594 	if (!ssid) {
595 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
596 	}
597 	HidlManager *hidl_manager = HidlManager::getInstance();
598 	if (!hidl_manager ||
599 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
600 		wpa_s->ifname, ssid->id, &network)) {
601 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
602 	}
603 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
604 }
605 
removeNetworkInternal(SupplicantNetworkId id)606 SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id)
607 {
608 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
609 	int result = wpa_supplicant_remove_network(wpa_s, id);
610 	if (result == -1) {
611 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
612 	}
613 	if (result != 0) {
614 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
615 	}
616 	return {SupplicantStatusCode::SUCCESS, ""};
617 }
618 
619 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
getNetworkInternal(SupplicantNetworkId id)620 StaIface::getNetworkInternal(SupplicantNetworkId id)
621 {
622 	android::sp<ISupplicantStaNetwork> network;
623 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
624 	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
625 	if (!ssid) {
626 		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
627 			network};
628 	}
629 	HidlManager *hidl_manager = HidlManager::getInstance();
630 	if (!hidl_manager ||
631 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
632 		wpa_s->ifname, ssid->id, &network)) {
633 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
634 	}
635 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
636 }
637 
638 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
listNetworksInternal()639 StaIface::listNetworksInternal()
640 {
641 	std::vector<SupplicantNetworkId> network_ids;
642 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
643 	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
644 	     wpa_ssid = wpa_ssid->next) {
645 		network_ids.emplace_back(wpa_ssid->id);
646 	}
647 	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
648 }
649 
registerCallbackInternal(const sp<ISupplicantStaIfaceCallback> & callback)650 SupplicantStatus StaIface::registerCallbackInternal(
651     const sp<ISupplicantStaIfaceCallback> &callback)
652 {
653 	HidlManager *hidl_manager = HidlManager::getInstance();
654 	if (!hidl_manager ||
655 	    hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) {
656 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
657 	}
658 	return {SupplicantStatusCode::SUCCESS, ""};
659 }
660 
reassociateInternal()661 SupplicantStatus StaIface::reassociateInternal()
662 {
663 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
664 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
665 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
666 	}
667 	wpas_request_connection(wpa_s);
668 	return {SupplicantStatusCode::SUCCESS, ""};
669 }
670 
reconnectInternal()671 SupplicantStatus StaIface::reconnectInternal()
672 {
673 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
674 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
675 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
676 	}
677 	if (!wpa_s->disconnected) {
678 		return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
679 			""};
680 	}
681 	wpas_request_connection(wpa_s);
682 	return {SupplicantStatusCode::SUCCESS, ""};
683 }
684 
disconnectInternal()685 SupplicantStatus StaIface::disconnectInternal()
686 {
687 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
688 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
689 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
690 	}
691 	wpas_request_disconnection(wpa_s);
692 	return {SupplicantStatusCode::SUCCESS, ""};
693 }
694 
setPowerSaveInternal(bool enable)695 SupplicantStatus StaIface::setPowerSaveInternal(bool enable)
696 {
697 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
698 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
699 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
700 	}
701 	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
702 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
703 	}
704 	return {SupplicantStatusCode::SUCCESS, ""};
705 }
706 
initiateTdlsDiscoverInternal(const std::array<uint8_t,6> & mac_address)707 SupplicantStatus StaIface::initiateTdlsDiscoverInternal(
708     const std::array<uint8_t, 6> &mac_address)
709 {
710 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
711 	int ret;
712 	const u8 *peer = mac_address.data();
713 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
714 		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
715 	} else {
716 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
717 	}
718 	if (ret) {
719 		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
720 	}
721 	return {SupplicantStatusCode::SUCCESS, ""};
722 }
723 
initiateTdlsSetupInternal(const std::array<uint8_t,6> & mac_address)724 SupplicantStatus StaIface::initiateTdlsSetupInternal(
725     const std::array<uint8_t, 6> &mac_address)
726 {
727 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
728 	int ret;
729 	const u8 *peer = mac_address.data();
730 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
731 	    !(wpa_s->conf->tdls_external_control)) {
732 		wpa_tdls_remove(wpa_s->wpa, peer);
733 		ret = wpa_tdls_start(wpa_s->wpa, peer);
734 	} else {
735 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
736 	}
737 	if (ret) {
738 		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
739 	}
740 	return {SupplicantStatusCode::SUCCESS, ""};
741 }
742 
initiateTdlsTeardownInternal(const std::array<uint8_t,6> & mac_address)743 SupplicantStatus StaIface::initiateTdlsTeardownInternal(
744     const std::array<uint8_t, 6> &mac_address)
745 {
746 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
747 	int ret;
748 	const u8 *peer = mac_address.data();
749 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
750 	    !(wpa_s->conf->tdls_external_control)) {
751 		ret = wpa_tdls_teardown_link(
752 		    wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
753 	} else {
754 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
755 	}
756 	if (ret) {
757 		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
758 	}
759 	return {SupplicantStatusCode::SUCCESS, ""};
760 }
761 
initiateAnqpQueryInternal(const std::array<uint8_t,6> & mac_address,const std::vector<ISupplicantStaIface::AnqpInfoId> & info_elements,const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> & sub_types)762 SupplicantStatus StaIface::initiateAnqpQueryInternal(
763     const std::array<uint8_t, 6> &mac_address,
764     const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements,
765     const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types)
766 {
767 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
768 	if (info_elements.size() > kMaxAnqpElems) {
769 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
770 	}
771 	uint16_t info_elems_buf[kMaxAnqpElems];
772 	uint32_t num_info_elems = 0;
773 	for (const auto &info_element : info_elements) {
774 		info_elems_buf[num_info_elems++] =
775 		    static_cast<std::underlying_type<
776 			ISupplicantStaIface::AnqpInfoId>::type>(info_element);
777 	}
778 	uint32_t sub_types_bitmask = 0;
779 	for (const auto &type : sub_types) {
780 		sub_types_bitmask |= BIT(
781 		    static_cast<std::underlying_type<
782 			ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type));
783 	}
784 	if (anqp_send_req(
785 		wpa_s, mac_address.data(), info_elems_buf, num_info_elems,
786 		sub_types_bitmask, false)) {
787 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
788 	}
789 	return {SupplicantStatusCode::SUCCESS, ""};
790 }
791 
initiateHs20IconQueryInternal(const std::array<uint8_t,6> & mac_address,const std::string & file_name)792 SupplicantStatus StaIface::initiateHs20IconQueryInternal(
793     const std::array<uint8_t, 6> &mac_address, const std::string &file_name)
794 {
795 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
796 	wpa_s->fetch_osu_icon_in_progress = 0;
797 	if (hs20_anqp_send_req(
798 		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
799 		reinterpret_cast<const uint8_t *>(file_name.c_str()),
800 		file_name.size(), true)) {
801 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
802 	}
803 	return {SupplicantStatusCode::SUCCESS, ""};
804 }
805 
806 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
getMacAddressInternal()807 StaIface::getMacAddressInternal()
808 {
809 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
810 	std::vector<char> cmd(
811 	    kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
812 	char driver_cmd_reply_buf[4096] = {};
813 	int ret = wpa_drv_driver_cmd(
814 	    wpa_s, cmd.data(), driver_cmd_reply_buf,
815 	    sizeof(driver_cmd_reply_buf));
816 	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
817 	std::string reply_str = driver_cmd_reply_buf;
818 	if (ret < 0 || reply_str.empty() ||
819 	    reply_str.find("=") == std::string::npos) {
820 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
821 	}
822 	// Remove all whitespace first and then split using the delimiter "=".
823 	reply_str.erase(
824 	    remove_if(reply_str.begin(), reply_str.end(), isspace),
825 	    reply_str.end());
826 	std::string mac_addr_str =
827 	    reply_str.substr(reply_str.find("=") + 1, reply_str.size());
828 	std::array<uint8_t, 6> mac_addr;
829 	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
830 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
831 	}
832 	return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr};
833 }
834 
startRxFilterInternal()835 SupplicantStatus StaIface::startRxFilterInternal()
836 {
837 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
838 }
839 
stopRxFilterInternal()840 SupplicantStatus StaIface::stopRxFilterInternal()
841 {
842 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
843 }
844 
addRxFilterInternal(ISupplicantStaIface::RxFilterType type)845 SupplicantStatus StaIface::addRxFilterInternal(
846     ISupplicantStaIface::RxFilterType type)
847 {
848 	return doOneArgDriverCommand(
849 	    retrieveIfacePtr(), kAddRxFilter,
850 	    convertHidlRxFilterTypeToInternal(type));
851 }
852 
removeRxFilterInternal(ISupplicantStaIface::RxFilterType type)853 SupplicantStatus StaIface::removeRxFilterInternal(
854     ISupplicantStaIface::RxFilterType type)
855 {
856 	return doOneArgDriverCommand(
857 	    retrieveIfacePtr(), kRemoveRxFilter,
858 	    convertHidlRxFilterTypeToInternal(type));
859 }
860 
setBtCoexistenceModeInternal(ISupplicantStaIface::BtCoexistenceMode mode)861 SupplicantStatus StaIface::setBtCoexistenceModeInternal(
862     ISupplicantStaIface::BtCoexistenceMode mode)
863 {
864 	return doOneArgDriverCommand(
865 	    retrieveIfacePtr(), kSetBtCoexistenceMode,
866 	    convertHidlBtCoexModeToInternal(mode));
867 }
868 
setBtCoexistenceScanModeEnabledInternal(bool enable)869 SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
870 {
871 	const char *cmd;
872 	if (enable) {
873 		cmd = kSetBtCoexistenceScanStart;
874 	} else {
875 		cmd = kSetBtCoexistenceScanStop;
876 	}
877 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
878 }
879 
setSuspendModeEnabledInternal(bool enable)880 SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable)
881 {
882 	const char *cmd;
883 	if (enable) {
884 		cmd = kSetSupendModeEnabled;
885 	} else {
886 		cmd = kSetSupendModeDisabled;
887 	}
888 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
889 }
890 
setCountryCodeInternal(const std::array<int8_t,2> & code)891 SupplicantStatus StaIface::setCountryCodeInternal(
892     const std::array<int8_t, 2> &code)
893 {
894 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
895 	SupplicantStatus status = doOneArgDriverCommand(
896 	    wpa_s, kSetCountryCode,
897 	    std::string(std::begin(code), std::end(code)));
898 	if (status.code != SupplicantStatusCode::SUCCESS) {
899 		return status;
900 	}
901 	struct p2p_data *p2p = wpa_s->global->p2p;
902 	if (p2p) {
903 		char country[3];
904 		country[0] = code[0];
905 		country[1] = code[1];
906 		country[2] = 0x04;
907 		p2p_set_country(p2p, country);
908 	}
909 	return {SupplicantStatusCode::SUCCESS, ""};
910 }
911 
startWpsRegistrarInternal(const std::array<uint8_t,6> & bssid,const std::string & pin)912 SupplicantStatus StaIface::startWpsRegistrarInternal(
913     const std::array<uint8_t, 6> &bssid, const std::string &pin)
914 {
915 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
916 	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
917 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
918 	}
919 	return {SupplicantStatusCode::SUCCESS, ""};
920 }
921 
startWpsPbcInternal(const std::array<uint8_t,6> & bssid)922 SupplicantStatus StaIface::startWpsPbcInternal(
923     const std::array<uint8_t, 6> &bssid)
924 {
925 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
926 	const uint8_t *bssid_addr =
927 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
928 	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
929 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
930 	}
931 	return {SupplicantStatusCode::SUCCESS, ""};
932 }
933 
startWpsPinKeypadInternal(const std::string & pin)934 SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
935 {
936 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
937 	if (wpas_wps_start_pin(
938 		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
939 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
940 	}
941 	return {SupplicantStatusCode::SUCCESS, ""};
942 }
943 
startWpsPinDisplayInternal(const std::array<uint8_t,6> & bssid)944 std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal(
945     const std::array<uint8_t, 6> &bssid)
946 {
947 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
948 	const uint8_t *bssid_addr =
949 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
950 	int pin =
951 	    wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
952 	if (pin < 0) {
953 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
954 	}
955 	return {{SupplicantStatusCode::SUCCESS, ""},
956 		misc_utils::convertWpsPinToString(pin)};
957 }
958 
cancelWpsInternal()959 SupplicantStatus StaIface::cancelWpsInternal()
960 {
961 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
962 	if (wpas_wps_cancel(wpa_s)) {
963 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
964 	}
965 	return {SupplicantStatusCode::SUCCESS, ""};
966 }
967 
setWpsDeviceNameInternal(const std::string & name)968 SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
969 {
970 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
971 }
972 
setWpsDeviceTypeInternal(const std::array<uint8_t,8> & type)973 SupplicantStatus StaIface::setWpsDeviceTypeInternal(
974     const std::array<uint8_t, 8> &type)
975 {
976 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
977 }
978 
setWpsManufacturerInternal(const std::string & manufacturer)979 SupplicantStatus StaIface::setWpsManufacturerInternal(
980     const std::string &manufacturer)
981 {
982 	return iface_config_utils::setWpsManufacturer(
983 	    retrieveIfacePtr(), manufacturer);
984 }
985 
setWpsModelNameInternal(const std::string & model_name)986 SupplicantStatus StaIface::setWpsModelNameInternal(
987     const std::string &model_name)
988 {
989 	return iface_config_utils::setWpsModelName(
990 	    retrieveIfacePtr(), model_name);
991 }
992 
setWpsModelNumberInternal(const std::string & model_number)993 SupplicantStatus StaIface::setWpsModelNumberInternal(
994     const std::string &model_number)
995 {
996 	return iface_config_utils::setWpsModelNumber(
997 	    retrieveIfacePtr(), model_number);
998 }
999 
setWpsSerialNumberInternal(const std::string & serial_number)1000 SupplicantStatus StaIface::setWpsSerialNumberInternal(
1001     const std::string &serial_number)
1002 {
1003 	return iface_config_utils::setWpsSerialNumber(
1004 	    retrieveIfacePtr(), serial_number);
1005 }
1006 
setWpsConfigMethodsInternal(uint16_t config_methods)1007 SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods)
1008 {
1009 	return iface_config_utils::setWpsConfigMethods(
1010 	    retrieveIfacePtr(), config_methods);
1011 }
1012 
setExternalSimInternal(bool useExternalSim)1013 SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim)
1014 {
1015 	return iface_config_utils::setExternalSim(
1016 	    retrieveIfacePtr(), useExternalSim);
1017 }
1018 
addExtRadioWorkInternal(const std::string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec)1019 std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal(
1020     const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
1021 {
1022 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1023 	auto *ework = static_cast<struct wpa_external_work *>(
1024 	    os_zalloc(sizeof(struct wpa_external_work)));
1025 	if (!ework) {
1026 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
1027 			UINT32_MAX};
1028 	}
1029 
1030 	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
1031 	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
1032 	ework->timeout = timeout_in_sec;
1033 	wpa_s->ext_work_id++;
1034 	if (wpa_s->ext_work_id == 0) {
1035 		wpa_s->ext_work_id++;
1036 	}
1037 	ework->id = wpa_s->ext_work_id;
1038 
1039 	if (radio_add_work(
1040 		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
1041 		ework)) {
1042 		os_free(ework);
1043 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
1044 			UINT32_MAX};
1045 	}
1046 	return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id};
1047 }
1048 
removeExtRadioWorkInternal(uint32_t id)1049 SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
1050 {
1051 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1052 	struct wpa_radio_work *work;
1053 	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
1054 	{
1055 		if (os_strncmp(
1056 			work->type, kExtRadioWorkNamePrefix,
1057 			sizeof(kExtRadioWorkNamePrefix)) != 0)
1058 			continue;
1059 
1060 		auto *ework =
1061 		    static_cast<struct wpa_external_work *>(work->ctx);
1062 		if (ework->id != id)
1063 			continue;
1064 
1065 		wpa_dbg(
1066 		    wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
1067 		    ework->id, ework->type);
1068 		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
1069 		endExtRadioWork(work);
1070 
1071 		return {SupplicantStatusCode::SUCCESS, ""};
1072 	}
1073 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1074 }
1075 
enableAutoReconnectInternal(bool enable)1076 SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable)
1077 {
1078 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1079 	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
1080 	return {SupplicantStatusCode::SUCCESS, ""};
1081 }
1082 
1083 std::pair<SupplicantStatus, uint32_t>
getKeyMgmtCapabilitiesInternal()1084 StaIface::getKeyMgmtCapabilitiesInternal()
1085 {
1086 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1087 	struct wpa_driver_capa capa;
1088 	uint32_t mask = 0;
1089 
1090 	/* Get capabilities from driver and populate the key management mask */
1091 	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
1092 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, mask};
1093 	}
1094 
1095 	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
1096 	 * flags and always enabled.
1097 	 */
1098 	mask |=
1099 	    (ISupplicantStaNetwork::KeyMgmtMask::NONE |
1100 	     ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X);
1101 
1102 	if (capa.key_mgmt &
1103 	    (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1104 		mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP;
1105 	}
1106 
1107 	if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1108 			     WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1109 		mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK;
1110 	}
1111 #ifdef CONFIG_SUITEB192
1112 	if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
1113 		mask |= ISupplicantStaNetwork::KeyMgmtMask::SUITE_B_192;
1114 	}
1115 #endif /* CONFIG_SUITEB192 */
1116 #ifdef CONFIG_OWE
1117 	if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
1118 		mask |= ISupplicantStaNetwork::KeyMgmtMask::OWE;
1119 	}
1120 #endif /* CONFIG_OWE */
1121 #ifdef CONFIG_SAE
1122 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
1123 		mask |= ISupplicantStaNetwork::KeyMgmtMask::SAE;
1124 	}
1125 #endif /* CONFIG_SAE */
1126 #ifdef CONFIG_DPP
1127 	if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
1128 		mask |= ISupplicantStaNetwork::KeyMgmtMask::DPP;
1129 	}
1130 #endif
1131 	return {{SupplicantStatusCode::SUCCESS, ""}, mask};
1132 }
1133 
1134 std::pair<SupplicantStatus, uint32_t>
addDppPeerUriInternal(const std::string & uri)1135 StaIface::addDppPeerUriInternal(const std::string& uri)
1136 {
1137 #ifdef CONFIG_DPP
1138 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1139 	int32_t id;
1140 
1141 	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
1142 
1143 	if (id > 0) {
1144 		return {{SupplicantStatusCode::SUCCESS, ""}, id};
1145 	}
1146 #endif
1147 	return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, -1};
1148 }
1149 
removeDppUriInternal(uint32_t bootstrap_id)1150 SupplicantStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
1151 {
1152 #ifdef CONFIG_DPP
1153 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1154 	std::string bootstrap_id_str;
1155 
1156 	if (bootstrap_id == 0) {
1157 		bootstrap_id_str = "*";
1158 	}
1159 	else {
1160 		bootstrap_id_str = std::to_string(bootstrap_id);
1161 	}
1162 
1163 	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
1164 		return {SupplicantStatusCode::SUCCESS, ""};
1165 	}
1166 #endif
1167 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1168 }
1169 
startDppConfiguratorInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id,const std::string & ssid,const std::string & password,const std::string & psk,DppNetRole net_role,DppAkm security_akm)1170 SupplicantStatus StaIface::startDppConfiguratorInitiatorInternal(
1171 		uint32_t peer_bootstrap_id,	uint32_t own_bootstrap_id,
1172 		const std::string& ssid, const std::string& password,
1173 		const std::string& psk, DppNetRole net_role, DppAkm security_akm)
1174 {
1175 #ifdef CONFIG_DPP
1176 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1177 	std::string cmd = "";
1178 
1179 	if (net_role != DppNetRole::AP &&
1180 			net_role != DppNetRole::STA) {
1181 		wpa_printf(MSG_ERROR,
1182 			   "DPP: Error: Invalid network role specified: %d", net_role);
1183 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1184 	}
1185 
1186 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1187 	cmd += (own_bootstrap_id > 0) ?
1188 			" own=" + std::to_string(own_bootstrap_id) : "";
1189 
1190 	/* Check for supported AKMs */
1191 	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
1192 			security_akm != DppAkm::PSK_SAE) {
1193 		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
1194 				security_akm);
1195 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1196 	}
1197 
1198 	/* SAE AKM requires SSID and password to be initialized */
1199 	if ((security_akm == DppAkm::SAE ||
1200 			security_akm == DppAkm::PSK_SAE) &&
1201 			(ssid.empty() || password.empty())) {
1202 		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
1203 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1204 	} else if (security_akm == DppAkm::PSK ||
1205 			security_akm == DppAkm::PSK_SAE) {
1206 		/* PSK AKM requires SSID and password/psk to be initialized */
1207 		if (ssid.empty()) {
1208 			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
1209 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1210 		}
1211 		if (password.empty() && psk.empty()) {
1212 			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
1213 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1214 		}
1215 	}
1216 
1217 	cmd += " role=configurator";
1218 	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
1219 
1220 	if (!psk.empty()) {
1221 		cmd += " psk=" + psk;
1222 	} else {
1223 		cmd += (password.empty()) ? "" : " pass=" + password;
1224 	}
1225 
1226 	std::string role = "";
1227 	if (net_role == DppNetRole::AP) {
1228 		role = "ap-";
1229 	}
1230 	else {
1231 		role = "sta-";
1232 	}
1233 
1234 	switch (security_akm) {
1235 	case DppAkm::PSK:
1236 		role += "psk";
1237 		break;
1238 
1239 	case DppAkm::SAE:
1240 		role += "sae";
1241 		break;
1242 
1243 	case DppAkm::PSK_SAE:
1244 		role += "psk-sae";
1245 		break;
1246 
1247 	default:
1248 		wpa_printf(MSG_ERROR,
1249 			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
1250 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1251 	}
1252 
1253 	cmd += " conf=";
1254 	cmd += role;
1255 
1256 	wpa_printf(MSG_DEBUG,
1257 		   "DPP initiator command: %s", cmd.c_str());
1258 
1259 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1260 		return {SupplicantStatusCode::SUCCESS, ""};
1261 	}
1262 #endif
1263 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1264 }
1265 
startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id)1266 SupplicantStatus StaIface::startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,
1267 			uint32_t own_bootstrap_id) {
1268 #ifdef CONFIG_DPP
1269 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1270 	std::string cmd = "";
1271 
1272 	/* Report received configuration to HIDL and create an internal profile */
1273 	wpa_s->conf->dpp_config_processing = 1;
1274 
1275 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1276 	cmd += (own_bootstrap_id > 0) ?
1277 			" own=" + std::to_string(own_bootstrap_id) : "";
1278 
1279 	cmd += " role=enrollee";
1280 
1281 	wpa_printf(MSG_DEBUG,
1282 		   "DPP initiator command: %s", cmd.c_str());
1283 
1284 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1285 		return {SupplicantStatusCode::SUCCESS, ""};
1286 	}
1287 #endif
1288 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1289 }
stopDppInitiatorInternal()1290 SupplicantStatus StaIface::stopDppInitiatorInternal()
1291 {
1292 #ifdef CONFIG_DPP
1293 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1294 
1295 	wpas_dpp_stop(wpa_s);
1296 	return {SupplicantStatusCode::SUCCESS, ""};
1297 #else
1298 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1299 #endif
1300 }
1301 
1302 /**
1303  * Retrieve the underlying |wpa_supplicant| struct
1304  * pointer for this iface.
1305  * If the underlying iface is removed, then all RPC method calls on this object
1306  * will return failure.
1307  */
retrieveIfacePtr()1308 wpa_supplicant *StaIface::retrieveIfacePtr()
1309 {
1310 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1311 }
1312 }  // namespace implementation
1313 }  // namespace V1_2
1314 }  // namespace supplicant
1315 }  // namespace wifi
1316 }  // namespace hardware
1317 }  // namespace android
1318