• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hidl interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
5  *
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 #include "utils/eloop.h"
18 #include "gas_query.h"
19 #include "interworking.h"
20 #include "hs20_supplicant.h"
21 #include "wps_supplicant.h"
22 }
23 
24 namespace {
25 using android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface;
26 using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
27 using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
28 using android::hardware::wifi::supplicant::V1_1::implementation::HidlManager;
29 
30 constexpr uint32_t kMaxAnqpElems = 100;
31 constexpr char kGetMacAddress[] = "MACADDR";
32 constexpr char kStartRxFilter[] = "RXFILTER-START";
33 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
34 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
35 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
36 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
37 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
38 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
39 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
40 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
41 constexpr char kSetCountryCode[] = "COUNTRY";
42 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>(
43     ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS);
44 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
45 
convertHidlRxFilterTypeToInternal(ISupplicantStaIface::RxFilterType type)46 uint8_t convertHidlRxFilterTypeToInternal(
47     ISupplicantStaIface::RxFilterType type)
48 {
49 	switch (type) {
50 	case ISupplicantStaIface::RxFilterType::V4_MULTICAST:
51 		return 2;
52 	case ISupplicantStaIface::RxFilterType::V6_MULTICAST:
53 		return 3;
54 	};
55 	WPA_ASSERT(false);
56 }
57 
convertHidlBtCoexModeToInternal(ISupplicantStaIface::BtCoexistenceMode mode)58 uint8_t convertHidlBtCoexModeToInternal(
59     ISupplicantStaIface::BtCoexistenceMode mode)
60 {
61 	switch (mode) {
62 	case ISupplicantStaIface::BtCoexistenceMode::ENABLED:
63 		return 0;
64 	case ISupplicantStaIface::BtCoexistenceMode::DISABLED:
65 		return 1;
66 	case ISupplicantStaIface::BtCoexistenceMode::SENSE:
67 		return 2;
68 	};
69 	WPA_ASSERT(false);
70 }
71 
doZeroArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd)72 SupplicantStatus doZeroArgDriverCommand(
73     struct wpa_supplicant *wpa_s, const char *cmd)
74 {
75 	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
76 	char driver_cmd_reply_buf[4096] = {};
77 	if (wpa_drv_driver_cmd(
78 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
79 		sizeof(driver_cmd_reply_buf))) {
80 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
81 	}
82 	return {SupplicantStatusCode::SUCCESS, ""};
83 }
84 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,uint8_t arg)85 SupplicantStatus doOneArgDriverCommand(
86     struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
87 {
88 	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
89 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
90 }
91 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,const std::string & arg)92 SupplicantStatus doOneArgDriverCommand(
93     struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
94 {
95 	std::string cmd_str = std::string(cmd) + " " + arg;
96 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
97 }
98 
endExtRadioWork(struct wpa_radio_work * work)99 void endExtRadioWork(struct wpa_radio_work *work)
100 {
101 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
102 	work->wpa_s->ext_work_in_progress = 0;
103 	radio_work_done(work);
104 	os_free(ework);
105 }
106 
extRadioWorkTimeoutCb(void * eloop_ctx,void * timeout_ctx)107 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
108 {
109 	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
110 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
111 	wpa_dbg(
112 	    work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
113 	    ework->id, work->type);
114 
115 	HidlManager *hidl_manager = HidlManager::getInstance();
116 	WPA_ASSERT(hidl_manager);
117 	hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
118 
119 	endExtRadioWork(work);
120 }
121 
startExtRadioWork(struct wpa_radio_work * work)122 void startExtRadioWork(struct wpa_radio_work *work)
123 {
124 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
125 	work->wpa_s->ext_work_in_progress = 1;
126 	if (!ework->timeout) {
127 		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
128 	}
129 	eloop_register_timeout(
130 	    ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
131 }
132 
extRadioWorkStartCb(struct wpa_radio_work * work,int deinit)133 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
134 {
135 	// deinit==1 is invoked during interface removal. Since the HIDL
136 	// interface does not support interface addition/removal, we don't
137 	// need to handle this scenario.
138 	WPA_ASSERT(!deinit);
139 
140 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
141 	wpa_dbg(
142 	    work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
143 	    ework->id, ework->type);
144 
145 	HidlManager *hidl_manager = HidlManager::getInstance();
146 	WPA_ASSERT(hidl_manager);
147 	hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
148 
149 	startExtRadioWork(work);
150 }
151 
152 }  // namespace
153 
154 namespace android {
155 namespace hardware {
156 namespace wifi {
157 namespace supplicant {
158 namespace V1_1 {
159 namespace implementation {
160 using hidl_return_util::validateAndCall;
161 
162 using namespace android::hardware::wifi::supplicant::V1_0;
163 using namespace android::hardware::wifi::supplicant::V1_1;
164 using V1_0::ISupplicantStaIfaceCallback;
165 
StaIface(struct wpa_global * wpa_global,const char ifname[])166 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
167     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
168 {
169 }
170 
invalidate()171 void StaIface::invalidate() { is_valid_ = false; }
isValid()172 bool StaIface::isValid()
173 {
174 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
175 }
176 
getName(getName_cb _hidl_cb)177 Return<void> StaIface::getName(getName_cb _hidl_cb)
178 {
179 	return validateAndCall(
180 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
181 	    &StaIface::getNameInternal, _hidl_cb);
182 }
183 
getType(getType_cb _hidl_cb)184 Return<void> StaIface::getType(getType_cb _hidl_cb)
185 {
186 	return validateAndCall(
187 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
188 	    &StaIface::getTypeInternal, _hidl_cb);
189 }
190 
addNetwork(addNetwork_cb _hidl_cb)191 Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
192 {
193 	return validateAndCall(
194 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
195 	    &StaIface::addNetworkInternal, _hidl_cb);
196 }
197 
removeNetwork(SupplicantNetworkId id,removeNetwork_cb _hidl_cb)198 Return<void> StaIface::removeNetwork(
199     SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
200 {
201 	return validateAndCall(
202 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
203 	    &StaIface::removeNetworkInternal, _hidl_cb, id);
204 }
205 
getNetwork(SupplicantNetworkId id,getNetwork_cb _hidl_cb)206 Return<void> StaIface::getNetwork(
207     SupplicantNetworkId id, getNetwork_cb _hidl_cb)
208 {
209 	return validateAndCall(
210 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
211 	    &StaIface::getNetworkInternal, _hidl_cb, id);
212 }
213 
listNetworks(listNetworks_cb _hidl_cb)214 Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb)
215 {
216 	return validateAndCall(
217 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
218 	    &StaIface::listNetworksInternal, _hidl_cb);
219 }
220 
registerCallback(const sp<ISupplicantStaIfaceCallback> & callback,registerCallback_cb _hidl_cb)221 Return<void> StaIface::registerCallback(
222     const sp<ISupplicantStaIfaceCallback>
223     & callback, registerCallback_cb _hidl_cb)
224 {
225 	return validateAndCall(
226 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
227 	    &StaIface::registerCallbackInternal, _hidl_cb, callback);
228 }
229 
registerCallback_1_1(const sp<V1_1::ISupplicantStaIfaceCallback> & callback,registerCallback_cb _hidl_cb)230 Return<void> StaIface::registerCallback_1_1(
231     const sp<V1_1::ISupplicantStaIfaceCallback> &callback,
232     registerCallback_cb _hidl_cb)
233 {
234 	sp<V1_0::ISupplicantStaIfaceCallback> callback_1_0 =  callback;
235 	return validateAndCall(
236 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
237 	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_0);
238 }
239 
reassociate(reassociate_cb _hidl_cb)240 Return<void> StaIface::reassociate(reassociate_cb _hidl_cb)
241 {
242 	return validateAndCall(
243 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
244 	    &StaIface::reassociateInternal, _hidl_cb);
245 }
246 
reconnect(reconnect_cb _hidl_cb)247 Return<void> StaIface::reconnect(reconnect_cb _hidl_cb)
248 {
249 	return validateAndCall(
250 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
251 	    &StaIface::reconnectInternal, _hidl_cb);
252 }
253 
disconnect(disconnect_cb _hidl_cb)254 Return<void> StaIface::disconnect(disconnect_cb _hidl_cb)
255 {
256 	return validateAndCall(
257 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
258 	    &StaIface::disconnectInternal, _hidl_cb);
259 }
260 
setPowerSave(bool enable,setPowerSave_cb _hidl_cb)261 Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
262 {
263 	return validateAndCall(
264 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
265 	    &StaIface::setPowerSaveInternal, _hidl_cb, enable);
266 }
267 
initiateTdlsDiscover(const hidl_array<uint8_t,6> & mac_address,initiateTdlsDiscover_cb _hidl_cb)268 Return<void> StaIface::initiateTdlsDiscover(
269     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb)
270 {
271 	return validateAndCall(
272 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
273 	    &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address);
274 }
275 
initiateTdlsSetup(const hidl_array<uint8_t,6> & mac_address,initiateTdlsSetup_cb _hidl_cb)276 Return<void> StaIface::initiateTdlsSetup(
277     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb)
278 {
279 	return validateAndCall(
280 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
281 	    &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address);
282 }
283 
initiateTdlsTeardown(const hidl_array<uint8_t,6> & mac_address,initiateTdlsTeardown_cb _hidl_cb)284 Return<void> StaIface::initiateTdlsTeardown(
285     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb)
286 {
287 	return validateAndCall(
288 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
289 	    &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address);
290 }
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)291 Return<void> StaIface::initiateAnqpQuery(
292     const hidl_array<uint8_t, 6> &mac_address,
293     const hidl_vec<ISupplicantStaIface::AnqpInfoId> &info_elements,
294     const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types,
295     initiateAnqpQuery_cb _hidl_cb)
296 {
297 	return validateAndCall(
298 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
299 	    &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address,
300 	    info_elements, sub_types);
301 }
302 
initiateHs20IconQuery(const hidl_array<uint8_t,6> & mac_address,const hidl_string & file_name,initiateHs20IconQuery_cb _hidl_cb)303 Return<void> StaIface::initiateHs20IconQuery(
304     const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name,
305     initiateHs20IconQuery_cb _hidl_cb)
306 {
307 	return validateAndCall(
308 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
309 	    &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address,
310 	    file_name);
311 }
312 
getMacAddress(getMacAddress_cb _hidl_cb)313 Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb)
314 {
315 	return validateAndCall(
316 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
317 	    &StaIface::getMacAddressInternal, _hidl_cb);
318 }
319 
startRxFilter(startRxFilter_cb _hidl_cb)320 Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb)
321 {
322 	return validateAndCall(
323 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
324 	    &StaIface::startRxFilterInternal, _hidl_cb);
325 }
326 
stopRxFilter(stopRxFilter_cb _hidl_cb)327 Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb)
328 {
329 	return validateAndCall(
330 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
331 	    &StaIface::stopRxFilterInternal, _hidl_cb);
332 }
333 
addRxFilter(ISupplicantStaIface::RxFilterType type,addRxFilter_cb _hidl_cb)334 Return<void> StaIface::addRxFilter(
335     ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb)
336 {
337 	return validateAndCall(
338 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
339 	    &StaIface::addRxFilterInternal, _hidl_cb, type);
340 }
341 
removeRxFilter(ISupplicantStaIface::RxFilterType type,removeRxFilter_cb _hidl_cb)342 Return<void> StaIface::removeRxFilter(
343     ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb)
344 {
345 	return validateAndCall(
346 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
347 	    &StaIface::removeRxFilterInternal, _hidl_cb, type);
348 }
349 
setBtCoexistenceMode(ISupplicantStaIface::BtCoexistenceMode mode,setBtCoexistenceMode_cb _hidl_cb)350 Return<void> StaIface::setBtCoexistenceMode(
351     ISupplicantStaIface::BtCoexistenceMode mode,
352     setBtCoexistenceMode_cb _hidl_cb)
353 {
354 	return validateAndCall(
355 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
356 	    &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode);
357 }
358 
setBtCoexistenceScanModeEnabled(bool enable,setBtCoexistenceScanModeEnabled_cb _hidl_cb)359 Return<void> StaIface::setBtCoexistenceScanModeEnabled(
360     bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb)
361 {
362 	return validateAndCall(
363 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
364 	    &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb,
365 	    enable);
366 }
367 
setSuspendModeEnabled(bool enable,setSuspendModeEnabled_cb _hidl_cb)368 Return<void> StaIface::setSuspendModeEnabled(
369     bool enable, setSuspendModeEnabled_cb _hidl_cb)
370 {
371 	return validateAndCall(
372 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
373 	    &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable);
374 }
375 
setCountryCode(const hidl_array<int8_t,2> & code,setCountryCode_cb _hidl_cb)376 Return<void> StaIface::setCountryCode(
377     const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb)
378 {
379 	return validateAndCall(
380 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
381 	    &StaIface::setCountryCodeInternal, _hidl_cb, code);
382 }
383 
startWpsRegistrar(const hidl_array<uint8_t,6> & bssid,const hidl_string & pin,startWpsRegistrar_cb _hidl_cb)384 Return<void> StaIface::startWpsRegistrar(
385     const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin,
386     startWpsRegistrar_cb _hidl_cb)
387 {
388 	return validateAndCall(
389 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
390 	    &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin);
391 }
392 
startWpsPbc(const hidl_array<uint8_t,6> & bssid,startWpsPbc_cb _hidl_cb)393 Return<void> StaIface::startWpsPbc(
394     const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb)
395 {
396 	return validateAndCall(
397 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
398 	    &StaIface::startWpsPbcInternal, _hidl_cb, bssid);
399 }
400 
startWpsPinKeypad(const hidl_string & pin,startWpsPinKeypad_cb _hidl_cb)401 Return<void> StaIface::startWpsPinKeypad(
402     const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb)
403 {
404 	return validateAndCall(
405 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
406 	    &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin);
407 }
408 
startWpsPinDisplay(const hidl_array<uint8_t,6> & bssid,startWpsPinDisplay_cb _hidl_cb)409 Return<void> StaIface::startWpsPinDisplay(
410     const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb)
411 {
412 	return validateAndCall(
413 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
414 	    &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid);
415 }
416 
cancelWps(cancelWps_cb _hidl_cb)417 Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb)
418 {
419 	return validateAndCall(
420 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
421 	    &StaIface::cancelWpsInternal, _hidl_cb);
422 }
423 
setWpsDeviceName(const hidl_string & name,setWpsDeviceName_cb _hidl_cb)424 Return<void> StaIface::setWpsDeviceName(
425     const hidl_string &name, setWpsDeviceName_cb _hidl_cb)
426 {
427 	return validateAndCall(
428 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
429 	    &StaIface::setWpsDeviceNameInternal, _hidl_cb, name);
430 }
431 
setWpsDeviceType(const hidl_array<uint8_t,8> & type,setWpsDeviceType_cb _hidl_cb)432 Return<void> StaIface::setWpsDeviceType(
433     const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb)
434 {
435 	return validateAndCall(
436 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
437 	    &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type);
438 }
439 
setWpsManufacturer(const hidl_string & manufacturer,setWpsManufacturer_cb _hidl_cb)440 Return<void> StaIface::setWpsManufacturer(
441     const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb)
442 {
443 	return validateAndCall(
444 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
445 	    &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
446 }
447 
setWpsModelName(const hidl_string & model_name,setWpsModelName_cb _hidl_cb)448 Return<void> StaIface::setWpsModelName(
449     const hidl_string &model_name, setWpsModelName_cb _hidl_cb)
450 {
451 	return validateAndCall(
452 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
453 	    &StaIface::setWpsModelNameInternal, _hidl_cb, model_name);
454 }
455 
setWpsModelNumber(const hidl_string & model_number,setWpsModelNumber_cb _hidl_cb)456 Return<void> StaIface::setWpsModelNumber(
457     const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb)
458 {
459 	return validateAndCall(
460 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
461 	    &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number);
462 }
463 
setWpsSerialNumber(const hidl_string & serial_number,setWpsSerialNumber_cb _hidl_cb)464 Return<void> StaIface::setWpsSerialNumber(
465     const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb)
466 {
467 	return validateAndCall(
468 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
469 	    &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
470 }
471 
setWpsConfigMethods(uint16_t config_methods,setWpsConfigMethods_cb _hidl_cb)472 Return<void> StaIface::setWpsConfigMethods(
473     uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
474 {
475 	return validateAndCall(
476 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
477 	    &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
478 }
479 
setExternalSim(bool useExternalSim,setExternalSim_cb _hidl_cb)480 Return<void> StaIface::setExternalSim(
481     bool useExternalSim, setExternalSim_cb _hidl_cb)
482 {
483 	return validateAndCall(
484 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
485 	    &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim);
486 }
487 
addExtRadioWork(const hidl_string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec,addExtRadioWork_cb _hidl_cb)488 Return<void> StaIface::addExtRadioWork(
489     const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec,
490     addExtRadioWork_cb _hidl_cb)
491 {
492 	return validateAndCall(
493 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
494 	    &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz,
495 	    timeout_in_sec);
496 }
497 
removeExtRadioWork(uint32_t id,removeExtRadioWork_cb _hidl_cb)498 Return<void> StaIface::removeExtRadioWork(
499     uint32_t id, removeExtRadioWork_cb _hidl_cb)
500 {
501 	return validateAndCall(
502 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
503 	    &StaIface::removeExtRadioWorkInternal, _hidl_cb, id);
504 }
505 
enableAutoReconnect(bool enable,enableAutoReconnect_cb _hidl_cb)506 Return<void> StaIface::enableAutoReconnect(
507     bool enable, enableAutoReconnect_cb _hidl_cb)
508 {
509 	return validateAndCall(
510 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
511 	    &StaIface::enableAutoReconnectInternal, _hidl_cb, enable);
512 }
513 
getNameInternal()514 std::pair<SupplicantStatus, std::string> StaIface::getNameInternal()
515 {
516 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
517 }
518 
getTypeInternal()519 std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal()
520 {
521 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
522 }
523 
524 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
addNetworkInternal()525 StaIface::addNetworkInternal()
526 {
527 	android::sp<ISupplicantStaNetwork> network;
528 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
529 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
530 	if (!ssid) {
531 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
532 	}
533 	HidlManager *hidl_manager = HidlManager::getInstance();
534 	if (!hidl_manager ||
535 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
536 		wpa_s->ifname, ssid->id, &network)) {
537 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
538 	}
539 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
540 }
541 
removeNetworkInternal(SupplicantNetworkId id)542 SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id)
543 {
544 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
545 	int result = wpa_supplicant_remove_network(wpa_s, id);
546 	if (result == -1) {
547 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
548 	}
549 	if (result != 0) {
550 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
551 	}
552 	return {SupplicantStatusCode::SUCCESS, ""};
553 }
554 
555 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
getNetworkInternal(SupplicantNetworkId id)556 StaIface::getNetworkInternal(SupplicantNetworkId id)
557 {
558 	android::sp<ISupplicantStaNetwork> network;
559 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
560 	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
561 	if (!ssid) {
562 		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
563 			network};
564 	}
565 	HidlManager *hidl_manager = HidlManager::getInstance();
566 	if (!hidl_manager ||
567 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
568 		wpa_s->ifname, ssid->id, &network)) {
569 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
570 	}
571 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
572 }
573 
574 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
listNetworksInternal()575 StaIface::listNetworksInternal()
576 {
577 	std::vector<SupplicantNetworkId> network_ids;
578 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
579 	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
580 	     wpa_ssid = wpa_ssid->next) {
581 		network_ids.emplace_back(wpa_ssid->id);
582 	}
583 	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
584 }
585 
registerCallbackInternal(const sp<ISupplicantStaIfaceCallback> & callback)586 SupplicantStatus StaIface::registerCallbackInternal(
587     const sp<ISupplicantStaIfaceCallback> &callback)
588 {
589 	HidlManager *hidl_manager = HidlManager::getInstance();
590 	if (!hidl_manager ||
591 	    hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) {
592 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
593 	}
594 	return {SupplicantStatusCode::SUCCESS, ""};
595 }
596 
reassociateInternal()597 SupplicantStatus StaIface::reassociateInternal()
598 {
599 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
600 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
601 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
602 	}
603 	wpas_request_connection(wpa_s);
604 	return {SupplicantStatusCode::SUCCESS, ""};
605 }
606 
reconnectInternal()607 SupplicantStatus StaIface::reconnectInternal()
608 {
609 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
610 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
611 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
612 	}
613 	if (!wpa_s->disconnected) {
614 		return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
615 			""};
616 	}
617 	wpas_request_connection(wpa_s);
618 	return {SupplicantStatusCode::SUCCESS, ""};
619 }
620 
disconnectInternal()621 SupplicantStatus StaIface::disconnectInternal()
622 {
623 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
624 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
625 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
626 	}
627 	wpas_request_disconnection(wpa_s);
628 	return {SupplicantStatusCode::SUCCESS, ""};
629 }
630 
setPowerSaveInternal(bool enable)631 SupplicantStatus StaIface::setPowerSaveInternal(bool enable)
632 {
633 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
634 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
635 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
636 	}
637 	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
638 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
639 	}
640 	return {SupplicantStatusCode::SUCCESS, ""};
641 }
642 
initiateTdlsDiscoverInternal(const std::array<uint8_t,6> & mac_address)643 SupplicantStatus StaIface::initiateTdlsDiscoverInternal(
644     const std::array<uint8_t, 6> &mac_address)
645 {
646 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
647 	int ret;
648 	const u8 *peer = mac_address.data();
649 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
650 		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
651 	} else {
652 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
653 	}
654 	if (ret) {
655 		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
656 	}
657 	return {SupplicantStatusCode::SUCCESS, ""};
658 }
659 
initiateTdlsSetupInternal(const std::array<uint8_t,6> & mac_address)660 SupplicantStatus StaIface::initiateTdlsSetupInternal(
661     const std::array<uint8_t, 6> &mac_address)
662 {
663 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
664 	int ret;
665 	const u8 *peer = mac_address.data();
666 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
667 	    !(wpa_s->conf->tdls_external_control)) {
668 		wpa_tdls_remove(wpa_s->wpa, peer);
669 		ret = wpa_tdls_start(wpa_s->wpa, peer);
670 	} else {
671 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
672 	}
673 	if (ret) {
674 		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
675 	}
676 	return {SupplicantStatusCode::SUCCESS, ""};
677 }
678 
initiateTdlsTeardownInternal(const std::array<uint8_t,6> & mac_address)679 SupplicantStatus StaIface::initiateTdlsTeardownInternal(
680     const std::array<uint8_t, 6> &mac_address)
681 {
682 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
683 	int ret;
684 	const u8 *peer = mac_address.data();
685 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
686 	    !(wpa_s->conf->tdls_external_control)) {
687 		ret = wpa_tdls_teardown_link(
688 		    wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
689 	} else {
690 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
691 	}
692 	if (ret) {
693 		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
694 	}
695 	return {SupplicantStatusCode::SUCCESS, ""};
696 }
697 
initiateAnqpQueryInternal(const std::array<uint8_t,6> & mac_address,const std::vector<ISupplicantStaIface::AnqpInfoId> & info_elements,const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> & sub_types)698 SupplicantStatus StaIface::initiateAnqpQueryInternal(
699     const std::array<uint8_t, 6> &mac_address,
700     const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements,
701     const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types)
702 {
703 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
704 	if (info_elements.size() > kMaxAnqpElems) {
705 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
706 	}
707 	uint16_t info_elems_buf[kMaxAnqpElems];
708 	uint32_t num_info_elems = 0;
709 	for (const auto &info_element : info_elements) {
710 		info_elems_buf[num_info_elems++] =
711 		    static_cast<std::underlying_type<
712 			ISupplicantStaIface::AnqpInfoId>::type>(info_element);
713 	}
714 	uint32_t sub_types_bitmask = 0;
715 	for (const auto &type : sub_types) {
716 		sub_types_bitmask |= BIT(
717 		    static_cast<std::underlying_type<
718 			ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type));
719 	}
720 	if (anqp_send_req(
721 		wpa_s, mac_address.data(), info_elems_buf, num_info_elems,
722 		sub_types_bitmask, false)) {
723 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
724 	}
725 	return {SupplicantStatusCode::SUCCESS, ""};
726 }
727 
initiateHs20IconQueryInternal(const std::array<uint8_t,6> & mac_address,const std::string & file_name)728 SupplicantStatus StaIface::initiateHs20IconQueryInternal(
729     const std::array<uint8_t, 6> &mac_address, const std::string &file_name)
730 {
731 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
732 	wpa_s->fetch_osu_icon_in_progress = 0;
733 	if (hs20_anqp_send_req(
734 		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
735 		reinterpret_cast<const uint8_t *>(file_name.c_str()),
736 		file_name.size(), true)) {
737 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
738 	}
739 	return {SupplicantStatusCode::SUCCESS, ""};
740 }
741 
742 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
getMacAddressInternal()743 StaIface::getMacAddressInternal()
744 {
745 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
746 	std::vector<char> cmd(
747 	    kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
748 	char driver_cmd_reply_buf[4096] = {};
749 	int ret = wpa_drv_driver_cmd(
750 	    wpa_s, cmd.data(), driver_cmd_reply_buf,
751 	    sizeof(driver_cmd_reply_buf));
752 	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
753 	std::string reply_str = driver_cmd_reply_buf;
754 	if (ret < 0 || reply_str.empty() ||
755 	    reply_str.find("=") == std::string::npos) {
756 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
757 	}
758 	// Remove all whitespace first and then split using the delimiter "=".
759 	reply_str.erase(
760 	    remove_if(reply_str.begin(), reply_str.end(), isspace),
761 	    reply_str.end());
762 	std::string mac_addr_str =
763 	    reply_str.substr(reply_str.find("=") + 1, reply_str.size());
764 	std::array<uint8_t, 6> mac_addr;
765 	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
766 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
767 	}
768 	return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr};
769 }
770 
startRxFilterInternal()771 SupplicantStatus StaIface::startRxFilterInternal()
772 {
773 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
774 }
775 
stopRxFilterInternal()776 SupplicantStatus StaIface::stopRxFilterInternal()
777 {
778 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
779 }
780 
addRxFilterInternal(ISupplicantStaIface::RxFilterType type)781 SupplicantStatus StaIface::addRxFilterInternal(
782     ISupplicantStaIface::RxFilterType type)
783 {
784 	return doOneArgDriverCommand(
785 	    retrieveIfacePtr(), kAddRxFilter,
786 	    convertHidlRxFilterTypeToInternal(type));
787 }
788 
removeRxFilterInternal(ISupplicantStaIface::RxFilterType type)789 SupplicantStatus StaIface::removeRxFilterInternal(
790     ISupplicantStaIface::RxFilterType type)
791 {
792 	return doOneArgDriverCommand(
793 	    retrieveIfacePtr(), kRemoveRxFilter,
794 	    convertHidlRxFilterTypeToInternal(type));
795 }
796 
setBtCoexistenceModeInternal(ISupplicantStaIface::BtCoexistenceMode mode)797 SupplicantStatus StaIface::setBtCoexistenceModeInternal(
798     ISupplicantStaIface::BtCoexistenceMode mode)
799 {
800 	return doOneArgDriverCommand(
801 	    retrieveIfacePtr(), kSetBtCoexistenceMode,
802 	    convertHidlBtCoexModeToInternal(mode));
803 }
804 
setBtCoexistenceScanModeEnabledInternal(bool enable)805 SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
806 {
807 	const char *cmd;
808 	if (enable) {
809 		cmd = kSetBtCoexistenceScanStart;
810 	} else {
811 		cmd = kSetBtCoexistenceScanStop;
812 	}
813 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
814 }
815 
setSuspendModeEnabledInternal(bool enable)816 SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable)
817 {
818 	const char *cmd;
819 	if (enable) {
820 		cmd = kSetSupendModeEnabled;
821 	} else {
822 		cmd = kSetSupendModeDisabled;
823 	}
824 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
825 }
826 
setCountryCodeInternal(const std::array<int8_t,2> & code)827 SupplicantStatus StaIface::setCountryCodeInternal(
828     const std::array<int8_t, 2> &code)
829 {
830 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
831 	SupplicantStatus status = doOneArgDriverCommand(
832 	    wpa_s, kSetCountryCode,
833 	    std::string(std::begin(code), std::end(code)));
834 	if (status.code != SupplicantStatusCode::SUCCESS) {
835 		return status;
836 	}
837 	struct p2p_data *p2p = wpa_s->global->p2p;
838 	if (p2p) {
839 		char country[3];
840 		country[0] = code[0];
841 		country[1] = code[1];
842 		country[2] = 0x04;
843 		p2p_set_country(p2p, country);
844 	}
845 	return {SupplicantStatusCode::SUCCESS, ""};
846 }
847 
startWpsRegistrarInternal(const std::array<uint8_t,6> & bssid,const std::string & pin)848 SupplicantStatus StaIface::startWpsRegistrarInternal(
849     const std::array<uint8_t, 6> &bssid, const std::string &pin)
850 {
851 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
852 	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
853 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
854 	}
855 	return {SupplicantStatusCode::SUCCESS, ""};
856 }
857 
startWpsPbcInternal(const std::array<uint8_t,6> & bssid)858 SupplicantStatus StaIface::startWpsPbcInternal(
859     const std::array<uint8_t, 6> &bssid)
860 {
861 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
862 	const uint8_t *bssid_addr =
863 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
864 	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0)) {
865 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
866 	}
867 	return {SupplicantStatusCode::SUCCESS, ""};
868 }
869 
startWpsPinKeypadInternal(const std::string & pin)870 SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
871 {
872 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
873 	if (wpas_wps_start_pin(
874 		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
875 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
876 	}
877 	return {SupplicantStatusCode::SUCCESS, ""};
878 }
879 
startWpsPinDisplayInternal(const std::array<uint8_t,6> & bssid)880 std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal(
881     const std::array<uint8_t, 6> &bssid)
882 {
883 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
884 	const uint8_t *bssid_addr =
885 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
886 	int pin =
887 	    wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
888 	if (pin < 0) {
889 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
890 	}
891 	return {{SupplicantStatusCode::SUCCESS, ""},
892 		misc_utils::convertWpsPinToString(pin)};
893 }
894 
cancelWpsInternal()895 SupplicantStatus StaIface::cancelWpsInternal()
896 {
897 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
898 	if (wpas_wps_cancel(wpa_s)) {
899 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
900 	}
901 	return {SupplicantStatusCode::SUCCESS, ""};
902 }
903 
setWpsDeviceNameInternal(const std::string & name)904 SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
905 {
906 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
907 }
908 
setWpsDeviceTypeInternal(const std::array<uint8_t,8> & type)909 SupplicantStatus StaIface::setWpsDeviceTypeInternal(
910     const std::array<uint8_t, 8> &type)
911 {
912 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
913 }
914 
setWpsManufacturerInternal(const std::string & manufacturer)915 SupplicantStatus StaIface::setWpsManufacturerInternal(
916     const std::string &manufacturer)
917 {
918 	return iface_config_utils::setWpsManufacturer(
919 	    retrieveIfacePtr(), manufacturer);
920 }
921 
setWpsModelNameInternal(const std::string & model_name)922 SupplicantStatus StaIface::setWpsModelNameInternal(
923     const std::string &model_name)
924 {
925 	return iface_config_utils::setWpsModelName(
926 	    retrieveIfacePtr(), model_name);
927 }
928 
setWpsModelNumberInternal(const std::string & model_number)929 SupplicantStatus StaIface::setWpsModelNumberInternal(
930     const std::string &model_number)
931 {
932 	return iface_config_utils::setWpsModelNumber(
933 	    retrieveIfacePtr(), model_number);
934 }
935 
setWpsSerialNumberInternal(const std::string & serial_number)936 SupplicantStatus StaIface::setWpsSerialNumberInternal(
937     const std::string &serial_number)
938 {
939 	return iface_config_utils::setWpsSerialNumber(
940 	    retrieveIfacePtr(), serial_number);
941 }
942 
setWpsConfigMethodsInternal(uint16_t config_methods)943 SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods)
944 {
945 	return iface_config_utils::setWpsConfigMethods(
946 	    retrieveIfacePtr(), config_methods);
947 }
948 
setExternalSimInternal(bool useExternalSim)949 SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim)
950 {
951 	return iface_config_utils::setExternalSim(
952 	    retrieveIfacePtr(), useExternalSim);
953 }
954 
addExtRadioWorkInternal(const std::string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec)955 std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal(
956     const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
957 {
958 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
959 	auto *ework = static_cast<struct wpa_external_work *>(
960 	    os_zalloc(sizeof(struct wpa_external_work)));
961 	if (!ework) {
962 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
963 			UINT32_MAX};
964 	}
965 
966 	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
967 	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
968 	ework->timeout = timeout_in_sec;
969 	wpa_s->ext_work_id++;
970 	if (wpa_s->ext_work_id == 0) {
971 		wpa_s->ext_work_id++;
972 	}
973 	ework->id = wpa_s->ext_work_id;
974 
975 	if (radio_add_work(
976 		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
977 		ework)) {
978 		os_free(ework);
979 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
980 			UINT32_MAX};
981 	}
982 	return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id};
983 }
984 
removeExtRadioWorkInternal(uint32_t id)985 SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
986 {
987 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
988 	struct wpa_radio_work *work;
989 	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
990 	{
991 		if (os_strncmp(
992 			work->type, kExtRadioWorkNamePrefix,
993 			sizeof(kExtRadioWorkNamePrefix)) != 0)
994 			continue;
995 
996 		auto *ework =
997 		    static_cast<struct wpa_external_work *>(work->ctx);
998 		if (ework->id != id)
999 			continue;
1000 
1001 		wpa_dbg(
1002 		    wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
1003 		    ework->id, ework->type);
1004 		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
1005 		endExtRadioWork(work);
1006 
1007 		return {SupplicantStatusCode::SUCCESS, ""};
1008 	}
1009 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1010 }
1011 
enableAutoReconnectInternal(bool enable)1012 SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable)
1013 {
1014 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1015 	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
1016 	return {SupplicantStatusCode::SUCCESS, ""};
1017 }
1018 
1019 /**
1020  * Retrieve the underlying |wpa_supplicant| struct
1021  * pointer for this iface.
1022  * If the underlying iface is removed, then all RPC method calls on this object
1023  * will return failure.
1024  */
retrieveIfacePtr()1025 wpa_supplicant *StaIface::retrieveIfacePtr()
1026 {
1027 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1028 }
1029 }  // namespace implementation
1030 }  // namespace V1_1
1031 }  // namespace wifi
1032 }  // namespace supplicant
1033 }  // namespace hardware
1034 }  // namespace android
1035