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