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