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