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