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