• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - Manager for Aidl interface objects
3  * Copyright (c) 2021, Google Inc. All rights reserved.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include <algorithm>
10 #include <functional>
11 #include <iostream>
12 #include <regex>
13 
14 #include "aidl_manager.h"
15 #include "misc_utils.h"
16 #include <android/binder_process.h>
17 #include <android/binder_manager.h>
18 #include <aidl/android/hardware/wifi/supplicant/IpVersion.h>
19 #include <cutils/properties.h>
20 
21 extern "C" {
22 #include "scan.h"
23 #include "src/eap_common/eap_sim_common.h"
24 #include "list.h"
25 }
26 
27 namespace {
28 
29 constexpr uint8_t kWfdDeviceInfoLen = 6;
30 constexpr uint8_t kWfdR2DeviceInfoLen = 2;
31 // GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>]
32 constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)";
33 constexpr char kGsmAuthRegex3[] =
34 	"GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)";
35 // UMTS-AUTH:<RAND>:<AUTN>
36 constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)";
37 constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN;
38 constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
39 constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
40 const std::vector<uint8_t> kZeroBssid = {0, 0, 0, 0, 0, 0};
41 int32_t aidl_service_version = 0;
42 int32_t aidl_client_version = 0;
43 
44 using aidl::android::hardware::wifi::supplicant::GsmRand;
45 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
46 
47 /**
48  * Check if the provided |wpa_supplicant| structure represents a P2P iface or
49  * not.
50  */
isP2pIface(const struct wpa_supplicant * wpa_s)51 constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s)
52 {
53 	return wpa_s->global->p2p_init_wpa_s == wpa_s;
54 }
55 
56 /**
57  * Creates a unique key for the network using the provided |ifname| and
58  * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
59  * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
60  *
61  * @param ifname Name of the corresponding interface.
62  * @param network_id ID of the corresponding network.
63  */
getNetworkObjectMapKey(const std::string & ifname,int network_id)64 const std::string getNetworkObjectMapKey(
65 	const std::string &ifname, int network_id)
66 {
67 	return ifname + "_" + std::to_string(network_id);
68 }
69 
70 /**
71  * Add callback to the corresponding list after linking to death on the
72  * corresponding aidl object reference.
73  */
74 template <class CallbackType>
registerForDeathAndAddCallbackAidlObjectToList(AIBinder_DeathRecipient * death_notifier,const std::shared_ptr<CallbackType> & callback,std::vector<std::shared_ptr<CallbackType>> & callback_list)75 int registerForDeathAndAddCallbackAidlObjectToList(
76 	AIBinder_DeathRecipient* death_notifier,
77 	const std::shared_ptr<CallbackType> &callback,
78 	std::vector<std::shared_ptr<CallbackType>> &callback_list)
79 {
80 	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
81 			death_notifier, nullptr /* cookie */);
82 	if (status != STATUS_OK) {
83 		wpa_printf(
84 			MSG_ERROR,
85 			"Error registering for death notification for "
86 			"supplicant callback object");
87 		return 1;
88 	}
89 	callback_list.push_back(callback);
90 	if (aidl_client_version == 0) {
91 	    callback->getInterfaceVersion(&aidl_client_version);
92 	    wpa_printf(MSG_INFO, "AIDL client version: %d", aidl_client_version);
93 	}
94 	return 0;
95 }
96 
97 template <class ObjectType>
addAidlObjectToMap(const std::string & key,const std::shared_ptr<ObjectType> & object,std::map<const std::string,std::shared_ptr<ObjectType>> & object_map)98 int addAidlObjectToMap(
99 	const std::string &key, const std::shared_ptr<ObjectType> &object,
100 	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
101 {
102 	// Return failure if we already have an object for that |key|.
103 	if (object_map.find(key) != object_map.end())
104 		return 1;
105 	object_map[key] = object;
106 	if (!object_map[key].get())
107 		return 1;
108 	return 0;
109 }
110 
111 template <class ObjectType>
removeAidlObjectFromMap(const std::string & key,std::map<const std::string,std::shared_ptr<ObjectType>> & object_map)112 int removeAidlObjectFromMap(
113 	const std::string &key,
114 	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
115 {
116 	// Return failure if we dont have an object for that |key|.
117 	const auto &object_iter = object_map.find(key);
118 	if (object_iter == object_map.end())
119 		return 1;
120 	object_iter->second->invalidate();
121 	object_map.erase(object_iter);
122 	return 0;
123 }
124 
125 template <class CallbackType>
addIfaceCallbackAidlObjectToMap(AIBinder_DeathRecipient * death_notifier,const std::string & ifname,const std::shared_ptr<CallbackType> & callback,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)126 int addIfaceCallbackAidlObjectToMap(
127 	AIBinder_DeathRecipient* death_notifier,
128 	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
129 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
130 	&callbacks_map)
131 {
132 	if (ifname.empty())
133 		return 1;
134 
135 	auto iface_callback_map_iter = callbacks_map.find(ifname);
136 	if (iface_callback_map_iter == callbacks_map.end())
137 		return 1;
138 	auto &iface_callback_list = iface_callback_map_iter->second;
139 
140 	// Register for death notification before we add it to our list.
141 	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
142 		death_notifier, callback, iface_callback_list);
143 }
144 
145 template <class CallbackType>
addNetworkCallbackAidlObjectToMap(AIBinder_DeathRecipient * death_notifier,const std::string & ifname,int network_id,const std::shared_ptr<CallbackType> & callback,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)146 int addNetworkCallbackAidlObjectToMap(
147 	AIBinder_DeathRecipient* death_notifier,
148 	const std::string &ifname, int network_id,
149 	const std::shared_ptr<CallbackType> &callback,
150 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
151 	&callbacks_map)
152 {
153 	if (ifname.empty() || network_id < 0)
154 		return 1;
155 
156 	// Generate the key to be used to lookup the network.
157 	const std::string network_key =
158 		getNetworkObjectMapKey(ifname, network_id);
159 	auto network_callback_map_iter = callbacks_map.find(network_key);
160 	if (network_callback_map_iter == callbacks_map.end())
161 		return 1;
162 	auto &network_callback_list = network_callback_map_iter->second;
163 
164 	// Register for death notification before we add it to our list.
165 	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
166 		death_notifier, callback, network_callback_list);
167 }
168 
169 template <class CallbackType>
removeAllIfaceCallbackAidlObjectsFromMap(AIBinder_DeathRecipient * death_notifier,const std::string & ifname,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)170 int removeAllIfaceCallbackAidlObjectsFromMap(
171 	AIBinder_DeathRecipient* death_notifier,
172 	const std::string &ifname,
173 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
174 	&callbacks_map)
175 {
176 	auto iface_callback_map_iter = callbacks_map.find(ifname);
177 	if (iface_callback_map_iter == callbacks_map.end())
178 		return 1;
179 	const auto &iface_callback_list = iface_callback_map_iter->second;
180 	for (const auto &callback : iface_callback_list) {
181 		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
182 				death_notifier, nullptr /* cookie */);
183 		if (status != STATUS_OK) {
184 			wpa_printf(
185 				MSG_ERROR,
186 				"Error deregistering for death notification for "
187 				"iface callback object");
188 		}
189 	}
190 	callbacks_map.erase(iface_callback_map_iter);
191 	return 0;
192 }
193 
194 template <class CallbackType>
removeAllNetworkCallbackAidlObjectsFromMap(AIBinder_DeathRecipient * death_notifier,const std::string & network_key,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)195 int removeAllNetworkCallbackAidlObjectsFromMap(
196 	AIBinder_DeathRecipient* death_notifier,
197 	const std::string &network_key,
198 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
199 	&callbacks_map)
200 {
201 	auto network_callback_map_iter = callbacks_map.find(network_key);
202 	if (network_callback_map_iter == callbacks_map.end())
203 		return 1;
204 	const auto &network_callback_list = network_callback_map_iter->second;
205 	for (const auto &callback : network_callback_list) {
206 		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
207 				death_notifier, nullptr /* cookie */);
208 		if (status != STATUS_OK) {
209 			wpa_printf(
210 				MSG_ERROR,
211 				"Error deregistering for death "
212 				"notification for "
213 				"network callback object");
214 		}
215 	}
216 	callbacks_map.erase(network_callback_map_iter);
217 	return 0;
218 }
219 
220 template <class CallbackType>
removeIfaceCallbackAidlObjectFromMap(const std::string & ifname,const std::shared_ptr<CallbackType> & callback,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)221 void removeIfaceCallbackAidlObjectFromMap(
222 	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
223 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
224 	&callbacks_map)
225 {
226 	if (ifname.empty())
227 		return;
228 
229 	auto iface_callback_map_iter = callbacks_map.find(ifname);
230 	if (iface_callback_map_iter == callbacks_map.end())
231 		return;
232 
233 	auto &iface_callback_list = iface_callback_map_iter->second;
234 	iface_callback_list.erase(
235 		std::remove(
236 		iface_callback_list.begin(), iface_callback_list.end(),
237 		callback),
238 		iface_callback_list.end());
239 }
240 
241 template <class CallbackType>
removeNetworkCallbackAidlObjectFromMap(const std::string & ifname,int network_id,const std::shared_ptr<CallbackType> & callback,std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)242 void removeNetworkCallbackAidlObjectFromMap(
243 	const std::string &ifname, int network_id,
244 	const std::shared_ptr<CallbackType> &callback,
245 	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
246 	&callbacks_map)
247 {
248 	if (ifname.empty() || network_id < 0)
249 		return;
250 
251 	// Generate the key to be used to lookup the network.
252 	const std::string network_key =
253 		getNetworkObjectMapKey(ifname, network_id);
254 
255 	auto network_callback_map_iter = callbacks_map.find(network_key);
256 	if (network_callback_map_iter == callbacks_map.end())
257 		return;
258 
259 	auto &network_callback_list = network_callback_map_iter->second;
260 	network_callback_list.erase(
261 		std::remove(
262 		network_callback_list.begin(), network_callback_list.end(),
263 		callback),
264 		network_callback_list.end());
265 }
266 
267 template <class CallbackType>
callWithEachIfaceCallback(const std::string & ifname,const std::function<ndk::ScopedAStatus (std::shared_ptr<CallbackType>)> & method,const std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)268 void callWithEachIfaceCallback(
269 	const std::string &ifname,
270 	const std::function<ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
271 	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
272 	&callbacks_map)
273 {
274 	if (ifname.empty())
275 		return;
276 
277 	auto iface_callback_map_iter = callbacks_map.find(ifname);
278 	if (iface_callback_map_iter == callbacks_map.end())
279 		return;
280 	const auto &iface_callback_list = iface_callback_map_iter->second;
281 	for (const auto &callback : iface_callback_list) {
282 		if (!method(callback).isOk()) {
283 			wpa_printf(
284 				MSG_ERROR, "Failed to invoke AIDL iface callback");
285 		}
286 	}
287 }
288 
289 template <class CallbackType>
callWithEachNetworkCallback(const std::string & ifname,int network_id,const std::function<ndk::ScopedAStatus (std::shared_ptr<CallbackType>)> & method,const std::map<const std::string,std::vector<std::shared_ptr<CallbackType>>> & callbacks_map)290 void callWithEachNetworkCallback(
291 	const std::string &ifname, int network_id,
292 	const std::function<
293 	ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
294 	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
295 	&callbacks_map)
296 {
297 	if (ifname.empty() || network_id < 0)
298 		return;
299 
300 	// Generate the key to be used to lookup the network.
301 	const std::string network_key =
302 		getNetworkObjectMapKey(ifname, network_id);
303 	auto network_callback_map_iter = callbacks_map.find(network_key);
304 	if (network_callback_map_iter == callbacks_map.end())
305 		return;
306 	const auto &network_callback_list = network_callback_map_iter->second;
307 	for (const auto &callback : network_callback_list) {
308 		if (!method(callback).isOk()) {
309 			wpa_printf(
310 				MSG_ERROR,
311 				"Failed to invoke AIDL network callback");
312 		}
313 	}
314 }
315 
parseGsmAuthNetworkRequest(const std::string & params_str,std::vector<GsmRand> * out_rands)316 int parseGsmAuthNetworkRequest(
317 	const std::string &params_str,
318 	std::vector<GsmRand> *out_rands)
319 {
320 	std::smatch matches;
321 	std::regex params_gsm_regex2(kGsmAuthRegex2);
322 	std::regex params_gsm_regex3(kGsmAuthRegex3);
323 	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
324 		!std::regex_match(params_str, matches, params_gsm_regex2)) {
325 		return 1;
326 	}
327 	for (uint32_t i = 1; i < matches.size(); i++) {
328 		GsmRand rand;
329 		rand.data = std::vector<uint8_t>(kGsmRandLenBytes);
330 		const auto &match = matches[i];
331 		WPA_ASSERT(match.size() >= 2 * rand.data.size());
332 		if (hexstr2bin(match.str().c_str(), rand.data.data(), rand.data.size())) {
333 			wpa_printf(MSG_ERROR, "Failed to parse GSM auth params");
334 			return 1;
335 		}
336 		out_rands->push_back(rand);
337 	}
338 	return 0;
339 }
340 
parseUmtsAuthNetworkRequest(const std::string & params_str,std::vector<uint8_t> * out_rand,std::vector<uint8_t> * out_autn)341 int parseUmtsAuthNetworkRequest(
342 	const std::string &params_str,
343 	std::vector<uint8_t> *out_rand,
344 	std::vector<uint8_t> *out_autn)
345 {
346 	std::smatch matches;
347 	std::regex params_umts_regex(kUmtsAuthRegex);
348 	if (!std::regex_match(params_str, matches, params_umts_regex)) {
349 		return 1;
350 	}
351 	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
352 	if (hexstr2bin(
353 		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
354 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
355 		return 1;
356 	}
357 	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
358 	if (hexstr2bin(
359 		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
360 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
361 		return 1;
362 	}
363 	return 0;
364 }
365 
byteArrToVec(const uint8_t * arr,int len)366 inline std::vector<uint8_t> byteArrToVec(const uint8_t* arr, int len) {
367 	return std::vector<uint8_t>{arr, arr + len};
368 }
369 
macAddrToVec(const uint8_t * mac_addr)370 inline std::vector<uint8_t> macAddrToVec(const uint8_t* mac_addr) {
371 	return byteArrToVec(mac_addr, ETH_ALEN);
372 }
373 
macAddrToArray(const uint8_t * mac_addr)374 inline std::array<uint8_t, ETH_ALEN> macAddrToArray(const uint8_t* mac_addr) {
375 	std::array<uint8_t, ETH_ALEN> arr;
376 	std::copy(mac_addr, mac_addr + ETH_ALEN, std::begin(arr));
377 	return arr;
378 }
379 
380 // Raw pointer to the global structure maintained by the core.
381 // Declared here to be accessible to onDeath()
382 struct wpa_global *wpa_global_;
383 
onDeath(void * cookie)384 void onDeath(void* cookie) {
385 	wpa_printf(MSG_ERROR, "Client died. Terminating...");
386 	wpa_supplicant_terminate_proc(wpa_global_);
387 }
388 
389 }  // namespace
390 
391 namespace aidl {
392 namespace android {
393 namespace hardware {
394 namespace wifi {
395 namespace supplicant {
396 
397 AidlManager *AidlManager::instance_ = NULL;
398 
getInstance()399 AidlManager *AidlManager::getInstance()
400 {
401 	if (!instance_)
402 		instance_ = new AidlManager();
403 	return instance_;
404 }
405 
destroyInstance()406 void AidlManager::destroyInstance()
407 {
408 	if (instance_)
409 		delete instance_;
410 	instance_ = NULL;
411 }
412 
413 /**
414  * Check that the AIDL service is running at least the expected version.
415  * Use to avoid the case where the AIDL interface version
416  * is greater than the version implemented by the service.
417  */
isAidlServiceVersionAtLeast(int32_t expected_version)418 int32_t AidlManager::isAidlServiceVersionAtLeast(int32_t expected_version)
419 {
420 	return expected_version <= aidl_service_version;
421 }
422 
isAidlClientVersionAtLeast(int32_t expected_version)423 int32_t AidlManager::isAidlClientVersionAtLeast(int32_t expected_version)
424 {
425 	return expected_version <= aidl_client_version;
426 }
427 
registerAidlService(struct wpa_global * global)428 int AidlManager::registerAidlService(struct wpa_global *global)
429 {
430 	// Create the main aidl service object and register it.
431 	wpa_printf(MSG_INFO, "Starting AIDL supplicant");
432 	supplicant_object_ = ndk::SharedRefBase::make<Supplicant>(global);
433 	if (!supplicant_object_->getInterfaceVersion(&aidl_service_version).isOk()) {
434 		aidl_service_version = Supplicant::version;
435 	}
436 	wpa_printf(MSG_INFO, "AIDL Interface version: %d", aidl_service_version);
437 	wpa_global_ = global;
438 	std::string instance = std::string() + Supplicant::descriptor + "/default";
439 	if (AServiceManager_addService(supplicant_object_->asBinder().get(),
440 			instance.c_str()) != STATUS_OK)
441 	{
442 		return 1;
443 	}
444 
445 	// Initialize the death notifier.
446 	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
447 	return 0;
448 }
449 
450 /**
451  * Register an interface to aidl manager.
452  *
453  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
454  *
455  * @return 0 on success, 1 on failure.
456  */
registerInterface(struct wpa_supplicant * wpa_s)457 int AidlManager::registerInterface(struct wpa_supplicant *wpa_s)
458 {
459 	if (!wpa_s)
460 		return 1;
461 
462 	if (isP2pIface(wpa_s)) {
463 		if (addAidlObjectToMap<P2pIface>(
464 			wpa_s->ifname,
465 			ndk::SharedRefBase::make<P2pIface>(wpa_s->global, wpa_s->ifname),
466 			p2p_iface_object_map_)) {
467 			wpa_printf(
468 				MSG_ERROR,
469 				"Failed to register P2P interface with AIDL "
470 				"control: %s",
471 				wpa_s->ifname);
472 			return 1;
473 		}
474 		p2p_iface_callbacks_map_[wpa_s->ifname] =
475 			std::vector<std::shared_ptr<ISupplicantP2pIfaceCallback>>();
476 	} else {
477 		if (addAidlObjectToMap<StaIface>(
478 			wpa_s->ifname,
479 			ndk::SharedRefBase::make<StaIface>(wpa_s->global, wpa_s->ifname),
480 			sta_iface_object_map_)) {
481 			wpa_printf(
482 				MSG_ERROR,
483 				"Failed to register STA interface with AIDL "
484 				"control: %s",
485 				wpa_s->ifname);
486 			return 1;
487 		}
488 		sta_iface_callbacks_map_[wpa_s->ifname] =
489 			std::vector<std::shared_ptr<ISupplicantStaIfaceCallback>>();
490 		// Turn on Android specific customizations for STA interfaces
491 		// here!
492 		//
493 		// Turn on scan mac randomization only if driver supports.
494 		if (wpa_s->mac_addr_rand_supported & MAC_ADDR_RAND_SCAN) {
495 			if (wpas_mac_addr_rand_scan_set(
496 				wpa_s, MAC_ADDR_RAND_SCAN, nullptr, nullptr)) {
497 				wpa_printf(
498 					MSG_ERROR,
499 					"Failed to enable scan mac randomization");
500 			}
501 		}
502 
503 		// Enable randomized source MAC address for GAS/ANQP
504 		// Set the lifetime to 0, guarantees a unique address for each GAS
505 		// session
506 		wpa_s->conf->gas_rand_mac_addr = WPAS_MAC_ADDR_STYLE_RANDOM;
507 		wpa_s->conf->gas_rand_addr_lifetime = 0;
508 	}
509 
510 	// Invoke the |onInterfaceCreated| method on all registered callbacks.
511 	callWithEachSupplicantCallback(std::bind(
512 		&ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
513 		misc_utils::charBufToString(wpa_s->ifname)));
514 	return 0;
515 }
516 
517 /**
518  * Unregister an interface from aidl manager.
519  *
520  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
521  *
522  * @return 0 on success, 1 on failure.
523  */
unregisterInterface(struct wpa_supplicant * wpa_s)524 int AidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
525 {
526 	if (!wpa_s)
527 		return 1;
528 
529 	// Check if this interface is present in P2P map first, else check in
530 	// STA map.
531 	// Note: We can't use isP2pIface() here because interface
532 	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
533 	// function is cleared by the core before notifying the AIDL interface.
534 	bool success =
535 		!removeAidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
536 	if (success) {  // assumed to be P2P
537 		success = !removeAllIfaceCallbackAidlObjectsFromMap(
538 			death_notifier_, wpa_s->ifname, p2p_iface_callbacks_map_);
539 	} else {  // assumed to be STA
540 		success = !removeAidlObjectFromMap(
541 			wpa_s->ifname, sta_iface_object_map_);
542 		if (success) {
543 			success = !removeAllIfaceCallbackAidlObjectsFromMap(
544 				death_notifier_, wpa_s->ifname, sta_iface_callbacks_map_);
545 		}
546 	}
547 	if (!success) {
548 		wpa_printf(
549 			MSG_ERROR,
550 			"Failed to unregister interface with AIDL "
551 			"control: %s",
552 			wpa_s->ifname);
553 		return 1;
554 	}
555 
556 	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
557 	callWithEachSupplicantCallback(std::bind(
558 		&ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
559 		misc_utils::charBufToString(wpa_s->ifname)));
560 	return 0;
561 }
562 
563 /**
564  * Register a network to aidl manager.
565  *
566  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
567  * the network is added.
568  * @param ssid |wpa_ssid| struct corresponding to the network being added.
569  *
570  * @return 0 on success, 1 on failure.
571  */
registerNetwork(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)572 int AidlManager::registerNetwork(
573 	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
574 {
575 	if (!wpa_s || !ssid)
576 		return 1;
577 
578 	// Generate the key to be used to lookup the network.
579 	const std::string network_key =
580 		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
581 
582 	if (isP2pIface(wpa_s)) {
583 		if (addAidlObjectToMap<P2pNetwork>(
584 			network_key,
585 			ndk::SharedRefBase::make<P2pNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
586 			p2p_network_object_map_)) {
587 			wpa_printf(
588 				MSG_ERROR,
589 				"Failed to register P2P network with AIDL "
590 				"control: %d",
591 				ssid->id);
592 			return 1;
593 		}
594 	} else {
595 		if (addAidlObjectToMap<StaNetwork>(
596 			network_key,
597 			ndk::SharedRefBase::make<StaNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
598 			sta_network_object_map_)) {
599 			wpa_printf(
600 				MSG_ERROR,
601 				"Failed to register STA network with AIDL "
602 				"control: %d",
603 				ssid->id);
604 			return 1;
605 		}
606 		sta_network_callbacks_map_[network_key] =
607 			std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>();
608 		// Invoke the |onNetworkAdded| method on all registered
609 		// callbacks.
610 		callWithEachStaIfaceCallback(
611 			misc_utils::charBufToString(wpa_s->ifname),
612 			std::bind(
613 			&ISupplicantStaIfaceCallback::onNetworkAdded,
614 			std::placeholders::_1, ssid->id));
615 	}
616 	return 0;
617 }
618 
619 /**
620  * Unregister a network from aidl manager.
621  *
622  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
623  * the network is added.
624  * @param ssid |wpa_ssid| struct corresponding to the network being added.
625  *
626  * @return 0 on success, 1 on failure.
627  */
unregisterNetwork(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)628 int AidlManager::unregisterNetwork(
629 	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
630 {
631 	if (!wpa_s || !ssid)
632 		return 1;
633 
634 	// Generate the key to be used to lookup the network.
635 	const std::string network_key =
636 		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
637 
638 	if (isP2pIface(wpa_s)) {
639 		if (removeAidlObjectFromMap(
640 			network_key, p2p_network_object_map_)) {
641 			wpa_printf(
642 				MSG_ERROR,
643 				"Failed to unregister P2P network with AIDL "
644 				"control: %d",
645 				ssid->id);
646 			return 1;
647 		}
648 	} else {
649 		if (removeAidlObjectFromMap(
650 			network_key, sta_network_object_map_)) {
651 			wpa_printf(
652 				MSG_ERROR,
653 				"Failed to unregister STA network with AIDL "
654 				"control: %d",
655 				ssid->id);
656 			return 1;
657 		}
658 		if (removeAllNetworkCallbackAidlObjectsFromMap(
659 			death_notifier_, network_key, sta_network_callbacks_map_)) {
660 			return 1;
661 		}
662 
663 		// Invoke the |onNetworkRemoved| method on all registered
664 		// callbacks.
665 		callWithEachStaIfaceCallback(
666 			misc_utils::charBufToString(wpa_s->ifname),
667 			std::bind(
668 			&ISupplicantStaIfaceCallback::onNetworkRemoved,
669 			std::placeholders::_1, ssid->id));
670 	}
671 	return 0;
672 }
673 
674 // Some of the undefined AKMs in AIDL (Mostly extension AKMs like FT AKMs)
675 // are mapped to the main AKM. This is for the framework to map the AKM to
676 // correct security type.
convertSupplicantSelectedKeyMgmtForConnectionToAidl(int key_mgmt)677 KeyMgmtMask convertSupplicantSelectedKeyMgmtForConnectionToAidl(int key_mgmt)
678 {
679 	switch (key_mgmt) {
680 		case WPA_KEY_MGMT_IEEE8021X:
681 			return KeyMgmtMask::WPA_EAP;
682 		case WPA_KEY_MGMT_PSK:
683 			return KeyMgmtMask::WPA_PSK;
684 		case WPA_KEY_MGMT_NONE:
685 			return KeyMgmtMask::NONE;
686 		case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
687 			return KeyMgmtMask::IEEE8021X;
688 		case WPA_KEY_MGMT_FT_IEEE8021X:
689 			return KeyMgmtMask::FT_EAP;
690 		case WPA_KEY_MGMT_FT_PSK:
691 			return KeyMgmtMask::FT_PSK;
692 		case WPA_KEY_MGMT_IEEE8021X_SHA256:
693 			return KeyMgmtMask::WPA_EAP_SHA256;
694 		case WPA_KEY_MGMT_PSK_SHA256:
695 			return KeyMgmtMask::WPA_PSK_SHA256;
696 		case WPA_KEY_MGMT_SAE:
697 		case WPA_KEY_MGMT_FT_SAE:
698 		case WPA_KEY_MGMT_SAE_EXT_KEY:
699 		case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
700 			return KeyMgmtMask::SAE;
701 		case WPA_KEY_MGMT_WAPI_PSK:
702 			return KeyMgmtMask::WAPI_PSK;
703 		case WPA_KEY_MGMT_WAPI_CERT:
704 			return KeyMgmtMask::WAPI_CERT;
705 		case WPA_KEY_MGMT_OSEN:
706 			return KeyMgmtMask::OSEN;
707 		case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
708 		case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
709 			return KeyMgmtMask::SUITE_B_192;
710 		case WPA_KEY_MGMT_FILS_SHA256:
711 		case WPA_KEY_MGMT_FT_FILS_SHA256:
712 			return KeyMgmtMask::FILS_SHA256;
713 		case WPA_KEY_MGMT_FILS_SHA384:
714 		case WPA_KEY_MGMT_FT_FILS_SHA384:
715 			return KeyMgmtMask::FILS_SHA384;
716 		case WPA_KEY_MGMT_OWE:
717 			return KeyMgmtMask::OWE;
718 		case WPA_KEY_MGMT_DPP:
719 			return KeyMgmtMask::DPP;
720 		default:
721 			wpa_printf(MSG_INFO, "Unable to convert supplicant key_mgmt 0x%x to AIDL",
722 				    key_mgmt);
723 			return (KeyMgmtMask) key_mgmt;
724 	}
725 }
726 
727 /**
728  * Notify all listeners about any state changes on a particular interface.
729  *
730  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
731  * the state change event occured.
732  */
notifyStateChange(struct wpa_supplicant * wpa_s)733 int AidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
734 {
735 	if (!wpa_s)
736 		return 1;
737 
738 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
739 		sta_iface_object_map_.end())
740 		return 1;
741 
742 	// Invoke the |onStateChanged| method on all registered callbacks.
743 	SupplicantStateChangeData aidl_state_change_data = {};
744 	aidl_state_change_data.id = UINT32_MAX;
745 	aidl_state_change_data.newState = static_cast<StaIfaceCallbackState>(wpa_s->wpa_state);
746 
747 	if (wpa_s->current_ssid) {
748 		aidl_state_change_data.id = wpa_s->current_ssid->id;
749 		std::vector<uint8_t> aidl_ssid(
750 			wpa_s->current_ssid->ssid,
751 			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
752 		aidl_state_change_data.ssid = aidl_ssid;
753 		wpa_printf(MSG_INFO, "assoc key_mgmt 0x%x network key_mgmt 0x%x",
754 			wpa_s->key_mgmt, wpa_s->current_ssid->key_mgmt);
755 	}
756 	std::array<uint8_t, ETH_ALEN> aidl_bssid;
757 	// wpa_supplicant sets the |pending_bssid| field when it starts a
758 	// connection. Only after association state does it update the |bssid|
759 	// field. So, in the AIDL callback send the appropriate bssid.
760 	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
761 		aidl_bssid = macAddrToArray(wpa_s->pending_bssid);
762 	} else {
763 		aidl_bssid = macAddrToArray(wpa_s->bssid);
764 	}
765 	aidl_state_change_data.bssid = aidl_bssid;
766 
767 	aidl_state_change_data.filsHlpSent =
768 		(wpa_auth_alg_fils(wpa_s->auth_alg) &&
769 		 !dl_list_empty(&wpa_s->fils_hlp_req) &&
770 		 (wpa_s->wpa_state == WPA_COMPLETED)) ? true : false;
771 	if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
772 		// wpa_supplicant sets the frequency on receiving the EVENT_ASSOC.
773 		aidl_state_change_data.frequencyMhz = wpa_s->assoc_freq;
774 		// The key_mgmt is selected prior to sending the connect command
775 		// to driver. But in case of CROSS-AKM Connection/Roaming, the
776 		// key_mgmt is updated with the one from association IE. So the
777 		// selected key_mgmt is accurate only after moving to
778 		// associated state.
779 		aidl_state_change_data.keyMgmtMask =
780 			convertSupplicantSelectedKeyMgmtForConnectionToAidl(wpa_s->key_mgmt);
781 	}
782 
783 	// Invoke the |onStateChanged| method on all registered callbacks.
784 	std::function<
785 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
786 		func = std::bind(
787 			&ISupplicantStaIfaceCallback::onSupplicantStateChanged,
788 			std::placeholders::_1,
789 			aidl_state_change_data);
790 	callWithEachStaIfaceCallback(
791 		misc_utils::charBufToString(wpa_s->ifname), func);
792 	return 0;
793 }
794 
795 /**
796  * Notify all listeners about a request on a particular network.
797  *
798  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
799  * the network is present.
800  * @param ssid |wpa_ssid| struct corresponding to the network.
801  * @param type type of request.
802  * @param param addition params associated with the request.
803  */
notifyNetworkRequest(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,int type,const char * param)804 int AidlManager::notifyNetworkRequest(
805 	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
806 	const char *param)
807 {
808 	if (!wpa_s || !ssid)
809 		return 1;
810 
811 	const std::string network_key =
812 		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
813 	if (sta_network_object_map_.find(network_key) ==
814 		sta_network_object_map_.end())
815 		return 1;
816 
817 	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
818 		callWithEachStaNetworkCallback(
819 			misc_utils::charBufToString(wpa_s->ifname),
820 			ssid->id,
821 			std::bind(
822 			&ISupplicantStaNetworkCallback::
823 				onNetworkEapIdentityRequest,
824 			std::placeholders::_1));
825 		return 0;
826 	}
827 	if (type == WPA_CTRL_REQ_SIM) {
828 		std::vector<GsmRand> gsm_rands;
829 		std::vector<uint8_t> umts_rand = std::vector<uint8_t>(16);
830 		std::vector<uint8_t> umts_autn = std::vector<uint8_t>(16);
831 		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
832 			NetworkRequestEapSimGsmAuthParams aidl_params;
833 			aidl_params.rands = gsm_rands;
834 			callWithEachStaNetworkCallback(
835 				misc_utils::charBufToString(wpa_s->ifname),
836 				ssid->id,
837 				std::bind(
838 				&ISupplicantStaNetworkCallback::
839 					onNetworkEapSimGsmAuthRequest,
840 				std::placeholders::_1, aidl_params));
841 			return 0;
842 		}
843 		if (!parseUmtsAuthNetworkRequest(
844 			param, &umts_rand, &umts_autn)) {
845 			NetworkRequestEapSimUmtsAuthParams aidl_params;
846 			aidl_params.rand = umts_rand;
847 			aidl_params.autn = umts_autn;
848 			callWithEachStaNetworkCallback(
849 				misc_utils::charBufToString(wpa_s->ifname),
850 				ssid->id,
851 				std::bind(
852 				&ISupplicantStaNetworkCallback::
853 					onNetworkEapSimUmtsAuthRequest,
854 				std::placeholders::_1, aidl_params));
855 			return 0;
856 		}
857 	}
858 	return 1;
859 }
860 
861 #ifdef CONFIG_INTERWORKING
862 /**
863  * Notify that the AT_PERMANENT_ID_REQ is denied from eap_peer when the strict
864  * conservative peer mode is enabled.
865  *
866  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
867  * the network is present.
868 */
notifyPermanentIdReqDenied(struct wpa_supplicant * wpa_s)869 void AidlManager::notifyPermanentIdReqDenied(struct wpa_supplicant *wpa_s)
870 {
871 	if (!wpa_s->current_ssid) {
872 		wpa_printf(MSG_ERROR, "Current network NULL. Drop permanent_id_req_denied event!");
873 		return;
874 	}
875 	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
876 
877 	callWithEachStaNetworkCallback(
878 			misc_utils::charBufToString(wpa_s->ifname),
879 			current_ssid->id,
880 			std::bind(
881 			&ISupplicantStaNetworkCallback::
882 				onPermanentIdReqDenied,
883 			std::placeholders::_1));
884 }
885 
886 /**
887  * Notify all listeners about the end of an ANQP query.
888  *
889  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
890  * @param bssid BSSID of the access point.
891  * @param result Result of the operation ("SUCCESS" or "FAILURE").
892  * @param anqp |wpa_bss_anqp| ANQP data fetched.
893  */
notifyAnqpQueryDone(struct wpa_supplicant * wpa_s,const u8 * bssid,const char * result,const struct wpa_bss_anqp * anqp)894 void AidlManager::notifyAnqpQueryDone(
895 	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
896 	const struct wpa_bss_anqp *anqp)
897 {
898 	if (!wpa_s || !bssid || !result || !anqp)
899 		return;
900 
901 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
902 		sta_iface_object_map_.end())
903 		return;
904 
905 	AnqpData aidl_anqp_data;
906 	Hs20AnqpData aidl_hs20_anqp_data;
907 	if (std::string(result) == "SUCCESS") {
908 		aidl_anqp_data.venueName =
909 			misc_utils::convertWpaBufToVector(anqp->venue_name);
910 		aidl_anqp_data.roamingConsortium =
911 			misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
912 		aidl_anqp_data.ipAddrTypeAvailability =
913 			misc_utils::convertWpaBufToVector(
914 			anqp->ip_addr_type_availability);
915 		aidl_anqp_data.naiRealm =
916 			misc_utils::convertWpaBufToVector(anqp->nai_realm);
917 		aidl_anqp_data.anqp3gppCellularNetwork =
918 			misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
919 		aidl_anqp_data.domainName =
920 			misc_utils::convertWpaBufToVector(anqp->domain_name);
921 
922 		struct wpa_bss_anqp_elem *elem;
923 		dl_list_for_each(elem, &anqp->anqp_elems, struct wpa_bss_anqp_elem,
924 				 list) {
925 			if (elem->infoid == ANQP_VENUE_URL && elem->protected_response) {
926 				aidl_anqp_data.venueUrl =
927 							misc_utils::convertWpaBufToVector(elem->payload);
928 				break;
929 			}
930 		}
931 
932 #ifdef CONFIG_HS20
933 		aidl_hs20_anqp_data.operatorFriendlyName =
934 			misc_utils::convertWpaBufToVector(
935 			anqp->hs20_operator_friendly_name);
936 		aidl_hs20_anqp_data.wanMetrics =
937 			misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
938 		aidl_hs20_anqp_data.connectionCapability =
939 			misc_utils::convertWpaBufToVector(
940 			anqp->hs20_connection_capability);
941 		aidl_hs20_anqp_data.osuProvidersList =
942 			misc_utils::convertWpaBufToVector(
943 			anqp->hs20_osu_providers_list);
944 #else
945 		aidl_hs20_anqp_data.operatorFriendlyName =
946 			misc_utils::convertWpaBufToVector(NULL);
947 		aidl_hs20_anqp_data.wanMetrics =
948 			misc_utils::convertWpaBufToVector(NULL);
949 		aidl_hs20_anqp_data.connectionCapability =
950 			misc_utils::convertWpaBufToVector(NULL);
951 		aidl_hs20_anqp_data.osuProvidersList =
952 			misc_utils::convertWpaBufToVector(NULL);
953 #endif /* CONFIG_HS20 */
954 	}
955 
956 	callWithEachStaIfaceCallback(
957 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
958 				   &ISupplicantStaIfaceCallback::onAnqpQueryDone,
959 				   std::placeholders::_1, macAddrToVec(bssid), aidl_anqp_data,
960 				   aidl_hs20_anqp_data));
961 }
962 #endif /* CONFIG_INTERWORKING */
963 
964 /**
965  * Notify all listeners about the end of an HS20 icon query.
966  *
967  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
968  * @param bssid BSSID of the access point.
969  * @param file_name Name of the icon file.
970  * @param image Raw bytes of the icon file.
971  * @param image_length Size of the the icon file.
972  */
notifyHs20IconQueryDone(struct wpa_supplicant * wpa_s,const u8 * bssid,const char * file_name,const u8 * image,u32 image_length)973 void AidlManager::notifyHs20IconQueryDone(
974 	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
975 	const u8 *image, u32 image_length)
976 {
977 	if (!wpa_s || !bssid || !file_name || !image)
978 		return;
979 
980 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
981 		sta_iface_object_map_.end())
982 		return;
983 
984 	callWithEachStaIfaceCallback(
985 		misc_utils::charBufToString(wpa_s->ifname),
986 		std::bind(
987 		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
988 		std::placeholders::_1, macAddrToVec(bssid), file_name,
989 		std::vector<uint8_t>(image, image + image_length)));
990 }
991 
992 /**
993  * Notify all listeners about the reception of HS20 subscription
994  * remediation notification from the server.
995  *
996  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
997  * @param url URL of the server.
998  * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
999  */
notifyHs20RxSubscriptionRemediation(struct wpa_supplicant * wpa_s,const char * url,u8 osu_method)1000 void AidlManager::notifyHs20RxSubscriptionRemediation(
1001 	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
1002 {
1003 	if (!wpa_s || !url)
1004 		return;
1005 
1006 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1007 		sta_iface_object_map_.end())
1008 		return;
1009 
1010 	OsuMethod aidl_osu_method;
1011 	if (osu_method & 0x1) {
1012 		aidl_osu_method = OsuMethod::OMA_DM;
1013 	} else if (osu_method & 0x2) {
1014 		aidl_osu_method = OsuMethod::SOAP_XML_SPP;
1015 	}
1016 	callWithEachStaIfaceCallback(
1017 		misc_utils::charBufToString(wpa_s->ifname),
1018 		std::bind(
1019 		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
1020 		std::placeholders::_1, macAddrToVec(wpa_s->bssid), aidl_osu_method, url));
1021 }
1022 
1023 /**
1024  * Notify all listeners about the reception of HS20 imminent death
1025  * notification from the server.
1026  *
1027  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
1028  * @param code Death reason code sent from server.
1029  * @param reauth_delay Reauthentication delay in seconds sent from server.
1030  * @param url URL of the server containing the reason text.
1031  */
notifyHs20RxDeauthImminentNotice(struct wpa_supplicant * wpa_s,u8 code,u16 reauth_delay,const char * url)1032 void AidlManager::notifyHs20RxDeauthImminentNotice(
1033 	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
1034 {
1035 	if (!wpa_s)
1036 		return;
1037 
1038 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1039 		sta_iface_object_map_.end())
1040 		return;
1041 
1042 	callWithEachStaIfaceCallback(
1043 		misc_utils::charBufToString(wpa_s->ifname),
1044 		std::bind(
1045 		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
1046 		std::placeholders::_1, macAddrToVec(wpa_s->bssid), code,
1047 		reauth_delay, misc_utils::charBufToString(url)));
1048 }
1049 
1050 /**
1051  * Notify all listeners about the reception of HS20 terms and conditions
1052  * acceptance notification from the server.
1053  *
1054  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
1055  * @param url URL of the T&C server.
1056  */
notifyHs20RxTermsAndConditionsAcceptance(struct wpa_supplicant * wpa_s,const char * url)1057 void AidlManager::notifyHs20RxTermsAndConditionsAcceptance(
1058 	struct wpa_supplicant *wpa_s, const char *url)
1059 {
1060 	if (!wpa_s || !url)
1061 		return;
1062 
1063 	if (sta_iface_object_map_.find(wpa_s->ifname)
1064 			== sta_iface_object_map_.end())
1065 		return;
1066 
1067 	callWithEachStaIfaceCallback(
1068 		misc_utils::charBufToString(wpa_s->ifname),
1069 		std::bind(
1070 			&ISupplicantStaIfaceCallback
1071 			::onHs20TermsAndConditionsAcceptanceRequestedNotification,
1072 			std::placeholders::_1, macAddrToVec(wpa_s->bssid), url));
1073 }
1074 
1075 /**
1076  * Notify all listeners about the reason code for disconnection from the
1077  * currently connected network.
1078  *
1079  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
1080  * the network is present.
1081  */
notifyDisconnectReason(struct wpa_supplicant * wpa_s)1082 void AidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
1083 {
1084 	if (!wpa_s)
1085 		return;
1086 
1087 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1088 		sta_iface_object_map_.end())
1089 		return;
1090 
1091 	const u8 *bssid = wpa_s->bssid;
1092 	if (is_zero_ether_addr(bssid)) {
1093 		bssid = wpa_s->pending_bssid;
1094 	}
1095 
1096 	callWithEachStaIfaceCallback(
1097 		misc_utils::charBufToString(wpa_s->ifname),
1098 		std::bind(
1099 		&ISupplicantStaIfaceCallback::onDisconnected,
1100 		std::placeholders::_1, macAddrToVec(bssid), wpa_s->disconnect_reason < 0,
1101 		static_cast<StaIfaceReasonCode>(
1102 			abs(wpa_s->disconnect_reason))));
1103 }
1104 
1105 /**
1106  * Notify all listeners about association reject from the access point to which
1107  * we are attempting to connect.
1108  *
1109  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
1110  * the network is present.
1111  * @param bssid bssid of AP that rejected the association.
1112  * @param timed_out flag to indicate failure is due to timeout
1113  * (auth, assoc, ...) rather than explicit rejection response from the AP.
1114  * @param assoc_resp_ie Association response IE.
1115  * @param assoc_resp_ie_len Association response IE length.
1116  */
notifyAssocReject(struct wpa_supplicant * wpa_s,const u8 * bssid,u8 timed_out,const u8 * assoc_resp_ie,size_t assoc_resp_ie_len)1117 void AidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s,
1118 	const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
1119 {
1120 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1121 #ifdef CONFIG_MBO
1122 	struct wpa_bss *reject_bss;
1123 #endif /* CONFIG_MBO */
1124 	AssociationRejectionData aidl_assoc_reject_data{};
1125 
1126 	if (!wpa_s)
1127 		return;
1128 
1129 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1130 		sta_iface_object_map_.end())
1131 		return;
1132 	if (wpa_s->current_ssid) {
1133 		aidl_assoc_reject_data.ssid = std::vector<uint8_t>(
1134 			wpa_s->current_ssid->ssid,
1135 			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
1136 	}
1137 	aidl_assoc_reject_data.bssid = macAddrToVec(bssid);
1138 	aidl_assoc_reject_data.statusCode = static_cast<StaIfaceStatusCode>(
1139 						wpa_s->assoc_status_code);
1140 	if (timed_out) {
1141 		aidl_assoc_reject_data.timedOut = true;
1142 	}
1143 #ifdef CONFIG_MBO
1144 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
1145 		reject_bss = wpa_s->current_bss;
1146 	} else {
1147 		reject_bss = wpa_bss_get_bssid(wpa_s, bssid);
1148 	}
1149 	if (reject_bss && assoc_resp_ie && assoc_resp_ie_len > 0) {
1150 		if (wpa_s->assoc_status_code ==
1151 			WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS) {
1152 			const u8 *rssi_rej;
1153 			rssi_rej = mbo_get_attr_from_ies(
1154 					assoc_resp_ie,
1155 					assoc_resp_ie_len,
1156 					OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
1157 			if (rssi_rej && rssi_rej[1] == 2) {
1158 				wpa_printf(MSG_INFO,
1159 					   "OCE: RSSI-based association rejection from "
1160 					   MACSTR " Delta RSSI: %u, Retry Delay: %u bss rssi: %d",
1161 					   MAC2STR(reject_bss->bssid),
1162 					   rssi_rej[2], rssi_rej[3], reject_bss->level);
1163 				aidl_assoc_reject_data.isOceRssiBasedAssocRejectAttrPresent = true;
1164 				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.deltaRssi
1165 						= rssi_rej[2];
1166 				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.retryDelayS
1167 						= rssi_rej[3];
1168 			}
1169 		} else if (wpa_s->assoc_status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
1170 			  || wpa_s->assoc_status_code == WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA) {
1171 			const u8 *assoc_disallowed;
1172 			assoc_disallowed = mbo_get_attr_from_ies(
1173 							assoc_resp_ie,
1174 							assoc_resp_ie_len,
1175 							MBO_ATTR_ID_ASSOC_DISALLOW);
1176 			if (assoc_disallowed && assoc_disallowed[1] == 1) {
1177 				wpa_printf(MSG_INFO,
1178 					"MBO: association disallowed indication from "
1179 					MACSTR " Reason: %d",
1180 					MAC2STR(reject_bss->bssid),
1181 					assoc_disallowed[2]);
1182 				aidl_assoc_reject_data.isMboAssocDisallowedReasonCodePresent = true;
1183 				aidl_assoc_reject_data.mboAssocDisallowedReason
1184 					= static_cast<MboAssocDisallowedReasonCode>(assoc_disallowed[2]);
1185 			}
1186 		}
1187 	}
1188 #endif /* CONFIG_MBO */
1189 
1190 	const std::function<
1191 			ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
1192 			func = std::bind(
1193 			&ISupplicantStaIfaceCallback::onAssociationRejected,
1194 			std::placeholders::_1, aidl_assoc_reject_data);
1195 	callWithEachStaIfaceCallback(aidl_ifname, func);
1196 }
1197 
notifyAuthTimeout(struct wpa_supplicant * wpa_s)1198 void AidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
1199 {
1200 	if (!wpa_s)
1201 		return;
1202 
1203 	const std::string ifname(wpa_s->ifname);
1204 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
1205 		return;
1206 
1207 	const u8 *bssid = wpa_s->bssid;
1208 	if (is_zero_ether_addr(bssid)) {
1209 		bssid = wpa_s->pending_bssid;
1210 	}
1211 	callWithEachStaIfaceCallback(
1212 		misc_utils::charBufToString(wpa_s->ifname),
1213 		std::bind(
1214 		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
1215 		std::placeholders::_1, macAddrToVec(bssid)));
1216 }
1217 
notifyBssidChanged(struct wpa_supplicant * wpa_s)1218 void AidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
1219 {
1220 	if (!wpa_s)
1221 		return;
1222 
1223 	const std::string ifname(wpa_s->ifname);
1224 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
1225 		return;
1226 
1227 	// wpa_supplicant does not explicitly give us the reason for bssid
1228 	// change, but we figure that out from what is set out of |wpa_s->bssid|
1229 	// & |wpa_s->pending_bssid|.
1230 	const u8 *bssid;
1231 	BssidChangeReason reason;
1232 	if (is_zero_ether_addr(wpa_s->bssid) &&
1233 		!is_zero_ether_addr(wpa_s->pending_bssid)) {
1234 		bssid = wpa_s->pending_bssid;
1235 		reason = BssidChangeReason::ASSOC_START;
1236 	} else if (
1237 		!is_zero_ether_addr(wpa_s->bssid) &&
1238 		is_zero_ether_addr(wpa_s->pending_bssid)) {
1239 		bssid = wpa_s->bssid;
1240 		reason = BssidChangeReason::ASSOC_COMPLETE;
1241 	} else if (
1242 		is_zero_ether_addr(wpa_s->bssid) &&
1243 		is_zero_ether_addr(wpa_s->pending_bssid)) {
1244 		bssid = wpa_s->pending_bssid;
1245 		reason = BssidChangeReason::DISASSOC;
1246 	} else {
1247 		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
1248 		return;
1249 	}
1250 
1251 	callWithEachStaIfaceCallback(
1252 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
1253 				   &ISupplicantStaIfaceCallback::onBssidChanged,
1254 				   std::placeholders::_1, reason, macAddrToVec(bssid)));
1255 }
1256 
notifyWpsEventFail(struct wpa_supplicant * wpa_s,uint8_t * peer_macaddr,uint16_t config_error,uint16_t error_indication)1257 void AidlManager::notifyWpsEventFail(
1258 	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
1259 	uint16_t error_indication)
1260 {
1261 	if (!wpa_s || !peer_macaddr)
1262 		return;
1263 
1264 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1265 		sta_iface_object_map_.end())
1266 		return;
1267 
1268 	callWithEachStaIfaceCallback(
1269 		misc_utils::charBufToString(wpa_s->ifname),
1270 		std::bind(
1271 		&ISupplicantStaIfaceCallback::onWpsEventFail,
1272 		std::placeholders::_1, macAddrToVec(peer_macaddr),
1273 		static_cast<WpsConfigError>(
1274 			config_error),
1275 		static_cast<WpsErrorIndication>(
1276 			error_indication)));
1277 }
1278 
notifyWpsEventSuccess(struct wpa_supplicant * wpa_s)1279 void AidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
1280 {
1281 	if (!wpa_s)
1282 		return;
1283 
1284 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1285 		sta_iface_object_map_.end())
1286 		return;
1287 
1288 	callWithEachStaIfaceCallback(
1289 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
1290 				   &ISupplicantStaIfaceCallback::onWpsEventSuccess,
1291 				   std::placeholders::_1));
1292 }
1293 
notifyWpsEventPbcOverlap(struct wpa_supplicant * wpa_s)1294 void AidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
1295 {
1296 	if (!wpa_s)
1297 		return;
1298 
1299 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1300 		sta_iface_object_map_.end())
1301 		return;
1302 
1303 	callWithEachStaIfaceCallback(
1304 		misc_utils::charBufToString(wpa_s->ifname),
1305 		std::bind(
1306 		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
1307 		std::placeholders::_1));
1308 }
1309 
notifyP2pDeviceFound(struct wpa_supplicant * wpa_s,const u8 * addr,const struct p2p_peer_info * info,const u8 * peer_wfd_device_info,u8 peer_wfd_device_info_len,const u8 * peer_wfd_r2_device_info,u8 peer_wfd_r2_device_info_len)1310 void AidlManager::notifyP2pDeviceFound(
1311 	struct wpa_supplicant *wpa_s, const u8 *addr,
1312 	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
1313 	u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
1314 	u8 peer_wfd_r2_device_info_len)
1315 {
1316 	if (!wpa_s || !addr || !info)
1317 		return;
1318 
1319 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1320 		p2p_iface_object_map_.end())
1321 		return;
1322 
1323 	std::vector<uint8_t> aidl_peer_wfd_device_info(kWfdDeviceInfoLen);
1324 	if (peer_wfd_device_info) {
1325 		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
1326 			wpa_printf(
1327 				MSG_ERROR, "Unexpected WFD device info len: %d",
1328 				peer_wfd_device_info_len);
1329 		} else {
1330 			os_memcpy(
1331 				aidl_peer_wfd_device_info.data(),
1332 				peer_wfd_device_info, kWfdDeviceInfoLen);
1333 		}
1334 	}
1335 
1336 	std::vector<uint8_t> aidl_peer_wfd_r2_device_info;
1337 	if (peer_wfd_r2_device_info) {
1338 		if (peer_wfd_r2_device_info_len != kWfdR2DeviceInfoLen) {
1339 			wpa_printf(
1340 				MSG_ERROR, "Unexpected WFD R2 device info len: %d",
1341 				peer_wfd_r2_device_info_len);
1342 			return;
1343 		} else {
1344 			std::copy(peer_wfd_r2_device_info,
1345 			    peer_wfd_r2_device_info + peer_wfd_r2_device_info_len,
1346 			    std::back_inserter(aidl_peer_wfd_r2_device_info));
1347 		}
1348 	}
1349 
1350 	std::vector<uint8_t> aidl_vendor_elems;
1351 	if (NULL != info->vendor_elems && wpabuf_len(info->vendor_elems) > 0) {
1352 		aidl_vendor_elems.reserve(wpabuf_len(info->vendor_elems));
1353 		std::copy(wpabuf_head_u8(info->vendor_elems),
1354 			wpabuf_head_u8(info->vendor_elems)
1355 				+ wpabuf_len(info->vendor_elems),
1356 			std::back_inserter(aidl_vendor_elems));
1357 	}
1358 
1359 	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
1360 		P2pDeviceFoundEventParams params;
1361 		params.srcAddress = macAddrToArray(addr);
1362 		params.p2pDeviceAddress = macAddrToArray(info->p2p_device_addr);
1363 		params.primaryDeviceType = byteArrToVec(info->pri_dev_type, 8);
1364 		params.deviceName = misc_utils::charBufToString(info->device_name);
1365 		params.configMethods = info->config_methods;
1366 		params.deviceCapabilities = info->dev_capab;
1367 		params.groupCapabilities = info->group_capab;
1368 		params.wfdDeviceInfo = aidl_peer_wfd_device_info;
1369 		params.wfdR2DeviceInfo = aidl_peer_wfd_r2_device_info;
1370 		params.vendorElemBytes = aidl_vendor_elems;
1371 		callWithEachP2pIfaceCallback(
1372 			misc_utils::charBufToString(wpa_s->ifname),
1373 			std::bind(
1374 			&ISupplicantP2pIfaceCallback::onDeviceFoundWithParams,
1375 			std::placeholders::_1, params));
1376 	} else {
1377 	    // Use legacy callback if service or client interface version < 3
1378 		const std::function<
1379 			ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
1380 			func = std::bind(
1381 			&ISupplicantP2pIfaceCallback::onDeviceFoundWithVendorElements,
1382 			std::placeholders::_1, macAddrToVec(addr), macAddrToVec(info->p2p_device_addr),
1383 			byteArrToVec(info->pri_dev_type, 8), misc_utils::charBufToString(info->device_name),
1384 			static_cast<WpsConfigMethods>(info->config_methods),
1385 			info->dev_capab, static_cast<P2pGroupCapabilityMask>(info->group_capab), aidl_peer_wfd_device_info,
1386 			aidl_peer_wfd_r2_device_info, aidl_vendor_elems);
1387 		callWithEachP2pIfaceCallback(wpa_s->ifname, func);
1388 	}
1389 }
1390 
notifyP2pDeviceLost(struct wpa_supplicant * wpa_s,const u8 * p2p_device_addr)1391 void AidlManager::notifyP2pDeviceLost(
1392 	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
1393 {
1394 	if (!wpa_s || !p2p_device_addr)
1395 		return;
1396 
1397 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1398 		p2p_iface_object_map_.end())
1399 		return;
1400 
1401 	callWithEachP2pIfaceCallback(
1402 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
1403 				   &ISupplicantP2pIfaceCallback::onDeviceLost,
1404 				   std::placeholders::_1, macAddrToVec(p2p_device_addr)));
1405 }
1406 
notifyP2pFindStopped(struct wpa_supplicant * wpa_s)1407 void AidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
1408 {
1409 	if (!wpa_s)
1410 		return;
1411 
1412 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1413 		p2p_iface_object_map_.end())
1414 		return;
1415 
1416 	callWithEachP2pIfaceCallback(
1417 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
1418 				   &ISupplicantP2pIfaceCallback::onFindStopped,
1419 				   std::placeholders::_1));
1420 }
1421 
notifyP2pGoNegReq(struct wpa_supplicant * wpa_s,const u8 * src_addr,u16 dev_passwd_id,u8)1422 void AidlManager::notifyP2pGoNegReq(
1423 	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
1424 	u8 /* go_intent */)
1425 {
1426 	if (!wpa_s || !src_addr)
1427 		return;
1428 
1429 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1430 		p2p_iface_object_map_.end())
1431 		return;
1432 
1433 	callWithEachP2pIfaceCallback(
1434 		misc_utils::charBufToString(wpa_s->ifname),
1435 		std::bind(
1436 		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
1437 		std::placeholders::_1, macAddrToVec(src_addr),
1438 		static_cast<WpsDevPasswordId>(
1439 			dev_passwd_id)));
1440 }
1441 
notifyP2pGoNegCompleted(struct wpa_supplicant * wpa_s,const struct p2p_go_neg_results * res)1442 void AidlManager::notifyP2pGoNegCompleted(
1443 	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
1444 {
1445 	if (!wpa_s || !res)
1446 		return;
1447 
1448 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1449 		p2p_iface_object_map_.end())
1450 		return;
1451 
1452 	callWithEachP2pIfaceCallback(
1453 		misc_utils::charBufToString(wpa_s->ifname),
1454 		std::bind(
1455 		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
1456 		std::placeholders::_1,
1457 		static_cast<P2pStatusCode>(
1458 			res->status)));
1459 }
1460 
notifyP2pGroupFormationFailure(struct wpa_supplicant * wpa_s,const char * reason)1461 void AidlManager::notifyP2pGroupFormationFailure(
1462 	struct wpa_supplicant *wpa_s, const char *reason)
1463 {
1464 	if (!wpa_s || !reason)
1465 		return;
1466 
1467 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1468 		p2p_iface_object_map_.end())
1469 		return;
1470 
1471 	callWithEachP2pIfaceCallback(
1472 		misc_utils::charBufToString(wpa_s->ifname),
1473 		std::bind(
1474 		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
1475 		std::placeholders::_1, reason));
1476 }
1477 
notifyP2pGroupStarted(struct wpa_supplicant * wpa_group_s,const struct wpa_ssid * ssid,int persistent,int client,const u8 * ip)1478 void AidlManager::notifyP2pGroupStarted(
1479 	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
1480 	int persistent, int client, const u8 *ip)
1481 {
1482 	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
1483 		return;
1484 
1485 	// For group notifications, need to use the parent iface for callbacks.
1486 	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
1487 	if (!wpa_s)
1488 		return;
1489 
1490 	uint32_t aidl_freq = wpa_group_s->current_bss
1491 				 ? wpa_group_s->current_bss->freq
1492 				 : wpa_group_s->assoc_freq;
1493 	std::vector<uint8_t> aidl_psk(32);
1494 	if (ssid->psk_set) {
1495 		aidl_psk.assign(ssid->psk, ssid->psk + 32);
1496 	}
1497 	bool aidl_is_go = (client == 0 ? true : false);
1498 	bool aidl_is_persistent = (persistent == 1 ? true : false);
1499 
1500 	// notify the group device again to ensure the framework knowing this device.
1501 	struct p2p_data *p2p = wpa_s->global->p2p;
1502 	struct p2p_device *dev = p2p_get_device(p2p, wpa_group_s->go_dev_addr);
1503 	if (NULL != dev) {
1504 		wpa_printf(MSG_DEBUG, "P2P: Update GO device on group started.");
1505 		p2p->cfg->dev_found(p2p->cfg->cb_ctx, wpa_group_s->go_dev_addr,
1506 				&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
1507 		dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
1508 	}
1509 
1510 	P2pGroupStartedEventParams params;
1511 	params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
1512 	params.isGroupOwner = aidl_is_go;
1513 	params.ssid = byteArrToVec(ssid->ssid, ssid->ssid_len);
1514 	params.frequencyMHz = aidl_freq;
1515 	params.psk = aidl_psk;
1516 	params.passphrase = misc_utils::charBufToString(ssid->passphrase);
1517 	params.isPersistent = aidl_is_persistent;
1518 	params.goDeviceAddress = macAddrToArray(wpa_group_s->go_dev_addr);
1519 	params.goInterfaceAddress = aidl_is_go ? macAddrToArray(wpa_group_s->own_addr) :
1520 			macAddrToArray(wpa_group_s->current_bss->bssid);
1521 	if (NULL != ip && !aidl_is_go) {
1522 		params.isP2pClientEapolIpAddressInfoPresent = true;
1523 		os_memcpy(&params.p2pClientIpInfo.ipAddressClient, &ip[0], 4);
1524 		os_memcpy(&params.p2pClientIpInfo.ipAddressMask, &ip[4], 4);
1525 		os_memcpy(&params.p2pClientIpInfo.ipAddressGo, &ip[8], 4);
1526 
1527 		wpa_printf(MSG_DEBUG, "P2P: IP Address allocated - CLI: 0x%x MASK: 0x%x GO: 0x%x",
1528 			   params.p2pClientIpInfo.ipAddressClient,
1529 			   params.p2pClientIpInfo.ipAddressMask,
1530 			   params.p2pClientIpInfo.ipAddressGo);
1531         }
1532 	callWithEachP2pIfaceCallback(
1533 		misc_utils::charBufToString(wpa_s->ifname),
1534 		std::bind(&ISupplicantP2pIfaceCallback::onGroupStartedWithParams,
1535 		std::placeholders::_1, params));
1536 }
1537 
notifyP2pGroupRemoved(struct wpa_supplicant * wpa_group_s,const struct wpa_ssid * ssid,const char * role)1538 void AidlManager::notifyP2pGroupRemoved(
1539 	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
1540 	const char *role)
1541 {
1542 	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
1543 		return;
1544 
1545 	// For group notifications, need to use the parent iface for callbacks.
1546 	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
1547 	if (!wpa_s)
1548 		return;
1549 
1550 	bool aidl_is_go = (std::string(role) == "GO");
1551 
1552 	callWithEachP2pIfaceCallback(
1553 		misc_utils::charBufToString(wpa_s->ifname),
1554 		std::bind(
1555 		&ISupplicantP2pIfaceCallback::onGroupRemoved,
1556 		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_is_go));
1557 }
1558 
notifyP2pInvitationReceived(struct wpa_supplicant * wpa_s,const u8 * sa,const u8 * go_dev_addr,const u8 * bssid,int id,int op_freq)1559 void AidlManager::notifyP2pInvitationReceived(
1560 	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
1561 	const u8 *bssid, int id, int op_freq)
1562 {
1563 	if (!wpa_s || !sa || !go_dev_addr || !bssid)
1564 		return;
1565 
1566 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1567 		p2p_iface_object_map_.end())
1568 		return;
1569 
1570 	int aidl_network_id;
1571 	if (id < 0) {
1572 		aidl_network_id = UINT32_MAX;
1573 	}
1574 	aidl_network_id = id;
1575 
1576 	callWithEachP2pIfaceCallback(
1577 		misc_utils::charBufToString(wpa_s->ifname),
1578 		std::bind(
1579 		&ISupplicantP2pIfaceCallback::onInvitationReceived,
1580 		std::placeholders::_1, macAddrToVec(sa), macAddrToVec(go_dev_addr),
1581 		macAddrToVec(bssid), aidl_network_id, op_freq));
1582 }
1583 
notifyP2pInvitationResult(struct wpa_supplicant * wpa_s,int status,const u8 * bssid)1584 void AidlManager::notifyP2pInvitationResult(
1585 	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
1586 {
1587 	if (!wpa_s)
1588 		return;
1589 
1590 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1591 		p2p_iface_object_map_.end())
1592 		return;
1593 
1594 	callWithEachP2pIfaceCallback(
1595 		misc_utils::charBufToString(wpa_s->ifname),
1596 		std::bind(
1597 		&ISupplicantP2pIfaceCallback::onInvitationResult,
1598 		std::placeholders::_1, bssid ? macAddrToVec(bssid) : kZeroBssid,
1599 		static_cast<P2pStatusCode>(
1600 			status)));
1601 }
1602 
notifyP2pProvisionDiscovery(struct wpa_supplicant * wpa_s,const u8 * dev_addr,int request,enum p2p_prov_disc_status status,u16 config_methods,unsigned int generated_pin,const char * group_ifname)1603 void AidlManager::notifyP2pProvisionDiscovery(
1604 	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
1605 	enum p2p_prov_disc_status status, u16 config_methods,
1606 	unsigned int generated_pin, const char *group_ifname)
1607 {
1608 	if (!wpa_s || !dev_addr)
1609 		return;
1610 
1611 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1612 		p2p_iface_object_map_.end())
1613 		return;
1614 
1615 	std::string aidl_generated_pin;
1616 	if (generated_pin > 0) {
1617 		aidl_generated_pin =
1618 			misc_utils::convertWpsPinToString(generated_pin);
1619 	}
1620 	bool aidl_is_request = (request == 1);
1621 
1622 	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
1623 		P2pProvisionDiscoveryCompletedEventParams params;
1624 		params.p2pDeviceAddress =  macAddrToArray(dev_addr);
1625 		params.isRequest = aidl_is_request;
1626 		params.status = static_cast<P2pProvDiscStatusCode>(status);
1627 		params.configMethods = config_methods;
1628 		params.generatedPin = aidl_generated_pin;
1629 		if (group_ifname != NULL) {
1630 			params.groupInterfaceName = misc_utils::charBufToString(group_ifname);
1631 		}
1632 		callWithEachP2pIfaceCallback(
1633 			misc_utils::charBufToString(wpa_s->ifname),
1634 			std::bind(
1635 			&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompletedEvent,
1636 			std::placeholders::_1, params));
1637 	} else {
1638 		// Use legacy callback if service or client interface version < 3
1639 		callWithEachP2pIfaceCallback(
1640 			misc_utils::charBufToString(wpa_s->ifname),
1641 			std::bind(
1642 			&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
1643 			std::placeholders::_1, macAddrToVec(dev_addr), aidl_is_request,
1644 			static_cast<P2pProvDiscStatusCode>(status),
1645 			static_cast<WpsConfigMethods>(config_methods), aidl_generated_pin));
1646 	}
1647 }
1648 
notifyP2pSdResponse(struct wpa_supplicant * wpa_s,const u8 * sa,u16 update_indic,const u8 * tlvs,size_t tlvs_len)1649 void AidlManager::notifyP2pSdResponse(
1650 	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
1651 	const u8 *tlvs, size_t tlvs_len)
1652 {
1653 	if (!wpa_s || !sa || !tlvs)
1654 		return;
1655 
1656 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1657 		p2p_iface_object_map_.end())
1658 		return;
1659 
1660 	callWithEachP2pIfaceCallback(
1661 		misc_utils::charBufToString(wpa_s->ifname),
1662 		std::bind(
1663 		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
1664 		std::placeholders::_1, macAddrToVec(sa), update_indic,
1665 		byteArrToVec(tlvs, tlvs_len)));
1666 }
1667 
notifyApStaAuthorized(struct wpa_supplicant * wpa_group_s,const u8 * sta,const u8 * p2p_dev_addr,const u8 * ip)1668 void AidlManager::notifyApStaAuthorized(
1669 	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr,
1670 	const u8 *ip)
1671 {
1672 	if (!wpa_group_s || !wpa_group_s->parent || !sta)
1673 		return;
1674 	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
1675 	if (!wpa_s)
1676 		return;
1677 
1678 	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
1679 		P2pPeerClientJoinedEventParams params;
1680 		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
1681 		params.clientInterfaceAddress = macAddrToArray(sta);
1682 		params.clientDeviceAddress = p2p_dev_addr ?
1683 				macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
1684 		int aidl_ip = 0;
1685 		if (NULL != ip) {
1686 			os_memcpy(&aidl_ip, &ip[0], 4);
1687 		}
1688 		params.clientIpAddress = aidl_ip;
1689 		callWithEachP2pIfaceCallback(
1690 			misc_utils::charBufToString(wpa_s->ifname),
1691 			std::bind(
1692 			&ISupplicantP2pIfaceCallback::onPeerClientJoined,
1693 			std::placeholders::_1, params));
1694 	} else {
1695 		// Use legacy callback if service or client interface version < 3
1696 		callWithEachP2pIfaceCallback(
1697 			misc_utils::charBufToString(wpa_s->ifname),
1698 			std::bind(
1699 			&ISupplicantP2pIfaceCallback::onStaAuthorized,
1700 			std::placeholders::_1, macAddrToVec(sta),
1701 			p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
1702 	}
1703 }
1704 
notifyApStaDeauthorized(struct wpa_supplicant * wpa_group_s,const u8 * sta,const u8 * p2p_dev_addr)1705 void AidlManager::notifyApStaDeauthorized(
1706 	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
1707 {
1708 	if (!wpa_group_s || !wpa_group_s->parent || !sta)
1709 		return;
1710 	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
1711 	if (!wpa_s)
1712 		return;
1713 
1714 	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
1715 		P2pPeerClientDisconnectedEventParams params;
1716 		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
1717 		params.clientInterfaceAddress = macAddrToArray(sta);
1718 		params.clientDeviceAddress = p2p_dev_addr ?
1719 				macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
1720 
1721 		callWithEachP2pIfaceCallback(
1722 			misc_utils::charBufToString(wpa_s->ifname),
1723 			std::bind(
1724 			&ISupplicantP2pIfaceCallback::onPeerClientDisconnected,
1725 			std::placeholders::_1, params));
1726 	} else {
1727 		// Use legacy callback if service or client interface version < 3
1728 		callWithEachP2pIfaceCallback(
1729 			misc_utils::charBufToString(wpa_s->ifname),
1730 			std::bind(
1731 			&ISupplicantP2pIfaceCallback::onStaDeauthorized,
1732 			std::placeholders::_1, macAddrToVec(sta),
1733 			p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
1734 	}
1735 }
1736 
notifyExtRadioWorkStart(struct wpa_supplicant * wpa_s,uint32_t id)1737 void AidlManager::notifyExtRadioWorkStart(
1738 	struct wpa_supplicant *wpa_s, uint32_t id)
1739 {
1740 	if (!wpa_s)
1741 		return;
1742 
1743 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1744 		sta_iface_object_map_.end())
1745 		return;
1746 
1747 	callWithEachStaIfaceCallback(
1748 		misc_utils::charBufToString(wpa_s->ifname),
1749 		std::bind(
1750 		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
1751 		std::placeholders::_1, id));
1752 }
1753 
notifyExtRadioWorkTimeout(struct wpa_supplicant * wpa_s,uint32_t id)1754 void AidlManager::notifyExtRadioWorkTimeout(
1755 	struct wpa_supplicant *wpa_s, uint32_t id)
1756 {
1757 	if (!wpa_s)
1758 		return;
1759 
1760 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1761 		sta_iface_object_map_.end())
1762 		return;
1763 
1764 	callWithEachStaIfaceCallback(
1765 		misc_utils::charBufToString(wpa_s->ifname),
1766 		std::bind(
1767 		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
1768 		std::placeholders::_1, id));
1769 }
1770 
notifyEapError(struct wpa_supplicant * wpa_s,int error_code)1771 void AidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
1772 {
1773 	if (!wpa_s)
1774 		return;
1775 
1776 	callWithEachStaIfaceCallback(
1777 		misc_utils::charBufToString(wpa_s->ifname),
1778 		std::bind(
1779 		&ISupplicantStaIfaceCallback::onEapFailure,
1780 		std::placeholders::_1,
1781 		macAddrToVec(wpa_s->bssid), error_code));
1782 }
1783 
1784 /**
1785  * Notify listener about a new DPP configuration received success event
1786  *
1787  * @param ifname Interface name
1788  * @param config Configuration object
1789  */
notifyDppConfigReceived(struct wpa_supplicant * wpa_s,struct wpa_ssid * config,bool conn_status_requested)1790 void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
1791 		struct wpa_ssid *config, bool conn_status_requested)
1792 {
1793 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1794 	DppConfigurationData aidl_dpp_config_data = {};
1795 
1796 	if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
1797 			(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
1798 		aidl_dpp_config_data.securityAkm = DppAkm::SAE;
1799 	} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
1800 		aidl_dpp_config_data.securityAkm = DppAkm::PSK;
1801 	} else if (config->key_mgmt & WPA_KEY_MGMT_DPP) {
1802 		aidl_dpp_config_data.securityAkm = DppAkm::DPP;
1803 	} else {
1804 		/* Unsupported AKM */
1805 		wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
1806 				config->key_mgmt);
1807 		notifyDppFailure(wpa_s, DppFailureCode::NOT_SUPPORTED);
1808 		return;
1809 	}
1810 
1811 	aidl_dpp_config_data.password = misc_utils::charBufToString(config->passphrase);
1812 	aidl_dpp_config_data.psk = byteArrToVec(config->psk, 32);
1813 	std::vector<uint8_t> aidl_ssid(
1814 		config->ssid,
1815 		config->ssid + config->ssid_len);
1816 	aidl_dpp_config_data.ssid = aidl_ssid;
1817 
1818 	if (aidl_dpp_config_data.securityAkm == DppAkm::DPP) {
1819 		std::string connector_str = misc_utils::charBufToString(config->dpp_connector);
1820 		aidl_dpp_config_data.dppConnectionKeys.connector
1821 			= std::vector<uint8_t>(connector_str.begin(), connector_str.end());
1822 		aidl_dpp_config_data.dppConnectionKeys.cSign
1823 			= byteArrToVec(config->dpp_csign, config->dpp_csign_len);
1824 		aidl_dpp_config_data.dppConnectionKeys.netAccessKey
1825 			= byteArrToVec(config->dpp_netaccesskey, config->dpp_netaccesskey_len);
1826 	}
1827 	aidl_dpp_config_data.connStatusRequested = conn_status_requested;
1828 
1829 	/* At this point, the network is already registered, notify about new
1830 	 * received configuration
1831 	 */
1832 	callWithEachStaIfaceCallback(aidl_ifname,
1833 			std::bind(
1834 					&ISupplicantStaIfaceCallback::onDppConfigReceived,
1835 					std::placeholders::_1, aidl_dpp_config_data));
1836 }
1837 
1838 /**
1839  * Notify listener about a DPP configuration sent success event
1840  *
1841  * @param ifname Interface name
1842  */
notifyDppConfigSent(struct wpa_supplicant * wpa_s)1843 void AidlManager::notifyDppConfigSent(struct wpa_supplicant *wpa_s)
1844 {
1845 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1846 
1847 	callWithEachStaIfaceCallback(aidl_ifname,
1848 			std::bind(&ISupplicantStaIfaceCallback::onDppSuccessConfigSent,
1849 					std::placeholders::_1));
1850 }
1851 
convertSupplicantDppStatusErrorCodeToAidl(enum dpp_status_error code)1852 DppStatusErrorCode convertSupplicantDppStatusErrorCodeToAidl(
1853 	enum dpp_status_error code)
1854 {
1855 	switch (code) {
1856 		case DPP_STATUS_OK:
1857 			return DppStatusErrorCode::SUCCESS;
1858 		case DPP_STATUS_NOT_COMPATIBLE:
1859 			return DppStatusErrorCode::NOT_COMPATIBLE;
1860 		case DPP_STATUS_AUTH_FAILURE:
1861 			return DppStatusErrorCode::AUTH_FAILURE;
1862 		case DPP_STATUS_UNWRAP_FAILURE:
1863 			return DppStatusErrorCode::UNWRAP_FAILURE;
1864 		case DPP_STATUS_BAD_GROUP:
1865 			return DppStatusErrorCode::BAD_GROUP;
1866 		case DPP_STATUS_CONFIGURE_FAILURE:
1867 			return DppStatusErrorCode::CONFIGURE_FAILURE;
1868 		case DPP_STATUS_RESPONSE_PENDING:
1869 			return DppStatusErrorCode::RESPONSE_PENDING;
1870 		case DPP_STATUS_INVALID_CONNECTOR:
1871 			return DppStatusErrorCode::INVALID_CONNECTOR;
1872 		case DPP_STATUS_CONFIG_REJECTED:
1873 			return DppStatusErrorCode::CONFIG_REJECTED;
1874 		case DPP_STATUS_NO_MATCH:
1875 			return DppStatusErrorCode::NO_MATCH;
1876 		case DPP_STATUS_NO_AP:
1877 			return DppStatusErrorCode::NO_AP;
1878 		case DPP_STATUS_CONFIGURE_PENDING:
1879 			return DppStatusErrorCode::CONFIGURE_PENDING;
1880 		case DPP_STATUS_CSR_NEEDED:
1881 			return DppStatusErrorCode::CSR_NEEDED;
1882 		case DPP_STATUS_CSR_BAD:
1883 			return DppStatusErrorCode::CSR_BAD;
1884 		case DPP_STATUS_NEW_KEY_NEEDED:
1885 			return DppStatusErrorCode::NEW_KEY_NEEDED;
1886 		default:
1887 			return DppStatusErrorCode::UNKNOWN;
1888 	}
1889 }
1890 
notifyDppConnectionStatusSent(struct wpa_supplicant * wpa_s,enum dpp_status_error result)1891 void AidlManager::notifyDppConnectionStatusSent(struct wpa_supplicant *wpa_s,
1892 		enum dpp_status_error result)
1893 {
1894 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1895 	callWithEachStaIfaceCallback(aidl_ifname,
1896 			std::bind(&ISupplicantStaIfaceCallback::onDppConnectionStatusResultSent,
1897 					std::placeholders::_1,
1898 					convertSupplicantDppStatusErrorCodeToAidl(result)));
1899 }
1900 
1901 /**
1902  * Notify listener about a DPP failure event
1903  *
1904  * @param ifname Interface name
1905  * @param code Status code
1906  */
notifyDppFailure(struct wpa_supplicant * wpa_s,android::hardware::wifi::supplicant::DppFailureCode code)1907 void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
1908 		android::hardware::wifi::supplicant::DppFailureCode code) {
1909 	notifyDppFailure(wpa_s, code, NULL, NULL, NULL, 0);
1910 }
1911 
1912 /**
1913  * Notify listener about a DPP failure event
1914  *
1915  * @param ifname Interface name
1916  * @param code Status code
1917  */
notifyDppFailure(struct wpa_supplicant * wpa_s,DppFailureCode code,const char * ssid,const char * channel_list,unsigned short band_list[],int size)1918 void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
1919 		DppFailureCode code, const char *ssid, const char *channel_list,
1920 		unsigned short band_list[], int size) {
1921 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1922 	std::vector<char16_t> band_list_vec(band_list, band_list + size);
1923 
1924 	callWithEachStaIfaceCallback(aidl_ifname,
1925 			std::bind(&ISupplicantStaIfaceCallback::onDppFailure,
1926 					std::placeholders::_1, code, misc_utils::charBufToString(ssid),
1927 					misc_utils::charBufToString(channel_list), band_list_vec));
1928 }
1929 
1930 /**
1931  * Notify listener about a DPP progress event
1932  *
1933  * @param ifname Interface name
1934  * @param code Status code
1935  */
notifyDppProgress(struct wpa_supplicant * wpa_s,DppProgressCode code)1936 void AidlManager::notifyDppProgress(
1937 		struct wpa_supplicant *wpa_s, DppProgressCode code) {
1938 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1939 
1940 	callWithEachStaIfaceCallback(aidl_ifname,
1941 			std::bind(&ISupplicantStaIfaceCallback::onDppProgress,
1942 					std::placeholders::_1, code));
1943 }
1944 
1945 /**
1946  * Notify listener about a DPP success event
1947  *
1948  * @param ifname Interface name
1949  * @param code Status code
1950  */
notifyDppSuccess(struct wpa_supplicant * wpa_s,DppEventType code)1951 void AidlManager::notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code)
1952 {
1953 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1954 
1955 	callWithEachStaIfaceCallback(aidl_ifname,
1956 			std::bind(&ISupplicantStaIfaceCallback::onDppSuccess,
1957 					std::placeholders::_1, code));
1958 }
1959 
1960 /**
1961  * Notify listener about a PMK cache added event
1962  *
1963  * @param ifname Interface name
1964  * @param entry PMK cache entry
1965  */
notifyPmkCacheAdded(struct wpa_supplicant * wpa_s,struct rsn_pmksa_cache_entry * pmksa_entry)1966 void AidlManager::notifyPmkCacheAdded(
1967 	struct wpa_supplicant *wpa_s, struct rsn_pmksa_cache_entry *pmksa_entry)
1968 {
1969 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
1970 
1971 	PmkSaCacheData aidl_pmksa_data = {};
1972 	aidl_pmksa_data.bssid = macAddrToArray(pmksa_entry->aa);
1973 	// Serialize PmkCacheEntry into blob.
1974 	std::stringstream ss(
1975 		std::stringstream::in | std::stringstream::out | std::stringstream::binary);
1976 	misc_utils::serializePmkCacheEntry(ss, pmksa_entry);
1977 	std::vector<uint8_t> serializedEntry(
1978 		std::istreambuf_iterator<char>(ss), {});
1979 	aidl_pmksa_data.serializedEntry = serializedEntry;
1980 	aidl_pmksa_data.expirationTimeInSec = pmksa_entry->expiration;
1981 
1982 	const std::function<
1983 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
1984 		func = std::bind(
1985 		&ISupplicantStaIfaceCallback::onPmkSaCacheAdded,
1986 		std::placeholders::_1, aidl_pmksa_data);
1987 	callWithEachStaIfaceCallback(aidl_ifname, func);
1988 }
1989 
1990 #ifdef CONFIG_WNM
convertSupplicantBssTmStatusToAidl(enum bss_trans_mgmt_status_code bss_tm_status)1991 BssTmStatusCode convertSupplicantBssTmStatusToAidl(
1992 	enum bss_trans_mgmt_status_code bss_tm_status)
1993 {
1994 	switch (bss_tm_status) {
1995 		case WNM_BSS_TM_ACCEPT:
1996 			return BssTmStatusCode::ACCEPT;
1997 		case WNM_BSS_TM_REJECT_UNSPECIFIED:
1998 			return BssTmStatusCode::REJECT_UNSPECIFIED;
1999 		case WNM_BSS_TM_REJECT_INSUFFICIENT_BEACON:
2000 			return BssTmStatusCode::REJECT_INSUFFICIENT_BEACON;
2001 		case WNM_BSS_TM_REJECT_INSUFFICIENT_CAPABITY:
2002 			return BssTmStatusCode::REJECT_INSUFFICIENT_CAPABITY;
2003 		case WNM_BSS_TM_REJECT_UNDESIRED:
2004 			return BssTmStatusCode::REJECT_BSS_TERMINATION_UNDESIRED;
2005 		case WNM_BSS_TM_REJECT_DELAY_REQUEST:
2006 			return BssTmStatusCode::REJECT_BSS_TERMINATION_DELAY_REQUEST;
2007 		case WNM_BSS_TM_REJECT_STA_CANDIDATE_LIST_PROVIDED:
2008 			return BssTmStatusCode::REJECT_STA_CANDIDATE_LIST_PROVIDED;
2009 		case WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES:
2010 			return BssTmStatusCode::REJECT_NO_SUITABLE_CANDIDATES;
2011 		case WNM_BSS_TM_REJECT_LEAVING_ESS:
2012 			return BssTmStatusCode::REJECT_LEAVING_ESS;
2013 		default:
2014 			return BssTmStatusCode::REJECT_UNSPECIFIED;
2015 	}
2016 }
2017 
setBssTmDataFlagsMask(struct wpa_supplicant * wpa_s)2018 BssTmDataFlagsMask setBssTmDataFlagsMask(struct wpa_supplicant *wpa_s)
2019 {
2020 	uint32_t flags = 0;
2021 
2022 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
2023 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_BSS_TERMINATION_INCLUDED);
2024 	}
2025 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
2026 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ESS_DISASSOCIATION_IMMINENT);
2027 	}
2028 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
2029 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_DISASSOCIATION_IMMINENT);
2030 	}
2031 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ABRIDGED) {
2032 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ABRIDGED);
2033 	}
2034 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
2035 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED);
2036 	}
2037 #ifdef CONFIG_MBO
2038 	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
2039 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_ASSOC_RETRY_DELAY_INCLUDED);
2040 	}
2041 	if (wpa_s->wnm_mbo_trans_reason_present) {
2042 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_TRANSITION_REASON_CODE_INCLUDED);
2043 	}
2044 	if (wpa_s->wnm_mbo_cell_pref_present) {
2045 		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED);
2046 	}
2047 #endif
2048 	return static_cast<BssTmDataFlagsMask>(flags);
2049 }
2050 
getBssTmDataAssocRetryDelayMs(struct wpa_supplicant * wpa_s)2051 uint32_t getBssTmDataAssocRetryDelayMs(struct wpa_supplicant *wpa_s)
2052 {
2053 	uint32_t beacon_int;
2054 	uint32_t duration_ms = 0;
2055 
2056 	if (wpa_s->current_bss)
2057 		beacon_int = wpa_s->current_bss->beacon_int;
2058 	else
2059 		beacon_int = 100; /* best guess */
2060 
2061 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
2062 		// number of tbtts to milliseconds
2063 		duration_ms = wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125;
2064 	}
2065 	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
2066 		//wnm_bss_termination_duration contains 12 bytes of BSS
2067 		//termination duration subelement. Format of IE is
2068 		// Sub eid | Length | BSS termination TSF | Duration
2069 		//	1	 1		 8		2
2070 		// Duration indicates number of minutes for which BSS is not
2071 		// present.
2072 		duration_ms = WPA_GET_LE16(wpa_s->wnm_bss_termination_duration + 10);
2073 		// minutes to milliseconds
2074 		duration_ms = duration_ms * 60 * 1000;
2075 	}
2076 #ifdef CONFIG_MBO
2077 	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
2078 		// number of seconds to milliseconds
2079 		duration_ms = wpa_s->wnm_mbo_assoc_retry_delay_sec * 1000;
2080 	}
2081 #endif
2082 
2083 	return duration_ms;
2084 }
2085 #endif
2086 
2087 /**
2088  * Notify listener about the status of BSS transition management
2089  * request frame handling.
2090  *
2091  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
2092  * the network is present.
2093  */
notifyBssTmStatus(struct wpa_supplicant * wpa_s)2094 void AidlManager::notifyBssTmStatus(struct wpa_supplicant *wpa_s)
2095 {
2096 #ifdef CONFIG_WNM
2097 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
2098 	BssTmData aidl_bsstm_data{};
2099 
2100 	aidl_bsstm_data.status = convertSupplicantBssTmStatusToAidl(wpa_s->bss_tm_status);
2101 	aidl_bsstm_data.flags = setBssTmDataFlagsMask(wpa_s);
2102 	aidl_bsstm_data.assocRetryDelayMs = getBssTmDataAssocRetryDelayMs(wpa_s);
2103 #ifdef CONFIG_MBO
2104 	if (wpa_s->wnm_mbo_cell_pref_present) {
2105 		aidl_bsstm_data.mboCellPreference = static_cast
2106 			<MboCellularDataConnectionPrefValue>
2107 			(wpa_s->wnm_mbo_cell_preference);
2108 	}
2109 	if (wpa_s->wnm_mbo_trans_reason_present) {
2110 		aidl_bsstm_data.mboTransitionReason =
2111 			static_cast<MboTransitionReasonCode>
2112 			(wpa_s->wnm_mbo_transition_reason);
2113 	}
2114 #endif
2115 
2116 	const std::function<
2117 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
2118 		func = std::bind(
2119 		&ISupplicantStaIfaceCallback::onBssTmHandlingDone,
2120 		std::placeholders::_1, aidl_bsstm_data);
2121 	callWithEachStaIfaceCallback(aidl_ifname, func);
2122 #endif
2123 }
2124 
setTransitionDisableFlagsMask(u8 bitmap)2125 TransitionDisableIndication setTransitionDisableFlagsMask(u8 bitmap)
2126 {
2127 	uint32_t flags = 0;
2128 
2129 	if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) {
2130 		flags |= static_cast<uint32_t>(TransitionDisableIndication::
2131 			USE_WPA3_PERSONAL);
2132 		bitmap &= ~TRANSITION_DISABLE_WPA3_PERSONAL;
2133 	}
2134 	if (bitmap & TRANSITION_DISABLE_SAE_PK) {
2135 		flags |= static_cast<uint32_t>(TransitionDisableIndication::
2136 			USE_SAE_PK);
2137 		bitmap &= ~TRANSITION_DISABLE_SAE_PK;
2138 	}
2139 	if (bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) {
2140 		flags |= static_cast<uint32_t>(TransitionDisableIndication::
2141 			USE_WPA3_ENTERPRISE);
2142 		bitmap &= ~TRANSITION_DISABLE_WPA3_ENTERPRISE;
2143 	}
2144 	if (bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) {
2145 		flags |= static_cast<uint32_t>(TransitionDisableIndication::
2146 			USE_ENHANCED_OPEN);
2147 		bitmap &= ~TRANSITION_DISABLE_ENHANCED_OPEN;
2148 	}
2149 
2150 	if (bitmap != 0) {
2151 		wpa_printf(MSG_WARNING, "Unhandled transition disable bit: 0x%x", bitmap);
2152 	}
2153 
2154 	return static_cast<TransitionDisableIndication>(flags);
2155 }
2156 
notifyTransitionDisable(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,u8 bitmap)2157 void AidlManager::notifyTransitionDisable(struct wpa_supplicant *wpa_s,
2158 	struct wpa_ssid *ssid, u8 bitmap)
2159 {
2160 	TransitionDisableIndication flag = setTransitionDisableFlagsMask(bitmap);
2161 	const std::function<
2162 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
2163 		func = std::bind(
2164 		&ISupplicantStaNetworkCallback::onTransitionDisable,
2165 		std::placeholders::_1, flag);
2166 
2167 	callWithEachStaNetworkCallback(
2168 		misc_utils::charBufToString(wpa_s->ifname), ssid->id, func);
2169 }
2170 
notifyNetworkNotFound(struct wpa_supplicant * wpa_s)2171 void AidlManager::notifyNetworkNotFound(struct wpa_supplicant *wpa_s)
2172 {
2173 	std::vector<uint8_t> aidl_ssid;
2174 
2175 	if (!wpa_s->current_ssid) {
2176 		wpa_printf(MSG_ERROR, "Current network NULL. Drop WPA_EVENT_NETWORK_NOT_FOUND!");
2177 		return;
2178 	}
2179 
2180 	aidl_ssid.assign(
2181 			wpa_s->current_ssid->ssid,
2182 			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
2183 
2184 	const std::function<
2185 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
2186 		func = std::bind(
2187 		&ISupplicantStaIfaceCallback::onNetworkNotFound,
2188 		std::placeholders::_1, aidl_ssid);
2189 	callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
2190 }
2191 
notifyFrequencyChanged(struct wpa_supplicant * wpa_s,int frequency)2192 void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_s, int frequency)
2193 {
2194 	if (!wpa_s)
2195 		return;
2196 
2197 	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
2198 	struct wpa_supplicant *wpa_p2pdev_s = getTargetP2pIfaceForGroup(wpa_s);
2199 	if (wpa_p2pdev_s) {
2200 		// Notify frequency changed event on P2P interface
2201 		const std::function<
2202 			ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
2203 			func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
2204 			std::placeholders::_1, aidl_ifname, frequency);
2205 		// For group notifications, need to use the parent iface for callbacks.
2206 		callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_p2pdev_s->ifname), func);
2207 	} else if (wpa_s->current_ssid) {
2208 		// Notify frequency changed event on STA interface
2209 		const std::function<
2210 			ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
2211 			func = std::bind(
2212 			&ISupplicantStaIfaceCallback::onBssFrequencyChanged,
2213 			std::placeholders::_1, frequency);
2214 		callWithEachStaIfaceCallback(aidl_ifname, func);
2215 	} else {
2216 		wpa_printf(MSG_INFO, "Drop frequency changed event");
2217 		return;
2218         }
2219 }
2220 
notifyCertification(struct wpa_supplicant * wpa_s,int depth,const char * subject,const char * altsubject[],int num_altsubject,const char * cert_hash,const struct wpabuf * cert)2221 void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
2222 		int depth, const char *subject,
2223 		const char *altsubject[],
2224 		int num_altsubject,
2225 		const char *cert_hash,
2226 		const struct wpabuf *cert)
2227 {
2228 	if (!wpa_s->current_ssid) {
2229 		wpa_printf(MSG_ERROR, "Current network NULL. Drop Certification event!");
2230 		return;
2231 	}
2232 	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
2233 	if (!wpa_key_mgmt_wpa_ieee8021x(current_ssid->key_mgmt)) {
2234 		return;
2235 	}
2236 	if (NULL == subject || NULL == cert_hash || NULL == cert) {
2237 		wpa_printf(MSG_ERROR,
2238 				"Incomplete certificate information. Drop Certification event!");
2239 		return;
2240 	}
2241 	if (current_ssid->eap.cert.ca_cert) {
2242 		return;
2243 	}
2244 
2245 	wpa_printf(MSG_DEBUG, "notifyCertification: depth=%d subject=%s hash=%s cert-size=%zu",
2246 			depth, subject, cert_hash, cert->used);
2247 	std::vector<uint8_t> subjectBlob(subject, subject + strlen(subject));
2248 	std::vector<uint8_t> certHashBlob(cert_hash, cert_hash + strlen(cert_hash));
2249 	std::vector<uint8_t> certBlob(cert->buf, cert->buf + cert->used);
2250 
2251 	const std::function<
2252 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
2253 		func = std::bind(
2254 		&ISupplicantStaNetworkCallback::onServerCertificateAvailable,
2255 		std::placeholders::_1,
2256 		depth,
2257 		subjectBlob,
2258 		certHashBlob,
2259 		certBlob);
2260 
2261 	callWithEachStaNetworkCallback(
2262 		misc_utils::charBufToString(wpa_s->ifname), current_ssid->id, func);
2263 }
2264 
notifyAuxiliaryEvent(struct wpa_supplicant * wpa_s,AuxiliarySupplicantEventCode event_code,const char * reason_string)2265 void AidlManager::notifyAuxiliaryEvent(struct wpa_supplicant *wpa_s,
2266 	AuxiliarySupplicantEventCode event_code, const char *reason_string)
2267 {
2268 	if (!wpa_s)
2269 		return;
2270 
2271 	const std::function<
2272 		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
2273 		func = std::bind(
2274 		&ISupplicantStaIfaceCallback::onAuxiliarySupplicantEvent,
2275 		std::placeholders::_1, event_code, macAddrToVec(wpa_s->bssid),
2276 		misc_utils::charBufToString(reason_string));
2277 	callWithEachStaIfaceCallback(
2278 		misc_utils::charBufToString(wpa_s->ifname), func);
2279 }
2280 
2281 /**
2282  * Retrieve the |ISupplicantP2pIface| aidl object reference using the provided
2283  * ifname.
2284  *
2285  * @param ifname Name of the corresponding interface.
2286  * @param iface_object Aidl reference corresponding to the iface.
2287  *
2288  * @return 0 on success, 1 on failure.
2289  */
getP2pIfaceAidlObjectByIfname(const std::string & ifname,std::shared_ptr<ISupplicantP2pIface> * iface_object)2290 int AidlManager::getP2pIfaceAidlObjectByIfname(
2291 	const std::string &ifname, std::shared_ptr<ISupplicantP2pIface> *iface_object)
2292 {
2293 	if (ifname.empty() || !iface_object)
2294 		return 1;
2295 
2296 	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
2297 	if (iface_object_iter == p2p_iface_object_map_.end())
2298 		return 1;
2299 
2300 	*iface_object = iface_object_iter->second;
2301 	return 0;
2302 }
2303 
2304 /**
2305  * Retrieve the |ISupplicantStaIface| aidl object reference using the provided
2306  * ifname.
2307  *
2308  * @param ifname Name of the corresponding interface.
2309  * @param iface_object Aidl reference corresponding to the iface.
2310  *
2311  * @return 0 on success, 1 on failure.
2312  */
getStaIfaceAidlObjectByIfname(const std::string & ifname,std::shared_ptr<ISupplicantStaIface> * iface_object)2313 int AidlManager::getStaIfaceAidlObjectByIfname(
2314 	const std::string &ifname, std::shared_ptr<ISupplicantStaIface> *iface_object)
2315 {
2316 	if (ifname.empty() || !iface_object)
2317 		return 1;
2318 
2319 	auto iface_object_iter = sta_iface_object_map_.find(ifname);
2320 	if (iface_object_iter == sta_iface_object_map_.end())
2321 		return 1;
2322 
2323 	*iface_object = iface_object_iter->second;
2324 	return 0;
2325 }
2326 
2327 /**
2328  * Retrieve the |ISupplicantP2pNetwork| aidl object reference using the provided
2329  * ifname and network_id.
2330  *
2331  * @param ifname Name of the corresponding interface.
2332  * @param network_id ID of the corresponding network.
2333  * @param network_object Aidl reference corresponding to the network.
2334  *
2335  * @return 0 on success, 1 on failure.
2336  */
getP2pNetworkAidlObjectByIfnameAndNetworkId(const std::string & ifname,int network_id,std::shared_ptr<ISupplicantP2pNetwork> * network_object)2337 int AidlManager::getP2pNetworkAidlObjectByIfnameAndNetworkId(
2338 	const std::string &ifname, int network_id,
2339 	std::shared_ptr<ISupplicantP2pNetwork> *network_object)
2340 {
2341 	if (ifname.empty() || network_id < 0 || !network_object)
2342 		return 1;
2343 
2344 	// Generate the key to be used to lookup the network.
2345 	const std::string network_key =
2346 		getNetworkObjectMapKey(ifname, network_id);
2347 
2348 	auto network_object_iter = p2p_network_object_map_.find(network_key);
2349 	if (network_object_iter == p2p_network_object_map_.end())
2350 		return 1;
2351 
2352 	*network_object = network_object_iter->second;
2353 	return 0;
2354 }
2355 
2356 /**
2357  * Retrieve the |ISupplicantStaNetwork| aidl object reference using the provided
2358  * ifname and network_id.
2359  *
2360  * @param ifname Name of the corresponding interface.
2361  * @param network_id ID of the corresponding network.
2362  * @param network_object Aidl reference corresponding to the network.
2363  *
2364  * @return 0 on success, 1 on failure.
2365  */
getStaNetworkAidlObjectByIfnameAndNetworkId(const std::string & ifname,int network_id,std::shared_ptr<ISupplicantStaNetwork> * network_object)2366 int AidlManager::getStaNetworkAidlObjectByIfnameAndNetworkId(
2367 	const std::string &ifname, int network_id,
2368 	std::shared_ptr<ISupplicantStaNetwork> *network_object)
2369 {
2370 	if (ifname.empty() || network_id < 0 || !network_object)
2371 		return 1;
2372 
2373 	// Generate the key to be used to lookup the network.
2374 	const std::string network_key =
2375 		getNetworkObjectMapKey(ifname, network_id);
2376 
2377 	auto network_object_iter = sta_network_object_map_.find(network_key);
2378 	if (network_object_iter == sta_network_object_map_.end())
2379 		return 1;
2380 
2381 	*network_object = network_object_iter->second;
2382 	return 0;
2383 }
2384 
2385 /**
2386  * Add a new |ISupplicantCallback| aidl object reference to our
2387  * global callback list.
2388  *
2389  * @param callback Aidl reference of the |ISupplicantCallback| object.
2390  *
2391  * @return 0 on success, 1 on failure.
2392  */
addSupplicantCallbackAidlObject(const std::shared_ptr<ISupplicantCallback> & callback)2393 int AidlManager::addSupplicantCallbackAidlObject(
2394 	const std::shared_ptr<ISupplicantCallback> &callback)
2395 {
2396 	return registerForDeathAndAddCallbackAidlObjectToList<
2397 		ISupplicantCallback>(
2398 		death_notifier_, callback, supplicant_callbacks_);
2399 }
2400 
2401 /**
2402  * Store the |INonStandardCertCallback| aidl object reference.
2403  *
2404  * @param callback Aidl reference of the |INonStandardCertCallback| object.
2405  *
2406  * @return 0 on success, 1 on failure.
2407  */
registerNonStandardCertCallbackAidlObject(const std::shared_ptr<INonStandardCertCallback> & callback)2408 int AidlManager::registerNonStandardCertCallbackAidlObject(
2409 	const std::shared_ptr<INonStandardCertCallback> &callback)
2410 {
2411 	if (callback == nullptr) return 1;
2412 	non_standard_cert_callback_ = callback;
2413 	return 0;
2414 }
2415 
2416 /**
2417  * Add a new iface callback aidl object reference to our
2418  * interface callback list.
2419  *
2420  * @param ifname Name of the corresponding interface.
2421  * @param callback Aidl reference of the callback object.
2422  *
2423  * @return 0 on success, 1 on failure.
2424  */
addP2pIfaceCallbackAidlObject(const std::string & ifname,const std::shared_ptr<ISupplicantP2pIfaceCallback> & callback)2425 int AidlManager::addP2pIfaceCallbackAidlObject(
2426 	const std::string &ifname,
2427 	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
2428 {
2429 	return addIfaceCallbackAidlObjectToMap(
2430 		death_notifier_, ifname, callback, p2p_iface_callbacks_map_);
2431 }
2432 
2433 /**
2434  * Add a new iface callback aidl object reference to our
2435  * interface callback list.
2436  *
2437  * @param ifname Name of the corresponding interface.
2438  * @param callback Aidl reference of the callback object.
2439  *
2440  * @return 0 on success, 1 on failure.
2441  */
addStaIfaceCallbackAidlObject(const std::string & ifname,const std::shared_ptr<ISupplicantStaIfaceCallback> & callback)2442 int AidlManager::addStaIfaceCallbackAidlObject(
2443 	const std::string &ifname,
2444 	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
2445 {
2446 	return addIfaceCallbackAidlObjectToMap(
2447 		death_notifier_, ifname, callback, sta_iface_callbacks_map_);
2448 }
2449 
2450 /**
2451  * Add a new network callback aidl object reference to our network callback
2452  * list.
2453  *
2454  * @param ifname Name of the corresponding interface.
2455  * @param network_id ID of the corresponding network.
2456  * @param callback Aidl reference of the callback object.
2457  *
2458  * @return 0 on success, 1 on failure.
2459  */
addStaNetworkCallbackAidlObject(const std::string & ifname,int network_id,const std::shared_ptr<ISupplicantStaNetworkCallback> & callback)2460 int AidlManager::addStaNetworkCallbackAidlObject(
2461 	const std::string &ifname, int network_id,
2462 	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
2463 {
2464 	return addNetworkCallbackAidlObjectToMap(
2465 		death_notifier_, ifname, network_id, callback,
2466 		sta_network_callbacks_map_);
2467 }
2468 
2469 /**
2470  * Finds the correct |wpa_supplicant| object for P2P notifications
2471  *
2472  * @param wpa_s the |wpa_supplicant| that triggered the P2P event.
2473  * @return appropriate |wpa_supplicant| object or NULL if not found.
2474  */
getTargetP2pIfaceForGroup(struct wpa_supplicant * wpa_group_s)2475 struct wpa_supplicant *AidlManager::getTargetP2pIfaceForGroup(
2476 		struct wpa_supplicant *wpa_group_s)
2477 {
2478 	if (!wpa_group_s || !wpa_group_s->parent)
2479 		return NULL;
2480 
2481 	struct wpa_supplicant *target_wpa_s = wpa_group_s->parent;
2482 
2483 	// check wpa_supplicant object is a p2p device interface
2484 	if ((wpa_group_s == wpa_group_s->p2pdev) && wpa_group_s->p2p_mgmt) {
2485 		if (p2p_iface_object_map_.find(wpa_group_s->ifname) !=
2486 			p2p_iface_object_map_.end())
2487 			return wpa_group_s;
2488 	}
2489 
2490 	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
2491 		p2p_iface_object_map_.end())
2492 		return target_wpa_s;
2493 
2494 	// try P2P device if available
2495 	if (!target_wpa_s->p2pdev || !target_wpa_s->p2pdev->p2p_mgmt)
2496 		return NULL;
2497 
2498 	target_wpa_s = target_wpa_s->p2pdev;
2499 	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
2500 		p2p_iface_object_map_.end())
2501 		return target_wpa_s;
2502 
2503 	return NULL;
2504 }
2505 
2506 /**
2507  * Removes the provided |ISupplicantCallback| aidl object reference
2508  * from our global callback list.
2509  *
2510  * @param callback Aidl reference of the |ISupplicantCallback| object.
2511  */
removeSupplicantCallbackAidlObject(const std::shared_ptr<ISupplicantCallback> & callback)2512 void AidlManager::removeSupplicantCallbackAidlObject(
2513 	const std::shared_ptr<ISupplicantCallback> &callback)
2514 {
2515 	supplicant_callbacks_.erase(
2516 		std::remove(
2517 		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
2518 		callback),
2519 		supplicant_callbacks_.end());
2520 }
2521 
2522 /**
2523  * Removes the provided iface callback aidl object reference from
2524  * our interface callback list.
2525  *
2526  * @param ifname Name of the corresponding interface.
2527  * @param callback Aidl reference of the callback object.
2528  */
removeP2pIfaceCallbackAidlObject(const std::string & ifname,const std::shared_ptr<ISupplicantP2pIfaceCallback> & callback)2529 void AidlManager::removeP2pIfaceCallbackAidlObject(
2530 	const std::string &ifname,
2531 	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
2532 {
2533 	return removeIfaceCallbackAidlObjectFromMap(
2534 		ifname, callback, p2p_iface_callbacks_map_);
2535 }
2536 
2537 /**
2538  * Removes the provided iface callback aidl object reference from
2539  * our interface callback list.
2540  *
2541  * @param ifname Name of the corresponding interface.
2542  * @param callback Aidl reference of the callback object.
2543  */
removeStaIfaceCallbackAidlObject(const std::string & ifname,const std::shared_ptr<ISupplicantStaIfaceCallback> & callback)2544 void AidlManager::removeStaIfaceCallbackAidlObject(
2545 	const std::string &ifname,
2546 	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
2547 {
2548 	return removeIfaceCallbackAidlObjectFromMap(
2549 		ifname, callback, sta_iface_callbacks_map_);
2550 }
2551 
2552 /**
2553  * Removes the provided network callback aidl object reference from
2554  * our network callback list.
2555  *
2556  * @param ifname Name of the corresponding interface.
2557  * @param network_id ID of the corresponding network.
2558  * @param callback Aidl reference of the callback object.
2559  */
removeStaNetworkCallbackAidlObject(const std::string & ifname,int network_id,const std::shared_ptr<ISupplicantStaNetworkCallback> & callback)2560 void AidlManager::removeStaNetworkCallbackAidlObject(
2561 	const std::string &ifname, int network_id,
2562 	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
2563 {
2564 	return removeNetworkCallbackAidlObjectFromMap(
2565 		ifname, network_id, callback, sta_network_callbacks_map_);
2566 }
2567 
2568 /**
2569  * Helper function to invoke the provided callback method on all the
2570  * registered |ISupplicantCallback| callback aidl objects.
2571  *
2572  * @param method Pointer to the required aidl method from
2573  * |ISupplicantCallback|.
2574  */
callWithEachSupplicantCallback(const std::function<ndk::ScopedAStatus (std::shared_ptr<ISupplicantCallback>)> & method)2575 void AidlManager::callWithEachSupplicantCallback(
2576 	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantCallback>)> &method)
2577 {
2578 	for (const auto &callback : supplicant_callbacks_) {
2579 		if (!method(callback).isOk()) {
2580 			wpa_printf(MSG_ERROR, "Failed to invoke AIDL callback");
2581 		}
2582 	}
2583 }
2584 
2585 /**
2586  * Helper function to invoke the provided callback method on all the
2587  * registered iface callback aidl objects for the specified
2588  * |ifname|.
2589  *
2590  * @param ifname Name of the corresponding interface.
2591  * @param method Pointer to the required aidl method from
2592  * |ISupplicantIfaceCallback|.
2593  */
callWithEachP2pIfaceCallback(const std::string & ifname,const std::function<ndk::ScopedAStatus (std::shared_ptr<ISupplicantP2pIfaceCallback>)> & method)2594 void AidlManager::callWithEachP2pIfaceCallback(
2595 	const std::string &ifname,
2596 	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
2597 	&method)
2598 {
2599 	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
2600 }
2601 
2602 /**
2603  * Helper function to invoke the provided callback method on all the
2604  * registered interface callback aidl objects for the specified
2605  * |ifname|.
2606  *
2607  * @param ifname Name of the corresponding interface.
2608  * @param method Pointer to the required aidl method from
2609  * |ISupplicantIfaceCallback|.
2610  */
callWithEachStaIfaceCallback(const std::string & ifname,const std::function<ndk::ScopedAStatus (std::shared_ptr<ISupplicantStaIfaceCallback>)> & method)2611 void AidlManager::callWithEachStaIfaceCallback(
2612 	const std::string &ifname,
2613 	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
2614 	&method)
2615 {
2616 	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
2617 }
2618 
2619 /**
2620  * Helper function to invoke the provided callback method on all the
2621  * registered network callback aidl objects for the specified
2622  * |ifname| & |network_id|.
2623  *
2624  * @param ifname Name of the corresponding interface.
2625  * @param network_id ID of the corresponding network.
2626  * @param method Pointer to the required aidl method from
2627  * |ISupplicantStaNetworkCallback|.
2628  */
callWithEachStaNetworkCallback(const std::string & ifname,int network_id,const std::function<ndk::ScopedAStatus (std::shared_ptr<ISupplicantStaNetworkCallback>)> & method)2629 void AidlManager::callWithEachStaNetworkCallback(
2630 	const std::string &ifname, int network_id,
2631 	const std::function<
2632 	ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)> &method)
2633 {
2634 	callWithEachNetworkCallback(
2635 		ifname, network_id, method, sta_network_callbacks_map_);
2636 }
2637 
notifyQosPolicyReset(struct wpa_supplicant * wpa_s)2638 void AidlManager::notifyQosPolicyReset(
2639 	struct wpa_supplicant *wpa_s)
2640 {
2641 	if (!wpa_s)
2642 		return;
2643 
2644 	callWithEachStaIfaceCallback(
2645 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
2646 			&ISupplicantStaIfaceCallback::onQosPolicyReset,
2647 			std::placeholders::_1));
2648 }
2649 
notifyQosPolicyRequest(struct wpa_supplicant * wpa_s,struct dscp_policy_data * policies,int num_policies)2650 void AidlManager::notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
2651 	struct dscp_policy_data *policies, int num_policies)
2652 {
2653 	if (!wpa_s || !policies)
2654 		return;
2655 
2656 	std::vector<QosPolicyData> qosPolicyData;
2657 	uint32_t mask = 0;
2658 
2659 	for (int num = 0; num < num_policies; num++) {
2660 		QosPolicyData policy;
2661 		QosPolicyClassifierParams classifier_params;
2662 		QosPolicyClassifierParamsMask classifier_param_mask;
2663 		bool ip_ver4 = false;
2664 
2665 		if (policies[num].type4_param.ip_version == 4) {
2666 			classifier_params.ipVersion = IpVersion::VERSION_4;
2667 			ip_ver4 = true;
2668 		} else {
2669 			classifier_params.ipVersion = IpVersion::VERSION_6;
2670 			ip_ver4 = false;
2671 		}
2672 
2673 		// classifier_mask parameters are defined in IEEE Std 802.11-2020, Table 9-170
2674 		if (policies[num].type4_param.classifier_mask & BIT(1)) {
2675 			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_IP);
2676 			if (ip_ver4) {
2677 				classifier_params.srcIp =
2678 					byteArrToVec((const uint8_t *)
2679 						&policies[num].type4_param.ip_params.v4.src_ip, 4);
2680 			} else {
2681 				classifier_params.srcIp =
2682 					byteArrToVec((const uint8_t *)
2683 						&policies[num].type4_param.ip_params.v6.src_ip, 16);
2684 			}
2685 		}
2686 		if (policies[num].type4_param.classifier_mask & BIT(2)) {
2687 			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DST_IP);
2688 			if (ip_ver4){
2689 				classifier_params.dstIp =
2690 					byteArrToVec((const uint8_t *)
2691 						&policies[num].type4_param.ip_params.v4.dst_ip, 4);
2692 			} else {
2693 				classifier_params.dstIp =
2694 					byteArrToVec((const uint8_t *)
2695 						&policies[num].type4_param.ip_params.v6.dst_ip, 16);
2696 			}
2697 		}
2698 		if (policies[num].type4_param.classifier_mask & BIT(3)) {
2699 			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_PORT);
2700 			if (ip_ver4){
2701 				classifier_params.srcPort =
2702 					policies[num].type4_param.ip_params.v4.src_port;
2703 			} else {
2704 				classifier_params.srcPort =
2705 					policies[num].type4_param.ip_params.v6.src_port;
2706 			}
2707 		}
2708 
2709 		if (policies[num].type4_param.classifier_mask & BIT(4)) {
2710 			mask |= static_cast<uint32_t>(
2711 				QosPolicyClassifierParamsMask::DST_PORT_RANGE);
2712 			if (ip_ver4) {
2713 				classifier_params.dstPortRange.startPort =
2714 					policies[num].type4_param.ip_params.v4.dst_port;
2715 				classifier_params.dstPortRange.endPort =
2716 					policies[num].type4_param.ip_params.v4.dst_port;
2717 			} else {
2718 				classifier_params.dstPortRange.startPort =
2719 					policies[num].type4_param.ip_params.v6.dst_port;
2720 				classifier_params.dstPortRange.endPort =
2721 					policies[num].type4_param.ip_params.v6.dst_port;
2722 			}
2723 		} else if (policies[num].port_range_info) {
2724 			mask |= static_cast<uint32_t>(
2725 				QosPolicyClassifierParamsMask::DST_PORT_RANGE);
2726 			classifier_params.dstPortRange.startPort = policies[num].start_port;
2727 			classifier_params.dstPortRange.endPort = policies[num].end_port;
2728 		}
2729 		if (policies[num].type4_param.classifier_mask & BIT(6)) {
2730 			mask |= static_cast<uint32_t>(
2731 				QosPolicyClassifierParamsMask::PROTOCOL_NEXT_HEADER);
2732 			if (ip_ver4) {
2733 				classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
2734 					policies[num].type4_param.ip_params.v4.protocol);
2735 			} else {
2736 				classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
2737 					policies[num].type4_param.ip_params.v6.next_header);
2738 			}
2739 		}
2740 		if (policies[num].type4_param.classifier_mask & BIT(7)) {
2741 			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::FLOW_LABEL);
2742 			classifier_params.flowLabelIpv6 =
2743 				byteArrToVec(policies[num].type4_param.ip_params.v6.flow_label, 3);
2744 		}
2745 		if (policies[num].domain_name_len != 0) {
2746 			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DOMAIN_NAME);
2747 			classifier_params.domainName =
2748 				misc_utils::charBufToString(
2749 					reinterpret_cast<const char *>(policies[num].domain_name));
2750 		}
2751 
2752 		classifier_params.classifierParamMask =
2753 			static_cast<QosPolicyClassifierParamsMask>(mask);
2754 		policy.policyId = policies[num].policy_id;
2755 		policy.requestType = static_cast<QosPolicyRequestType>(policies[num].req_type);
2756 		policy.dscp = policies[num].dscp;
2757 		policy.classifierParams = classifier_params;
2758 
2759 		qosPolicyData.push_back(policy);
2760 	}
2761 
2762 	callWithEachStaIfaceCallback(
2763 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
2764 			&ISupplicantStaIfaceCallback::onQosPolicyRequest,
2765 			std::placeholders::_1, wpa_s->dscp_req_dialog_token, qosPolicyData));
2766 }
2767 
notifyMloLinksInfoChanged(struct wpa_supplicant * wpa_s,enum mlo_info_change_reason reason)2768 void AidlManager::notifyMloLinksInfoChanged(struct wpa_supplicant *wpa_s,
2769 					    enum mlo_info_change_reason reason)
2770 {
2771 	if (!wpa_s)
2772 		return;
2773 
2774 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
2775 		sta_iface_object_map_.end())
2776 		return;
2777 
2778 	callWithEachStaIfaceCallback(
2779 		misc_utils::charBufToString(wpa_s->ifname),
2780 		std::bind(&ISupplicantStaIfaceCallback::onMloLinksInfoChanged,
2781 			  std::placeholders::_1,
2782 			  static_cast<ISupplicantStaIfaceCallback::MloLinkInfoChangeReason>(reason)));
2783 }
2784 
getCertificate(const char * alias,uint8_t ** value)2785 ssize_t AidlManager::getCertificate(const char* alias, uint8_t** value) {
2786 	if (alias == nullptr || value == nullptr) {
2787 		wpa_printf(MSG_ERROR, "Null pointer argument was passed to getCertificate");
2788 		return -1;
2789 	}
2790 	if (auto cert = certificate_utils::getCertificate(alias, non_standard_cert_callback_)) {
2791 		*value = (uint8_t *) os_malloc(cert->size());
2792 		if (*value == nullptr) return -1;
2793 		os_memcpy(*value, cert->data(), cert->size());
2794 		return cert->size();
2795 	}
2796 	return -1;
2797 }
2798 
listAliases(const char * prefix,char *** aliases)2799 ssize_t AidlManager::listAliases(const char *prefix, char ***aliases) {
2800 	if (prefix == nullptr || aliases == nullptr) {
2801 		wpa_printf(MSG_ERROR, "Null pointer argument was passed to listAliases");
2802 		return -1;
2803 	}
2804 
2805 	if (auto results =
2806 			certificate_utils::listAliases(prefix, non_standard_cert_callback_)) {
2807 		int count = results->size();
2808 		*aliases = (char **) os_malloc(sizeof(char *) * count);
2809 		if (*aliases == nullptr) {
2810 			wpa_printf(MSG_ERROR, "listAliases: os_malloc alias array error");
2811 			return -1;
2812 		}
2813 		os_memset(*aliases, 0, sizeof(char *) * count);
2814 
2815 		int index = 0;
2816 		for (auto it = results->begin(); it != results->end(); ++it) {
2817 			int alias_len = it->length();
2818 			char *alias = (char *) os_malloc(alias_len + 1);
2819 			if (alias == nullptr) {
2820 				wpa_printf(MSG_ERROR, "listAliases: os_malloc alias string error");
2821 				for (int i = 0; i < index; ++i) os_free((*aliases)[i]);
2822 				os_free(*aliases);
2823 				return -1;
2824 			}
2825 			os_memcpy(alias, it->data(), alias_len + 1);
2826 			(*aliases)[index] = alias;
2827 			index++;
2828 		}
2829 		return count;
2830 	}
2831 	return -1;
2832 }
2833 
getQosPolicyScsResponseStatusCode(int scsResponseCode)2834 QosPolicyScsResponseStatusCode getQosPolicyScsResponseStatusCode(int scsResponseCode)
2835 {
2836 	QosPolicyScsResponseStatusCode status = QosPolicyScsResponseStatusCode::TIMEOUT;
2837 	/* Status code as per Ieee802.11-2020 Table 9-50—Status codes */
2838 	switch (scsResponseCode) {
2839 		case 0: /* SUCCESS */
2840 			status = QosPolicyScsResponseStatusCode::SUCCESS;
2841 			break;
2842 		case 37: /* REQUEST_DECLINED */
2843 			status = QosPolicyScsResponseStatusCode::TCLAS_REQUEST_DECLINED;
2844 			break;
2845 		case 56: /* REQUESTED_TCLAS_NOT_SUPPORTED */
2846 		case 80: /* REQUESTED_TCLAS_NOT_SUPPORTED */
2847 			status = QosPolicyScsResponseStatusCode::TCLAS_NOT_SUPPORTED_BY_AP;
2848 			break;
2849 		case 57: /* INSUFFICIENT_TCLAS_PROCESSING_RESOURCES */
2850 			status = QosPolicyScsResponseStatusCode::TCLAS_INSUFFICIENT_RESOURCES;
2851 			break;
2852 		case 81: /* TCLAS_RESOURCES_EXHAUSTED */
2853 			status = QosPolicyScsResponseStatusCode::TCLAS_RESOURCES_EXHAUSTED;
2854 			break;
2855 		case 128: /* TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS */
2856 			status = QosPolicyScsResponseStatusCode::TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS;
2857 			break;
2858 		case 129: /* TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT */
2859 			status = QosPolicyScsResponseStatusCode::TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT;
2860 			break;
2861 		case 97: /* TCLAS_PROCESSING_TERMINATED */
2862 			status = QosPolicyScsResponseStatusCode::TCLAS_PROCESSING_TERMINATED;
2863 			break;
2864 		default:
2865 			status = QosPolicyScsResponseStatusCode::TIMEOUT;
2866 			break;
2867 		return status;
2868 	}
2869 	return status;
2870 }
2871 
notifyQosPolicyScsResponse(struct wpa_supplicant * wpa_s,unsigned int count,int ** scs_resp)2872 void AidlManager::notifyQosPolicyScsResponse(struct wpa_supplicant *wpa_s,
2873 		unsigned int count, int **scs_resp)
2874 {
2875 	if (!wpa_s || !count || !scs_resp)
2876 		return;
2877 
2878 	std::vector<QosPolicyScsResponseStatus> scsResponses;
2879 
2880 	for (int i = 0; i < count; i++) {
2881 		QosPolicyScsResponseStatus resp;
2882 		resp.policyId = scs_resp[0][i] & 0xFF;
2883 		resp.qosPolicyScsResponseStatusCode = getQosPolicyScsResponseStatusCode(scs_resp[1][i]);
2884 		scsResponses.push_back(resp);
2885 	}
2886 	callWithEachStaIfaceCallback(
2887 		misc_utils::charBufToString(wpa_s->ifname), std::bind(
2888 			&ISupplicantStaIfaceCallback::onQosPolicyResponseForScs,
2889 			std::placeholders::_1, scsResponses));
2890 }
2891 
2892 }  // namespace supplicant
2893 }  // namespace wifi
2894 }  // namespace hardware
2895 }  // namespace android
2896 }  // namespace aidl
2897