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