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 <regex>
12 
13 #include "hidl_manager.h"
14 #include "misc_utils.h"
15 
16 extern "C" {
17 #include "scan.h"
18 #include "src/eap_common/eap_sim_common.h"
19 }
20 
21 namespace {
22 using android::hardware::hidl_array;
23 using namespace android::hardware::wifi::supplicant::V1_2;
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 CallbackTypeV1_0, class CallbackTypeV1_1>
callWithEachIfaceCallback_1_1(const std::string & ifname,const std::function<android::hardware::Return<void> (android::sp<CallbackTypeV1_1>)> & method,const std::map<const std::string,std::vector<android::sp<CallbackTypeV1_0>>> & callbacks_map)293 void callWithEachIfaceCallback_1_1(
294     const std::string &ifname,
295     const std::function<
296 	android::hardware::Return<void>(android::sp<CallbackTypeV1_1>)> &method,
297     const std::map<
298 	const std::string, std::vector<android::sp<CallbackTypeV1_0>>>
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<CallbackTypeV1_1> callback_1_1 =
310 		    CallbackTypeV1_1::castFrom(callback);
311 		if (callback_1_1 == nullptr)
312 			continue;
313 
314 		if (!method(callback_1_1).isOk()) {
315 			wpa_printf(
316 			    MSG_ERROR, "Failed to invoke HIDL iface callback");
317 		}
318 	}
319 }
320 
321 template <class CallbackTypeV1_0, class CallbackTypeV1_2>
callWithEachIfaceCallback_1_2(const std::string & ifname,const std::function<android::hardware::Return<void> (android::sp<CallbackTypeV1_2>)> & method,const std::map<const std::string,std::vector<android::sp<CallbackTypeV1_0>>> & callbacks_map)322 void callWithEachIfaceCallback_1_2(
323     const std::string &ifname,
324     const std::function<
325 	android::hardware::Return<void>(android::sp<CallbackTypeV1_2>)> &method,
326     const std::map<
327 	const std::string, std::vector<android::sp<CallbackTypeV1_0>>>
328 	&callbacks_map)
329 {
330 	if (ifname.empty())
331 		return;
332 
333 	auto iface_callback_map_iter = callbacks_map.find(ifname);
334 	if (iface_callback_map_iter == callbacks_map.end())
335 		return;
336 	const auto &iface_callback_list = iface_callback_map_iter->second;
337 	for (const auto &callback : iface_callback_list) {
338 		android::sp<CallbackTypeV1_2> callback_1_2 =
339 		    CallbackTypeV1_2::castFrom(callback);
340 		if (callback_1_2 == nullptr)
341 			continue;
342 
343 		if (!method(callback_1_2).isOk()) {
344 			wpa_printf(
345 			    MSG_ERROR, "Failed to invoke HIDL iface callback");
346 		}
347 	}
348 }
349 
350 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)351 void callWithEachNetworkCallback(
352     const std::string &ifname, int network_id,
353     const std::function<
354 	android::hardware::Return<void>(android::sp<CallbackType>)> &method,
355     const std::map<const std::string, std::vector<android::sp<CallbackType>>>
356 	&callbacks_map)
357 {
358 	if (ifname.empty() || network_id < 0)
359 		return;
360 
361 	// Generate the key to be used to lookup the network.
362 	const std::string network_key =
363 	    getNetworkObjectMapKey(ifname, network_id);
364 	auto network_callback_map_iter = callbacks_map.find(network_key);
365 	if (network_callback_map_iter == callbacks_map.end())
366 		return;
367 	const auto &network_callback_list = network_callback_map_iter->second;
368 	for (const auto &callback : network_callback_list) {
369 		if (!method(callback).isOk()) {
370 			wpa_printf(
371 			    MSG_ERROR,
372 			    "Failed to invoke HIDL network callback");
373 		}
374 	}
375 }
376 
parseGsmAuthNetworkRequest(const std::string & params_str,std::vector<hidl_array<uint8_t,kGsmRandLenBytes>> * out_rands)377 int parseGsmAuthNetworkRequest(
378     const std::string &params_str,
379     std::vector<hidl_array<uint8_t, kGsmRandLenBytes>> *out_rands)
380 {
381 	std::smatch matches;
382 	std::regex params_gsm_regex2(kGsmAuthRegex2);
383 	std::regex params_gsm_regex3(kGsmAuthRegex3);
384 	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
385 	    !std::regex_match(params_str, matches, params_gsm_regex2)) {
386 		return 1;
387 	}
388 	for (uint32_t i = 1; i < matches.size(); i++) {
389 		hidl_array<uint8_t, kGsmRandLenBytes> rand;
390 		const auto &match = matches[i];
391 		WPA_ASSERT(match.size() >= 2 * rand.size());
392 		if (hexstr2bin(match.str().c_str(), rand.data(), rand.size())) {
393 			wpa_printf(
394 			    MSG_ERROR, "Failed to parse GSM auth params");
395 			return 1;
396 		}
397 		out_rands->push_back(rand);
398 	}
399 	return 0;
400 }
401 
parseUmtsAuthNetworkRequest(const std::string & params_str,hidl_array<uint8_t,kUmtsRandLenBytes> * out_rand,hidl_array<uint8_t,kUmtsAutnLenBytes> * out_autn)402 int parseUmtsAuthNetworkRequest(
403     const std::string &params_str,
404     hidl_array<uint8_t, kUmtsRandLenBytes> *out_rand,
405     hidl_array<uint8_t, kUmtsAutnLenBytes> *out_autn)
406 {
407 	std::smatch matches;
408 	std::regex params_umts_regex(kUmtsAuthRegex);
409 	if (!std::regex_match(params_str, matches, params_umts_regex)) {
410 		return 1;
411 	}
412 	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
413 	if (hexstr2bin(
414 		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
415 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
416 		return 1;
417 	}
418 	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
419 	if (hexstr2bin(
420 		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
421 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
422 		return 1;
423 	}
424 	return 0;
425 }
426 }  // namespace
427 
428 namespace android {
429 namespace hardware {
430 namespace wifi {
431 namespace supplicant {
432 namespace V1_2 {
433 namespace implementation {
434 
435 using namespace android::hardware::wifi::supplicant::V1_2;
436 using V1_0::ISupplicantStaIfaceCallback;
437 
438 HidlManager *HidlManager::instance_ = NULL;
439 
getInstance()440 HidlManager *HidlManager::getInstance()
441 {
442 	if (!instance_)
443 		instance_ = new HidlManager();
444 	return instance_;
445 }
446 
destroyInstance()447 void HidlManager::destroyInstance()
448 {
449 	if (instance_)
450 		delete instance_;
451 	instance_ = NULL;
452 }
453 
registerHidlService(struct wpa_global * global)454 int HidlManager::registerHidlService(struct wpa_global *global)
455 {
456 	// Create the main hidl service object and register it.
457 	supplicant_object_ = new Supplicant(global);
458 	if (supplicant_object_->registerAsService() != android::NO_ERROR) {
459 		return 1;
460 	}
461 	return 0;
462 }
463 
464 /**
465  * Register an interface to hidl manager.
466  *
467  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
468  *
469  * @return 0 on success, 1 on failure.
470  */
registerInterface(struct wpa_supplicant * wpa_s)471 int HidlManager::registerInterface(struct wpa_supplicant *wpa_s)
472 {
473 	if (!wpa_s)
474 		return 1;
475 
476 	if (isP2pIface(wpa_s)) {
477 		if (addHidlObjectToMap<P2pIface>(
478 			wpa_s->ifname,
479 			new P2pIface(wpa_s->global, wpa_s->ifname),
480 			p2p_iface_object_map_)) {
481 			wpa_printf(
482 			    MSG_ERROR,
483 			    "Failed to register P2P interface with HIDL "
484 			    "control: %s",
485 			    wpa_s->ifname);
486 			return 1;
487 		}
488 		p2p_iface_callbacks_map_[wpa_s->ifname] =
489 		    std::vector<android::sp<ISupplicantP2pIfaceCallback>>();
490 	} else {
491 		if (addHidlObjectToMap<StaIface>(
492 			wpa_s->ifname,
493 			new StaIface(wpa_s->global, wpa_s->ifname),
494 			sta_iface_object_map_)) {
495 			wpa_printf(
496 			    MSG_ERROR,
497 			    "Failed to register STA interface with HIDL "
498 			    "control: %s",
499 			    wpa_s->ifname);
500 			return 1;
501 		}
502 		sta_iface_callbacks_map_[wpa_s->ifname] =
503 		    std::vector<android::sp<ISupplicantStaIfaceCallback>>();
504 		// Turn on Android specific customizations for STA interfaces
505 		// here!
506 		//
507 		// Turn on scan mac randomization only if driver supports.
508 		if (wpa_s->mac_addr_rand_supported & MAC_ADDR_RAND_SCAN) {
509 			if (wpas_mac_addr_rand_scan_set(
510 				wpa_s, MAC_ADDR_RAND_SCAN, nullptr, nullptr)) {
511 				wpa_printf(
512 				    MSG_ERROR,
513 				    "Failed to enable scan mac randomization");
514 			}
515 		}
516 	}
517 
518 	// Invoke the |onInterfaceCreated| method on all registered callbacks.
519 	callWithEachSupplicantCallback(std::bind(
520 	    &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
521 	    wpa_s->ifname));
522 	return 0;
523 }
524 
525 /**
526  * Unregister an interface from hidl manager.
527  *
528  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
529  *
530  * @return 0 on success, 1 on failure.
531  */
unregisterInterface(struct wpa_supplicant * wpa_s)532 int HidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
533 {
534 	if (!wpa_s)
535 		return 1;
536 
537 	// Check if this interface is present in P2P map first, else check in
538 	// STA map.
539 	// Note: We can't use isP2pIface() here because interface
540 	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
541 	// function is cleared by the core before notifying the HIDL interface.
542 	bool success =
543 	    !removeHidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
544 	if (success) {  // assumed to be P2P
545 		success = !removeAllIfaceCallbackHidlObjectsFromMap(
546 		    wpa_s->ifname, p2p_iface_callbacks_map_);
547 	} else {  // assumed to be STA
548 		success = !removeHidlObjectFromMap(
549 		    wpa_s->ifname, sta_iface_object_map_);
550 		if (success) {
551 			success = !removeAllIfaceCallbackHidlObjectsFromMap(
552 			    wpa_s->ifname, sta_iface_callbacks_map_);
553 		}
554 	}
555 	if (!success) {
556 		wpa_printf(
557 		    MSG_ERROR,
558 		    "Failed to unregister interface with HIDL "
559 		    "control: %s",
560 		    wpa_s->ifname);
561 		return 1;
562 	}
563 
564 	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
565 	callWithEachSupplicantCallback(std::bind(
566 	    &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
567 	    wpa_s->ifname));
568 	return 0;
569 }
570 
571 /**
572  * Register a network to hidl manager.
573  *
574  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
575  * the network is added.
576  * @param ssid |wpa_ssid| struct corresponding to the network being added.
577  *
578  * @return 0 on success, 1 on failure.
579  */
registerNetwork(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)580 int HidlManager::registerNetwork(
581     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
582 {
583 	if (!wpa_s || !ssid)
584 		return 1;
585 
586 	// Generate the key to be used to lookup the network.
587 	const std::string network_key =
588 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
589 
590 	if (isP2pIface(wpa_s)) {
591 		if (addHidlObjectToMap<P2pNetwork>(
592 			network_key,
593 			new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
594 			p2p_network_object_map_)) {
595 			wpa_printf(
596 			    MSG_ERROR,
597 			    "Failed to register P2P network with HIDL "
598 			    "control: %d",
599 			    ssid->id);
600 			return 1;
601 		}
602 		p2p_network_callbacks_map_[network_key] =
603 		    std::vector<android::sp<ISupplicantP2pNetworkCallback>>();
604 		// Invoke the |onNetworkAdded| method on all registered
605 		// callbacks.
606 		callWithEachP2pIfaceCallback(
607 		    wpa_s->ifname,
608 		    std::bind(
609 			&ISupplicantP2pIfaceCallback::onNetworkAdded,
610 			std::placeholders::_1, ssid->id));
611 	} else {
612 		if (addHidlObjectToMap<StaNetwork>(
613 			network_key,
614 			new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
615 			sta_network_object_map_)) {
616 			wpa_printf(
617 			    MSG_ERROR,
618 			    "Failed to register STA network with HIDL "
619 			    "control: %d",
620 			    ssid->id);
621 			return 1;
622 		}
623 		sta_network_callbacks_map_[network_key] =
624 		    std::vector<android::sp<ISupplicantStaNetworkCallback>>();
625 		// Invoke the |onNetworkAdded| method on all registered
626 		// callbacks.
627 		callWithEachStaIfaceCallback(
628 		    wpa_s->ifname,
629 		    std::bind(
630 			&ISupplicantStaIfaceCallback::onNetworkAdded,
631 			std::placeholders::_1, ssid->id));
632 	}
633 	return 0;
634 }
635 
636 /**
637  * Unregister a network from hidl manager.
638  *
639  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
640  * the network is added.
641  * @param ssid |wpa_ssid| struct corresponding to the network being added.
642  *
643  * @return 0 on success, 1 on failure.
644  */
unregisterNetwork(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)645 int HidlManager::unregisterNetwork(
646     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
647 {
648 	if (!wpa_s || !ssid)
649 		return 1;
650 
651 	// Generate the key to be used to lookup the network.
652 	const std::string network_key =
653 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
654 
655 	if (isP2pIface(wpa_s)) {
656 		if (removeHidlObjectFromMap(
657 			network_key, p2p_network_object_map_)) {
658 			wpa_printf(
659 			    MSG_ERROR,
660 			    "Failed to unregister P2P network with HIDL "
661 			    "control: %d",
662 			    ssid->id);
663 			return 1;
664 		}
665 		if (removeAllNetworkCallbackHidlObjectsFromMap(
666 			network_key, p2p_network_callbacks_map_))
667 			return 1;
668 
669 		// Invoke the |onNetworkRemoved| method on all registered
670 		// callbacks.
671 		callWithEachP2pIfaceCallback(
672 		    wpa_s->ifname,
673 		    std::bind(
674 			&ISupplicantP2pIfaceCallback::onNetworkRemoved,
675 			std::placeholders::_1, ssid->id));
676 	} else {
677 		if (removeHidlObjectFromMap(
678 			network_key, sta_network_object_map_)) {
679 			wpa_printf(
680 			    MSG_ERROR,
681 			    "Failed to unregister STA network with HIDL "
682 			    "control: %d",
683 			    ssid->id);
684 			return 1;
685 		}
686 		if (removeAllNetworkCallbackHidlObjectsFromMap(
687 			network_key, sta_network_callbacks_map_))
688 			return 1;
689 
690 		// Invoke the |onNetworkRemoved| method on all registered
691 		// callbacks.
692 		callWithEachStaIfaceCallback(
693 		    wpa_s->ifname,
694 		    std::bind(
695 			&ISupplicantStaIfaceCallback::onNetworkRemoved,
696 			std::placeholders::_1, ssid->id));
697 	}
698 	return 0;
699 }
700 
701 /**
702  * Notify all listeners about any state changes on a particular interface.
703  *
704  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
705  * the state change event occured.
706  */
notifyStateChange(struct wpa_supplicant * wpa_s)707 int HidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
708 {
709 	if (!wpa_s)
710 		return 1;
711 
712 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
713 	    sta_iface_object_map_.end())
714 		return 1;
715 
716 	// Invoke the |onStateChanged| method on all registered callbacks.
717 	uint32_t hidl_network_id = UINT32_MAX;
718 	std::vector<uint8_t> hidl_ssid;
719 	if (wpa_s->current_ssid) {
720 		hidl_network_id = wpa_s->current_ssid->id;
721 		hidl_ssid.assign(
722 		    wpa_s->current_ssid->ssid,
723 		    wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
724 	}
725 	uint8_t *bssid;
726 	// wpa_supplicant sets the |pending_bssid| field when it starts a
727 	// connection. Only after association state does it update the |bssid|
728 	// field. So, in the HIDL callback send the appropriate bssid.
729 	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
730 		bssid = wpa_s->pending_bssid;
731 	} else {
732 		bssid = wpa_s->bssid;
733 	}
734 	callWithEachStaIfaceCallback(
735 	    wpa_s->ifname, std::bind(
736 			       &ISupplicantStaIfaceCallback::onStateChanged,
737 			       std::placeholders::_1,
738 			       static_cast<ISupplicantStaIfaceCallback::State>(
739 				   wpa_s->wpa_state),
740 			       bssid, hidl_network_id, hidl_ssid));
741 	return 0;
742 }
743 
744 /**
745  * Notify all listeners about a request on a particular network.
746  *
747  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
748  * the network is present.
749  * @param ssid |wpa_ssid| struct corresponding to the network.
750  * @param type type of request.
751  * @param param addition params associated with the request.
752  */
notifyNetworkRequest(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,int type,const char * param)753 int HidlManager::notifyNetworkRequest(
754     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
755     const char *param)
756 {
757 	if (!wpa_s || !ssid)
758 		return 1;
759 
760 	const std::string network_key =
761 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
762 	if (sta_network_object_map_.find(network_key) ==
763 	    sta_network_object_map_.end())
764 		return 1;
765 
766 	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
767 		callWithEachStaNetworkCallback(
768 		    wpa_s->ifname, ssid->id,
769 		    std::bind(
770 			&ISupplicantStaNetworkCallback::
771 			    onNetworkEapIdentityRequest,
772 			std::placeholders::_1));
773 		return 0;
774 	}
775 	if (type == WPA_CTRL_REQ_SIM) {
776 		std::vector<hidl_array<uint8_t, 16>> gsm_rands;
777 		hidl_array<uint8_t, 16> umts_rand;
778 		hidl_array<uint8_t, 16> umts_autn;
779 		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
780 			ISupplicantStaNetworkCallback::
781 			    NetworkRequestEapSimGsmAuthParams hidl_params;
782 			hidl_params.rands = gsm_rands;
783 			callWithEachStaNetworkCallback(
784 			    wpa_s->ifname, ssid->id,
785 			    std::bind(
786 				&ISupplicantStaNetworkCallback::
787 				    onNetworkEapSimGsmAuthRequest,
788 				std::placeholders::_1, hidl_params));
789 			return 0;
790 		}
791 		if (!parseUmtsAuthNetworkRequest(
792 			param, &umts_rand, &umts_autn)) {
793 			ISupplicantStaNetworkCallback::
794 			    NetworkRequestEapSimUmtsAuthParams hidl_params;
795 			hidl_params.rand = umts_rand;
796 			hidl_params.autn = umts_autn;
797 			callWithEachStaNetworkCallback(
798 			    wpa_s->ifname, ssid->id,
799 			    std::bind(
800 				&ISupplicantStaNetworkCallback::
801 				    onNetworkEapSimUmtsAuthRequest,
802 				std::placeholders::_1, hidl_params));
803 			return 0;
804 		}
805 	}
806 	return 1;
807 }
808 
809 /**
810  * Notify all listeners about the end of an ANQP query.
811  *
812  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
813  * @param bssid BSSID of the access point.
814  * @param result Result of the operation ("SUCCESS" or "FAILURE").
815  * @param anqp |wpa_bss_anqp| ANQP data fetched.
816  */
notifyAnqpQueryDone(struct wpa_supplicant * wpa_s,const u8 * bssid,const char * result,const struct wpa_bss_anqp * anqp)817 void HidlManager::notifyAnqpQueryDone(
818     struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
819     const struct wpa_bss_anqp *anqp)
820 {
821 	if (!wpa_s || !bssid || !result || !anqp)
822 		return;
823 
824 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
825 	    sta_iface_object_map_.end())
826 		return;
827 
828 	ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data;
829 	ISupplicantStaIfaceCallback::Hs20AnqpData hidl_hs20_anqp_data;
830 	if (std::string(result) == "SUCCESS") {
831 		hidl_anqp_data.venueName =
832 		    misc_utils::convertWpaBufToVector(anqp->venue_name);
833 		hidl_anqp_data.roamingConsortium =
834 		    misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
835 		hidl_anqp_data.ipAddrTypeAvailability =
836 		    misc_utils::convertWpaBufToVector(
837 			anqp->ip_addr_type_availability);
838 		hidl_anqp_data.naiRealm =
839 		    misc_utils::convertWpaBufToVector(anqp->nai_realm);
840 		hidl_anqp_data.anqp3gppCellularNetwork =
841 		    misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
842 		hidl_anqp_data.domainName =
843 		    misc_utils::convertWpaBufToVector(anqp->domain_name);
844 
845 		hidl_hs20_anqp_data.operatorFriendlyName =
846 		    misc_utils::convertWpaBufToVector(
847 			anqp->hs20_operator_friendly_name);
848 		hidl_hs20_anqp_data.wanMetrics =
849 		    misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
850 		hidl_hs20_anqp_data.connectionCapability =
851 		    misc_utils::convertWpaBufToVector(
852 			anqp->hs20_connection_capability);
853 		hidl_hs20_anqp_data.osuProvidersList =
854 		    misc_utils::convertWpaBufToVector(
855 			anqp->hs20_osu_providers_list);
856 	}
857 
858 	callWithEachStaIfaceCallback(
859 	    wpa_s->ifname, std::bind(
860 			       &ISupplicantStaIfaceCallback::onAnqpQueryDone,
861 			       std::placeholders::_1, bssid, hidl_anqp_data,
862 			       hidl_hs20_anqp_data));
863 }
864 
865 /**
866  * Notify all listeners about the end of an HS20 icon query.
867  *
868  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
869  * @param bssid BSSID of the access point.
870  * @param file_name Name of the icon file.
871  * @param image Raw bytes of the icon file.
872  * @param image_length Size of the the icon file.
873  */
notifyHs20IconQueryDone(struct wpa_supplicant * wpa_s,const u8 * bssid,const char * file_name,const u8 * image,u32 image_length)874 void HidlManager::notifyHs20IconQueryDone(
875     struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
876     const u8 *image, u32 image_length)
877 {
878 	if (!wpa_s || !bssid || !file_name || !image)
879 		return;
880 
881 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
882 	    sta_iface_object_map_.end())
883 		return;
884 
885 	callWithEachStaIfaceCallback(
886 	    wpa_s->ifname,
887 	    std::bind(
888 		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
889 		std::placeholders::_1, bssid, file_name,
890 		std::vector<uint8_t>(image, image + image_length)));
891 }
892 
893 /**
894  * Notify all listeners about the reception of HS20 subscription
895  * remediation notification from the server.
896  *
897  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
898  * @param url URL of the server.
899  * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
900  */
notifyHs20RxSubscriptionRemediation(struct wpa_supplicant * wpa_s,const char * url,u8 osu_method)901 void HidlManager::notifyHs20RxSubscriptionRemediation(
902     struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
903 {
904 	if (!wpa_s || !url)
905 		return;
906 
907 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
908 	    sta_iface_object_map_.end())
909 		return;
910 
911 	ISupplicantStaIfaceCallback::OsuMethod hidl_osu_method = {};
912 	if (osu_method & 0x1) {
913 		hidl_osu_method =
914 		    ISupplicantStaIfaceCallback::OsuMethod::OMA_DM;
915 	} else if (osu_method & 0x2) {
916 		hidl_osu_method =
917 		    ISupplicantStaIfaceCallback::OsuMethod::SOAP_XML_SPP;
918 	}
919 	callWithEachStaIfaceCallback(
920 	    wpa_s->ifname,
921 	    std::bind(
922 		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
923 		std::placeholders::_1, wpa_s->bssid, hidl_osu_method, url));
924 }
925 
926 /**
927  * Notify all listeners about the reception of HS20 immient deauth
928  * notification from the server.
929  *
930  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
931  * @param code Deauth reason code sent from server.
932  * @param reauth_delay Reauthentication delay in seconds sent from server.
933  * @param url URL of the server.
934  */
notifyHs20RxDeauthImminentNotice(struct wpa_supplicant * wpa_s,u8 code,u16 reauth_delay,const char * url)935 void HidlManager::notifyHs20RxDeauthImminentNotice(
936     struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
937 {
938 	if (!wpa_s || !url)
939 		return;
940 
941 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
942 	    sta_iface_object_map_.end())
943 		return;
944 
945 	callWithEachStaIfaceCallback(
946 	    wpa_s->ifname,
947 	    std::bind(
948 		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
949 		std::placeholders::_1, wpa_s->bssid, code, reauth_delay, url));
950 }
951 
952 /**
953  * Notify all listeners about the reason code for disconnection from the
954  * currently connected network.
955  *
956  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
957  * the network is present.
958  */
notifyDisconnectReason(struct wpa_supplicant * wpa_s)959 void HidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
960 {
961 	if (!wpa_s)
962 		return;
963 
964 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
965 	    sta_iface_object_map_.end())
966 		return;
967 
968 	const u8 *bssid = wpa_s->bssid;
969 	if (is_zero_ether_addr(bssid)) {
970 		bssid = wpa_s->pending_bssid;
971 	}
972 
973 	callWithEachStaIfaceCallback(
974 	    wpa_s->ifname,
975 	    std::bind(
976 		&ISupplicantStaIfaceCallback::onDisconnected,
977 		std::placeholders::_1, bssid, wpa_s->disconnect_reason < 0,
978 		static_cast<ISupplicantStaIfaceCallback::ReasonCode>(
979 		    abs(wpa_s->disconnect_reason))));
980 }
981 
982 /**
983  * Notify all listeners about association reject from the access point to which
984  * we are attempting to connect.
985  *
986  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
987  * the network is present.
988  */
notifyAssocReject(struct wpa_supplicant * wpa_s)989 void HidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s)
990 {
991 	if (!wpa_s)
992 		return;
993 
994 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
995 	    sta_iface_object_map_.end())
996 		return;
997 
998 	const u8 *bssid = wpa_s->bssid;
999 	if (is_zero_ether_addr(bssid)) {
1000 		bssid = wpa_s->pending_bssid;
1001 	}
1002 
1003 	callWithEachStaIfaceCallback(
1004 	    wpa_s->ifname,
1005 	    std::bind(
1006 		&ISupplicantStaIfaceCallback::onAssociationRejected,
1007 		std::placeholders::_1, bssid,
1008 		static_cast<ISupplicantStaIfaceCallback::StatusCode>(
1009 		    wpa_s->assoc_status_code),
1010 		wpa_s->assoc_timed_out == 1));
1011 }
1012 
notifyAuthTimeout(struct wpa_supplicant * wpa_s)1013 void HidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
1014 {
1015 	if (!wpa_s)
1016 		return;
1017 
1018 	const std::string ifname(wpa_s->ifname);
1019 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
1020 		return;
1021 
1022 	const u8 *bssid = wpa_s->bssid;
1023 	if (is_zero_ether_addr(bssid)) {
1024 		bssid = wpa_s->pending_bssid;
1025 	}
1026 	callWithEachStaIfaceCallback(
1027 	    wpa_s->ifname,
1028 	    std::bind(
1029 		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
1030 		std::placeholders::_1, bssid));
1031 }
1032 
notifyBssidChanged(struct wpa_supplicant * wpa_s)1033 void HidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
1034 {
1035 	if (!wpa_s)
1036 		return;
1037 
1038 	const std::string ifname(wpa_s->ifname);
1039 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
1040 		return;
1041 
1042 	// wpa_supplicant does not explicitly give us the reason for bssid
1043 	// change, but we figure that out from what is set out of |wpa_s->bssid|
1044 	// & |wpa_s->pending_bssid|.
1045 	const u8 *bssid;
1046 	ISupplicantStaIfaceCallback::BssidChangeReason reason;
1047 	if (is_zero_ether_addr(wpa_s->bssid) &&
1048 	    !is_zero_ether_addr(wpa_s->pending_bssid)) {
1049 		bssid = wpa_s->pending_bssid;
1050 		reason =
1051 		    ISupplicantStaIfaceCallback::BssidChangeReason::ASSOC_START;
1052 	} else if (
1053 	    !is_zero_ether_addr(wpa_s->bssid) &&
1054 	    is_zero_ether_addr(wpa_s->pending_bssid)) {
1055 		bssid = wpa_s->bssid;
1056 		reason = ISupplicantStaIfaceCallback::BssidChangeReason::
1057 		    ASSOC_COMPLETE;
1058 	} else if (
1059 	    is_zero_ether_addr(wpa_s->bssid) &&
1060 	    is_zero_ether_addr(wpa_s->pending_bssid)) {
1061 		bssid = wpa_s->pending_bssid;
1062 		reason =
1063 		    ISupplicantStaIfaceCallback::BssidChangeReason::DISASSOC;
1064 	} else {
1065 		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
1066 		return;
1067 	}
1068 
1069 	callWithEachStaIfaceCallback(
1070 	    wpa_s->ifname, std::bind(
1071 			       &ISupplicantStaIfaceCallback::onBssidChanged,
1072 			       std::placeholders::_1, reason, bssid));
1073 }
1074 
notifyWpsEventFail(struct wpa_supplicant * wpa_s,uint8_t * peer_macaddr,uint16_t config_error,uint16_t error_indication)1075 void HidlManager::notifyWpsEventFail(
1076     struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
1077     uint16_t error_indication)
1078 {
1079 	if (!wpa_s || !peer_macaddr)
1080 		return;
1081 
1082 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1083 	    sta_iface_object_map_.end())
1084 		return;
1085 
1086 	callWithEachStaIfaceCallback(
1087 	    wpa_s->ifname,
1088 	    std::bind(
1089 		&ISupplicantStaIfaceCallback::onWpsEventFail,
1090 		std::placeholders::_1, peer_macaddr,
1091 		static_cast<ISupplicantStaIfaceCallback::WpsConfigError>(
1092 		    config_error),
1093 		static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>(
1094 		    error_indication)));
1095 }
1096 
notifyWpsEventSuccess(struct wpa_supplicant * wpa_s)1097 void HidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
1098 {
1099 	if (!wpa_s)
1100 		return;
1101 
1102 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1103 	    sta_iface_object_map_.end())
1104 		return;
1105 
1106 	callWithEachStaIfaceCallback(
1107 	    wpa_s->ifname, std::bind(
1108 			       &ISupplicantStaIfaceCallback::onWpsEventSuccess,
1109 			       std::placeholders::_1));
1110 }
1111 
notifyWpsEventPbcOverlap(struct wpa_supplicant * wpa_s)1112 void HidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
1113 {
1114 	if (!wpa_s)
1115 		return;
1116 
1117 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1118 	    sta_iface_object_map_.end())
1119 		return;
1120 
1121 	callWithEachStaIfaceCallback(
1122 	    wpa_s->ifname,
1123 	    std::bind(
1124 		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
1125 		std::placeholders::_1));
1126 }
1127 
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)1128 void HidlManager::notifyP2pDeviceFound(
1129     struct wpa_supplicant *wpa_s, const u8 *addr,
1130     const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
1131     u8 peer_wfd_device_info_len)
1132 {
1133 	if (!wpa_s || !addr || !info)
1134 		return;
1135 
1136 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1137 	    p2p_iface_object_map_.end())
1138 		return;
1139 
1140 	std::array<uint8_t, kWfdDeviceInfoLen> hidl_peer_wfd_device_info{};
1141 	if (peer_wfd_device_info) {
1142 		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
1143 			wpa_printf(
1144 			    MSG_ERROR, "Unexpected WFD device info len: %d",
1145 			    peer_wfd_device_info_len);
1146 		} else {
1147 			os_memcpy(
1148 			    hidl_peer_wfd_device_info.data(),
1149 			    peer_wfd_device_info, kWfdDeviceInfoLen);
1150 		}
1151 	}
1152 
1153 	callWithEachP2pIfaceCallback(
1154 	    wpa_s->ifname,
1155 	    std::bind(
1156 		&ISupplicantP2pIfaceCallback::onDeviceFound,
1157 		std::placeholders::_1, addr, info->p2p_device_addr,
1158 		info->pri_dev_type, info->device_name, info->config_methods,
1159 		info->dev_capab, info->group_capab, hidl_peer_wfd_device_info));
1160 }
1161 
notifyP2pDeviceLost(struct wpa_supplicant * wpa_s,const u8 * p2p_device_addr)1162 void HidlManager::notifyP2pDeviceLost(
1163     struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
1164 {
1165 	if (!wpa_s || !p2p_device_addr)
1166 		return;
1167 
1168 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1169 	    p2p_iface_object_map_.end())
1170 		return;
1171 
1172 	callWithEachP2pIfaceCallback(
1173 	    wpa_s->ifname, std::bind(
1174 			       &ISupplicantP2pIfaceCallback::onDeviceLost,
1175 			       std::placeholders::_1, p2p_device_addr));
1176 }
1177 
notifyP2pFindStopped(struct wpa_supplicant * wpa_s)1178 void HidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
1179 {
1180 	if (!wpa_s)
1181 		return;
1182 
1183 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1184 	    p2p_iface_object_map_.end())
1185 		return;
1186 
1187 	callWithEachP2pIfaceCallback(
1188 	    wpa_s->ifname, std::bind(
1189 			       &ISupplicantP2pIfaceCallback::onFindStopped,
1190 			       std::placeholders::_1));
1191 }
1192 
notifyP2pGoNegReq(struct wpa_supplicant * wpa_s,const u8 * src_addr,u16 dev_passwd_id,u8)1193 void HidlManager::notifyP2pGoNegReq(
1194     struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
1195     u8 /* go_intent */)
1196 {
1197 	if (!wpa_s || !src_addr)
1198 		return;
1199 
1200 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1201 	    p2p_iface_object_map_.end())
1202 		return;
1203 
1204 	callWithEachP2pIfaceCallback(
1205 	    wpa_s->ifname,
1206 	    std::bind(
1207 		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
1208 		std::placeholders::_1, src_addr,
1209 		static_cast<ISupplicantP2pIfaceCallback::WpsDevPasswordId>(
1210 		    dev_passwd_id)));
1211 }
1212 
notifyP2pGoNegCompleted(struct wpa_supplicant * wpa_s,const struct p2p_go_neg_results * res)1213 void HidlManager::notifyP2pGoNegCompleted(
1214     struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
1215 {
1216 	if (!wpa_s || !res)
1217 		return;
1218 
1219 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1220 	    p2p_iface_object_map_.end())
1221 		return;
1222 
1223 	callWithEachP2pIfaceCallback(
1224 	    wpa_s->ifname,
1225 	    std::bind(
1226 		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
1227 		std::placeholders::_1,
1228 		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
1229 		    res->status)));
1230 }
1231 
notifyP2pGroupFormationFailure(struct wpa_supplicant * wpa_s,const char * reason)1232 void HidlManager::notifyP2pGroupFormationFailure(
1233     struct wpa_supplicant *wpa_s, const char *reason)
1234 {
1235 	if (!wpa_s || !reason)
1236 		return;
1237 
1238 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1239 	    p2p_iface_object_map_.end())
1240 		return;
1241 
1242 	callWithEachP2pIfaceCallback(
1243 	    wpa_s->ifname,
1244 	    std::bind(
1245 		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
1246 		std::placeholders::_1, reason));
1247 }
1248 
notifyP2pGroupStarted(struct wpa_supplicant * wpa_group_s,const struct wpa_ssid * ssid,int persistent,int client)1249 void HidlManager::notifyP2pGroupStarted(
1250     struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
1251     int persistent, int client)
1252 {
1253 	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
1254 		return;
1255 
1256 	// For group notifications, need to use the parent iface for callbacks.
1257 	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
1258 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1259 	    p2p_iface_object_map_.end())
1260 		return;
1261 
1262 	uint32_t hidl_freq = wpa_group_s->current_bss
1263 				 ? wpa_group_s->current_bss->freq
1264 				 : wpa_group_s->assoc_freq;
1265 	std::array<uint8_t, 32> hidl_psk;
1266 	if (ssid->psk_set) {
1267 		os_memcpy(hidl_psk.data(), ssid->psk, 32);
1268 	}
1269 	bool hidl_is_go = (client == 0 ? true : false);
1270 	bool hidl_is_persistent = (persistent == 1 ? true : false);
1271 
1272 	callWithEachP2pIfaceCallback(
1273 	    wpa_s->ifname,
1274 	    std::bind(
1275 		&ISupplicantP2pIfaceCallback::onGroupStarted,
1276 		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go,
1277 		std::vector<uint8_t>{ssid->ssid, ssid->ssid + ssid->ssid_len},
1278 		hidl_freq, hidl_psk, ssid->passphrase, wpa_group_s->go_dev_addr,
1279 		hidl_is_persistent));
1280 }
1281 
notifyP2pGroupRemoved(struct wpa_supplicant * wpa_group_s,const struct wpa_ssid * ssid,const char * role)1282 void HidlManager::notifyP2pGroupRemoved(
1283     struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
1284     const char *role)
1285 {
1286 	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
1287 		return;
1288 
1289 	// For group notifications, need to use the parent iface for callbacks.
1290 	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
1291 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1292 	    p2p_iface_object_map_.end())
1293 		return;
1294 
1295 	bool hidl_is_go = (std::string(role) == "GO");
1296 
1297 	callWithEachP2pIfaceCallback(
1298 	    wpa_s->ifname,
1299 	    std::bind(
1300 		&ISupplicantP2pIfaceCallback::onGroupRemoved,
1301 		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go));
1302 }
1303 
notifyP2pInvitationReceived(struct wpa_supplicant * wpa_s,const u8 * sa,const u8 * go_dev_addr,const u8 * bssid,int id,int op_freq)1304 void HidlManager::notifyP2pInvitationReceived(
1305     struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
1306     const u8 *bssid, int id, int op_freq)
1307 {
1308 	if (!wpa_s || !sa || !go_dev_addr || !bssid)
1309 		return;
1310 
1311 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1312 	    p2p_iface_object_map_.end())
1313 		return;
1314 
1315 	SupplicantNetworkId hidl_network_id;
1316 	if (id < 0) {
1317 		hidl_network_id = UINT32_MAX;
1318 	}
1319 	hidl_network_id = id;
1320 
1321 	callWithEachP2pIfaceCallback(
1322 	    wpa_s->ifname,
1323 	    std::bind(
1324 		&ISupplicantP2pIfaceCallback::onInvitationReceived,
1325 		std::placeholders::_1, sa, go_dev_addr, bssid, hidl_network_id,
1326 		op_freq));
1327 }
1328 
notifyP2pInvitationResult(struct wpa_supplicant * wpa_s,int status,const u8 * bssid)1329 void HidlManager::notifyP2pInvitationResult(
1330     struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
1331 {
1332 	if (!wpa_s)
1333 		return;
1334 
1335 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1336 	    p2p_iface_object_map_.end())
1337 		return;
1338 
1339 	callWithEachP2pIfaceCallback(
1340 	    wpa_s->ifname,
1341 	    std::bind(
1342 		&ISupplicantP2pIfaceCallback::onInvitationResult,
1343 		std::placeholders::_1, bssid ? bssid : kZeroBssid,
1344 		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
1345 		    status)));
1346 }
1347 
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)1348 void HidlManager::notifyP2pProvisionDiscovery(
1349     struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
1350     enum p2p_prov_disc_status status, u16 config_methods,
1351     unsigned int generated_pin)
1352 {
1353 	if (!wpa_s || !dev_addr)
1354 		return;
1355 
1356 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1357 	    p2p_iface_object_map_.end())
1358 		return;
1359 
1360 	std::string hidl_generated_pin;
1361 	if (generated_pin > 0) {
1362 		hidl_generated_pin =
1363 		    misc_utils::convertWpsPinToString(generated_pin);
1364 	}
1365 	bool hidl_is_request = (request == 1 ? true : false);
1366 
1367 	callWithEachP2pIfaceCallback(
1368 	    wpa_s->ifname,
1369 	    std::bind(
1370 		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
1371 		std::placeholders::_1, dev_addr, hidl_is_request,
1372 		static_cast<ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode>(
1373 		    status),
1374 		config_methods, hidl_generated_pin));
1375 }
1376 
notifyP2pSdResponse(struct wpa_supplicant * wpa_s,const u8 * sa,u16 update_indic,const u8 * tlvs,size_t tlvs_len)1377 void HidlManager::notifyP2pSdResponse(
1378     struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
1379     const u8 *tlvs, size_t tlvs_len)
1380 {
1381 	if (!wpa_s || !sa || !tlvs)
1382 		return;
1383 
1384 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
1385 	    p2p_iface_object_map_.end())
1386 		return;
1387 
1388 	callWithEachP2pIfaceCallback(
1389 	    wpa_s->ifname,
1390 	    std::bind(
1391 		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
1392 		std::placeholders::_1, sa, update_indic,
1393 		std::vector<uint8_t>{tlvs, tlvs + tlvs_len}));
1394 }
1395 
notifyApStaAuthorized(struct wpa_supplicant * wpa_s,const u8 * sta,const u8 * p2p_dev_addr)1396 void HidlManager::notifyApStaAuthorized(
1397     struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
1398 {
1399 	if (!wpa_s || !wpa_s->parent || !sta)
1400 		return;
1401 	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
1402 	    p2p_iface_object_map_.end())
1403 		return;
1404 	callWithEachP2pIfaceCallback(
1405 	    wpa_s->parent->ifname,
1406 	    std::bind(
1407 		&ISupplicantP2pIfaceCallback::onStaAuthorized,
1408 		std::placeholders::_1, sta,
1409 		p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
1410 }
1411 
notifyApStaDeauthorized(struct wpa_supplicant * wpa_s,const u8 * sta,const u8 * p2p_dev_addr)1412 void HidlManager::notifyApStaDeauthorized(
1413     struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
1414 {
1415 	if (!wpa_s || !wpa_s->parent || !sta)
1416 		return;
1417 	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
1418 	    p2p_iface_object_map_.end())
1419 		return;
1420 
1421 	callWithEachP2pIfaceCallback(
1422 	    wpa_s->parent->ifname,
1423 	    std::bind(
1424 		&ISupplicantP2pIfaceCallback::onStaDeauthorized,
1425 		std::placeholders::_1, sta,
1426 		p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
1427 }
1428 
notifyExtRadioWorkStart(struct wpa_supplicant * wpa_s,uint32_t id)1429 void HidlManager::notifyExtRadioWorkStart(
1430     struct wpa_supplicant *wpa_s, uint32_t id)
1431 {
1432 	if (!wpa_s)
1433 		return;
1434 
1435 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1436 	    sta_iface_object_map_.end())
1437 		return;
1438 
1439 	callWithEachStaIfaceCallback(
1440 	    wpa_s->ifname,
1441 	    std::bind(
1442 		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
1443 		std::placeholders::_1, id));
1444 }
1445 
notifyExtRadioWorkTimeout(struct wpa_supplicant * wpa_s,uint32_t id)1446 void HidlManager::notifyExtRadioWorkTimeout(
1447     struct wpa_supplicant *wpa_s, uint32_t id)
1448 {
1449 	if (!wpa_s)
1450 		return;
1451 
1452 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
1453 	    sta_iface_object_map_.end())
1454 		return;
1455 
1456 	callWithEachStaIfaceCallback(
1457 	    wpa_s->ifname,
1458 	    std::bind(
1459 		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
1460 		std::placeholders::_1, id));
1461 }
1462 
notifyEapError(struct wpa_supplicant * wpa_s,int error_code)1463 void HidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
1464 {
1465 	typedef V1_1::ISupplicantStaIfaceCallback::EapErrorCode EapErrorCode;
1466 
1467 	if (!wpa_s)
1468 		return;
1469 
1470 	switch (static_cast<EapErrorCode>(error_code)) {
1471 	case EapErrorCode::SIM_GENERAL_FAILURE_AFTER_AUTH:
1472 	case EapErrorCode::SIM_TEMPORARILY_DENIED:
1473 	case EapErrorCode::SIM_NOT_SUBSCRIBED:
1474 	case EapErrorCode::SIM_GENERAL_FAILURE_BEFORE_AUTH:
1475 	case EapErrorCode::SIM_VENDOR_SPECIFIC_EXPIRED_CERT:
1476 		break;
1477 	default:
1478 		return;
1479 	}
1480 
1481 	callWithEachStaIfaceCallback_1_1(
1482 	    wpa_s->ifname,
1483 	    std::bind(
1484 		&V1_1::ISupplicantStaIfaceCallback::onEapFailure_1_1,
1485 		std::placeholders::_1, static_cast<EapErrorCode>(error_code)));
1486 }
1487 
1488 /**
1489  * Notify listener about a new DPP configuration received success event
1490  *
1491  * @param ifname Interface name
1492  * @param config Configuration object
1493  */
notifyDppConfigReceived(struct wpa_supplicant * wpa_s,struct wpa_ssid * config)1494 void HidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
1495 		struct wpa_ssid *config)
1496 {
1497 	DppAkm securityAkm;
1498 	char *password;
1499 	std::string hidl_ifname = wpa_s->ifname;
1500 
1501 	if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
1502 			(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
1503 		securityAkm = DppAkm::SAE;
1504 	} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
1505 			securityAkm = DppAkm::PSK;
1506 	} else {
1507 		/* Unsupported AKM */
1508 		wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
1509 				config->key_mgmt);
1510 		notifyDppFailure(wpa_s, DppFailureCode::NOT_SUPPORTED);
1511 		return;
1512 	}
1513 
1514 	password = config->passphrase;
1515 	std::vector < uint8_t > hidl_ssid;
1516 	hidl_ssid.assign(config->ssid, config->ssid + config->ssid_len);
1517 
1518 	/* At this point, the network is already registered, notify about new
1519 	 * received configuration
1520 	 */
1521 	callWithEachStaIfaceCallback_1_2(hidl_ifname,
1522 			std::bind(
1523 					&V1_2::ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
1524 					std::placeholders::_1, hidl_ssid, password, config->psk,
1525 					securityAkm));
1526 }
1527 
1528 /**
1529  * Notify listener about a DPP configuration sent success event
1530  *
1531  * @param ifname Interface name
1532  */
notifyDppConfigSent(struct wpa_supplicant * wpa_s)1533 void HidlManager::notifyDppConfigSent(struct wpa_supplicant *wpa_s)
1534 {
1535 	std::string hidl_ifname = wpa_s->ifname;
1536 
1537 	callWithEachStaIfaceCallback_1_2(hidl_ifname,
1538 			std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppSuccessConfigSent,
1539 					std::placeholders::_1));
1540 }
1541 
1542 /**
1543  * Notify listener about a DPP failure event
1544  *
1545  * @param ifname Interface name
1546  * @param code Status code
1547  */
notifyDppFailure(struct wpa_supplicant * wpa_s,DppFailureCode code)1548 void HidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s, DppFailureCode code)
1549 {
1550 	std::string hidl_ifname = wpa_s->ifname;
1551 
1552 	callWithEachStaIfaceCallback_1_2(hidl_ifname,
1553 			std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppFailure,
1554 					std::placeholders::_1, code));
1555 }
1556 
1557 /**
1558  * Notify listener about a DPP progress event
1559  *
1560  * @param ifname Interface name
1561  * @param code Status code
1562  */
notifyDppProgress(struct wpa_supplicant * wpa_s,DppProgressCode code)1563 void HidlManager::notifyDppProgress(struct wpa_supplicant *wpa_s, DppProgressCode code)
1564 {
1565 	std::string hidl_ifname = wpa_s->ifname;
1566 
1567 	callWithEachStaIfaceCallback_1_2(hidl_ifname,
1568 			std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppProgress,
1569 					std::placeholders::_1, code));
1570 }
1571 
1572 /**
1573  * Retrieve the |ISupplicantP2pIface| hidl object reference using the provided
1574  * ifname.
1575  *
1576  * @param ifname Name of the corresponding interface.
1577  * @param iface_object Hidl reference corresponding to the iface.
1578  *
1579  * @return 0 on success, 1 on failure.
1580  */
getP2pIfaceHidlObjectByIfname(const std::string & ifname,android::sp<ISupplicantP2pIface> * iface_object)1581 int HidlManager::getP2pIfaceHidlObjectByIfname(
1582     const std::string &ifname, android::sp<ISupplicantP2pIface> *iface_object)
1583 {
1584 	if (ifname.empty() || !iface_object)
1585 		return 1;
1586 
1587 	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
1588 	if (iface_object_iter == p2p_iface_object_map_.end())
1589 		return 1;
1590 
1591 	*iface_object = iface_object_iter->second;
1592 	return 0;
1593 }
1594 
1595 /**
1596  * Retrieve the |ISupplicantStaIface| hidl object reference using the provided
1597  * ifname.
1598  *
1599  * @param ifname Name of the corresponding interface.
1600  * @param iface_object Hidl reference corresponding to the iface.
1601  *
1602  * @return 0 on success, 1 on failure.
1603  */
getStaIfaceHidlObjectByIfname(const std::string & ifname,android::sp<ISupplicantStaIface> * iface_object)1604 int HidlManager::getStaIfaceHidlObjectByIfname(
1605     const std::string &ifname, android::sp<ISupplicantStaIface> *iface_object)
1606 {
1607 	if (ifname.empty() || !iface_object)
1608 		return 1;
1609 
1610 	auto iface_object_iter = sta_iface_object_map_.find(ifname);
1611 	if (iface_object_iter == sta_iface_object_map_.end())
1612 		return 1;
1613 
1614 	*iface_object = iface_object_iter->second;
1615 	return 0;
1616 }
1617 
1618 /**
1619  * Retrieve the |ISupplicantP2pNetwork| hidl object reference using the provided
1620  * ifname and network_id.
1621  *
1622  * @param ifname Name of the corresponding interface.
1623  * @param network_id ID of the corresponding network.
1624  * @param network_object Hidl reference corresponding to the network.
1625  *
1626  * @return 0 on success, 1 on failure.
1627  */
getP2pNetworkHidlObjectByIfnameAndNetworkId(const std::string & ifname,int network_id,android::sp<ISupplicantP2pNetwork> * network_object)1628 int HidlManager::getP2pNetworkHidlObjectByIfnameAndNetworkId(
1629     const std::string &ifname, int network_id,
1630     android::sp<ISupplicantP2pNetwork> *network_object)
1631 {
1632 	if (ifname.empty() || network_id < 0 || !network_object)
1633 		return 1;
1634 
1635 	// Generate the key to be used to lookup the network.
1636 	const std::string network_key =
1637 	    getNetworkObjectMapKey(ifname, network_id);
1638 
1639 	auto network_object_iter = p2p_network_object_map_.find(network_key);
1640 	if (network_object_iter == p2p_network_object_map_.end())
1641 		return 1;
1642 
1643 	*network_object = network_object_iter->second;
1644 	return 0;
1645 }
1646 
1647 /**
1648  * Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided
1649  * ifname and network_id.
1650  *
1651  * @param ifname Name of the corresponding interface.
1652  * @param network_id ID of the corresponding network.
1653  * @param network_object Hidl reference corresponding to the network.
1654  *
1655  * @return 0 on success, 1 on failure.
1656  */
getStaNetworkHidlObjectByIfnameAndNetworkId(const std::string & ifname,int network_id,android::sp<ISupplicantStaNetwork> * network_object)1657 int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId(
1658     const std::string &ifname, int network_id,
1659     android::sp<ISupplicantStaNetwork> *network_object)
1660 {
1661 	if (ifname.empty() || network_id < 0 || !network_object)
1662 		return 1;
1663 
1664 	// Generate the key to be used to lookup the network.
1665 	const std::string network_key =
1666 	    getNetworkObjectMapKey(ifname, network_id);
1667 
1668 	auto network_object_iter = sta_network_object_map_.find(network_key);
1669 	if (network_object_iter == sta_network_object_map_.end())
1670 		return 1;
1671 
1672 	*network_object = network_object_iter->second;
1673 	return 0;
1674 }
1675 
1676 /**
1677  * Add a new |ISupplicantCallback| hidl object reference to our
1678  * global callback list.
1679  *
1680  * @param callback Hidl reference of the |ISupplicantCallback| object.
1681  *
1682  * @return 0 on success, 1 on failure.
1683  */
addSupplicantCallbackHidlObject(const android::sp<ISupplicantCallback> & callback)1684 int HidlManager::addSupplicantCallbackHidlObject(
1685     const android::sp<ISupplicantCallback> &callback)
1686 {
1687 	// Register for death notification before we add it to our list.
1688 	auto on_hidl_died_fctor = std::bind(
1689 	    &HidlManager::removeSupplicantCallbackHidlObject, this,
1690 	    std::placeholders::_1);
1691 	return registerForDeathAndAddCallbackHidlObjectToList<
1692 	    ISupplicantCallback>(
1693 	    callback, on_hidl_died_fctor, supplicant_callbacks_);
1694 }
1695 
1696 /**
1697  * Add a new iface callback hidl object reference to our
1698  * interface callback list.
1699  *
1700  * @param ifname Name of the corresponding interface.
1701  * @param callback Hidl reference of the callback object.
1702  *
1703  * @return 0 on success, 1 on failure.
1704  */
addP2pIfaceCallbackHidlObject(const std::string & ifname,const android::sp<ISupplicantP2pIfaceCallback> & callback)1705 int HidlManager::addP2pIfaceCallbackHidlObject(
1706     const std::string &ifname,
1707     const android::sp<ISupplicantP2pIfaceCallback> &callback)
1708 {
1709 	const std::function<void(
1710 	    const android::sp<ISupplicantP2pIfaceCallback> &)>
1711 	    on_hidl_died_fctor = std::bind(
1712 		&HidlManager::removeP2pIfaceCallbackHidlObject, this, ifname,
1713 		std::placeholders::_1);
1714 	return addIfaceCallbackHidlObjectToMap(
1715 	    ifname, callback, on_hidl_died_fctor, p2p_iface_callbacks_map_);
1716 }
1717 
1718 /**
1719  * Add a new iface callback hidl object reference to our
1720  * interface callback list.
1721  *
1722  * @param ifname Name of the corresponding interface.
1723  * @param callback Hidl reference of the callback object.
1724  *
1725  * @return 0 on success, 1 on failure.
1726  */
addStaIfaceCallbackHidlObject(const std::string & ifname,const android::sp<ISupplicantStaIfaceCallback> & callback)1727 int HidlManager::addStaIfaceCallbackHidlObject(
1728     const std::string &ifname,
1729     const android::sp<ISupplicantStaIfaceCallback> &callback)
1730 {
1731 	const std::function<void(
1732 	    const android::sp<ISupplicantStaIfaceCallback> &)>
1733 	    on_hidl_died_fctor = std::bind(
1734 		&HidlManager::removeStaIfaceCallbackHidlObject, this, ifname,
1735 		std::placeholders::_1);
1736 	return addIfaceCallbackHidlObjectToMap(
1737 	    ifname, callback, on_hidl_died_fctor, sta_iface_callbacks_map_);
1738 }
1739 
1740 /**
1741  * Add a new network callback hidl object reference to our network callback
1742  * list.
1743  *
1744  * @param ifname Name of the corresponding interface.
1745  * @param network_id ID of the corresponding network.
1746  * @param callback Hidl reference of the callback object.
1747  *
1748  * @return 0 on success, 1 on failure.
1749  */
addP2pNetworkCallbackHidlObject(const std::string & ifname,int network_id,const android::sp<ISupplicantP2pNetworkCallback> & callback)1750 int HidlManager::addP2pNetworkCallbackHidlObject(
1751     const std::string &ifname, int network_id,
1752     const android::sp<ISupplicantP2pNetworkCallback> &callback)
1753 {
1754 	const std::function<void(
1755 	    const android::sp<ISupplicantP2pNetworkCallback> &)>
1756 	    on_hidl_died_fctor = std::bind(
1757 		&HidlManager::removeP2pNetworkCallbackHidlObject, this, ifname,
1758 		network_id, std::placeholders::_1);
1759 	return addNetworkCallbackHidlObjectToMap(
1760 	    ifname, network_id, callback, on_hidl_died_fctor,
1761 	    p2p_network_callbacks_map_);
1762 }
1763 
1764 /**
1765  * Add a new network callback hidl object reference to our network callback
1766  * list.
1767  *
1768  * @param ifname Name of the corresponding interface.
1769  * @param network_id ID of the corresponding network.
1770  * @param callback Hidl reference of the callback object.
1771  *
1772  * @return 0 on success, 1 on failure.
1773  */
addStaNetworkCallbackHidlObject(const std::string & ifname,int network_id,const android::sp<ISupplicantStaNetworkCallback> & callback)1774 int HidlManager::addStaNetworkCallbackHidlObject(
1775     const std::string &ifname, int network_id,
1776     const android::sp<ISupplicantStaNetworkCallback> &callback)
1777 {
1778 	const std::function<void(
1779 	    const android::sp<ISupplicantStaNetworkCallback> &)>
1780 	    on_hidl_died_fctor = std::bind(
1781 		&HidlManager::removeStaNetworkCallbackHidlObject, this, ifname,
1782 		network_id, std::placeholders::_1);
1783 	return addNetworkCallbackHidlObjectToMap(
1784 	    ifname, network_id, callback, on_hidl_died_fctor,
1785 	    sta_network_callbacks_map_);
1786 }
1787 
1788 /**
1789  * Removes the provided |ISupplicantCallback| hidl object reference
1790  * from our global callback list.
1791  *
1792  * @param callback Hidl reference of the |ISupplicantCallback| object.
1793  */
removeSupplicantCallbackHidlObject(const android::sp<ISupplicantCallback> & callback)1794 void HidlManager::removeSupplicantCallbackHidlObject(
1795     const android::sp<ISupplicantCallback> &callback)
1796 {
1797 	supplicant_callbacks_.erase(
1798 	    std::remove(
1799 		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
1800 		callback),
1801 	    supplicant_callbacks_.end());
1802 }
1803 
1804 /**
1805  * Removes the provided iface callback hidl object reference from
1806  * our interface callback list.
1807  *
1808  * @param ifname Name of the corresponding interface.
1809  * @param callback Hidl reference of the callback object.
1810  */
removeP2pIfaceCallbackHidlObject(const std::string & ifname,const android::sp<ISupplicantP2pIfaceCallback> & callback)1811 void HidlManager::removeP2pIfaceCallbackHidlObject(
1812     const std::string &ifname,
1813     const android::sp<ISupplicantP2pIfaceCallback> &callback)
1814 {
1815 	return removeIfaceCallbackHidlObjectFromMap(
1816 	    ifname, callback, p2p_iface_callbacks_map_);
1817 }
1818 
1819 /**
1820  * Removes the provided iface callback hidl object reference from
1821  * our interface callback list.
1822  *
1823  * @param ifname Name of the corresponding interface.
1824  * @param callback Hidl reference of the callback object.
1825  */
removeStaIfaceCallbackHidlObject(const std::string & ifname,const android::sp<ISupplicantStaIfaceCallback> & callback)1826 void HidlManager::removeStaIfaceCallbackHidlObject(
1827     const std::string &ifname,
1828     const android::sp<ISupplicantStaIfaceCallback> &callback)
1829 {
1830 	return removeIfaceCallbackHidlObjectFromMap(
1831 	    ifname, callback, sta_iface_callbacks_map_);
1832 }
1833 
1834 /**
1835  * Removes the provided network callback hidl object reference from
1836  * our network callback list.
1837  *
1838  * @param ifname Name of the corresponding interface.
1839  * @param network_id ID of the corresponding network.
1840  * @param callback Hidl reference of the callback object.
1841  */
removeP2pNetworkCallbackHidlObject(const std::string & ifname,int network_id,const android::sp<ISupplicantP2pNetworkCallback> & callback)1842 void HidlManager::removeP2pNetworkCallbackHidlObject(
1843     const std::string &ifname, int network_id,
1844     const android::sp<ISupplicantP2pNetworkCallback> &callback)
1845 {
1846 	return removeNetworkCallbackHidlObjectFromMap(
1847 	    ifname, network_id, callback, p2p_network_callbacks_map_);
1848 }
1849 
1850 /**
1851  * Removes the provided network callback hidl object reference from
1852  * our network callback list.
1853  *
1854  * @param ifname Name of the corresponding interface.
1855  * @param network_id ID of the corresponding network.
1856  * @param callback Hidl reference of the callback object.
1857  */
removeStaNetworkCallbackHidlObject(const std::string & ifname,int network_id,const android::sp<ISupplicantStaNetworkCallback> & callback)1858 void HidlManager::removeStaNetworkCallbackHidlObject(
1859     const std::string &ifname, int network_id,
1860     const android::sp<ISupplicantStaNetworkCallback> &callback)
1861 {
1862 	return removeNetworkCallbackHidlObjectFromMap(
1863 	    ifname, network_id, callback, sta_network_callbacks_map_);
1864 }
1865 
1866 /**
1867  * Helper function to invoke the provided callback method on all the
1868  * registered |ISupplicantCallback| callback hidl objects.
1869  *
1870  * @param method Pointer to the required hidl method from
1871  * |ISupplicantCallback|.
1872  */
callWithEachSupplicantCallback(const std::function<Return<void> (android::sp<ISupplicantCallback>)> & method)1873 void HidlManager::callWithEachSupplicantCallback(
1874     const std::function<Return<void>(android::sp<ISupplicantCallback>)> &method)
1875 {
1876 	for (const auto &callback : supplicant_callbacks_) {
1877 		if (!method(callback).isOk()) {
1878 			wpa_printf(MSG_ERROR, "Failed to invoke HIDL callback");
1879 		}
1880 	}
1881 }
1882 
1883 /**
1884  * Helper fucntion to invoke the provided callback method on all the
1885  * registered iface callback hidl objects for the specified
1886  * |ifname|.
1887  *
1888  * @param ifname Name of the corresponding interface.
1889  * @param method Pointer to the required hidl method from
1890  * |ISupplicantIfaceCallback|.
1891  */
callWithEachP2pIfaceCallback(const std::string & ifname,const std::function<Return<void> (android::sp<ISupplicantP2pIfaceCallback>)> & method)1892 void HidlManager::callWithEachP2pIfaceCallback(
1893     const std::string &ifname,
1894     const std::function<Return<void>(android::sp<ISupplicantP2pIfaceCallback>)>
1895 	&method)
1896 {
1897 	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
1898 }
1899 
1900 /**
1901  * Helper function to invoke the provided callback method on all the
1902  * registered V1.1 interface callback hidl objects for the specified
1903  * |ifname|.
1904  *
1905  * @param ifname Name of the corresponding interface.
1906  * @param method Pointer to the required hidl method from
1907  * |V1_1::ISupplicantIfaceCallback|.
1908  */
callWithEachStaIfaceCallback_1_1(const std::string & ifname,const std::function<Return<void> (android::sp<V1_1::ISupplicantStaIfaceCallback>)> & method)1909 void HidlManager::callWithEachStaIfaceCallback_1_1(
1910     const std::string &ifname,
1911     const std::function<
1912 	Return<void>(android::sp<V1_1::ISupplicantStaIfaceCallback>)> &method)
1913 {
1914 	callWithEachIfaceCallback_1_1(ifname, method, sta_iface_callbacks_map_);
1915 }
1916 
1917 /**
1918  * Helper function to invoke the provided callback method on all the
1919  * registered V1.2 interface callback hidl objects for the specified
1920  * |ifname|.
1921  *
1922  * @param ifname Name of the corresponding interface.
1923  * @param method Pointer to the required hidl method from
1924  * |V1_2::ISupplicantIfaceCallback|.
1925  */
callWithEachStaIfaceCallback_1_2(const std::string & ifname,const std::function<Return<void> (android::sp<V1_2::ISupplicantStaIfaceCallback>)> & method)1926 void HidlManager::callWithEachStaIfaceCallback_1_2(
1927     const std::string &ifname,
1928     const std::function<
1929 	Return<void>(android::sp<V1_2::ISupplicantStaIfaceCallback>)> &method)
1930 {
1931 	callWithEachIfaceCallback_1_2(ifname, method, sta_iface_callbacks_map_);
1932 }
1933 
1934 /**
1935  * Helper function to invoke the provided callback method on all the
1936  * registered interface callback hidl objects for the specified
1937  * |ifname|.
1938  *
1939  * @param ifname Name of the corresponding interface.
1940  * @param method Pointer to the required hidl method from
1941  * |ISupplicantIfaceCallback|.
1942  */
callWithEachStaIfaceCallback(const std::string & ifname,const std::function<Return<void> (android::sp<ISupplicantStaIfaceCallback>)> & method)1943 void HidlManager::callWithEachStaIfaceCallback(
1944     const std::string &ifname,
1945     const std::function<Return<void>(android::sp<ISupplicantStaIfaceCallback>)>
1946 	&method)
1947 {
1948 	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
1949 }
1950 
1951 /**
1952  * Helper function to invoke the provided callback method on all the
1953  * registered network callback hidl objects for the specified
1954  * |ifname| & |network_id|.
1955  *
1956  * @param ifname Name of the corresponding interface.
1957  * @param network_id ID of the corresponding network.
1958  * @param method Pointer to the required hidl method from
1959  * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
1960  */
callWithEachP2pNetworkCallback(const std::string & ifname,int network_id,const std::function<Return<void> (android::sp<ISupplicantP2pNetworkCallback>)> & method)1961 void HidlManager::callWithEachP2pNetworkCallback(
1962     const std::string &ifname, int network_id,
1963     const std::function<
1964 	Return<void>(android::sp<ISupplicantP2pNetworkCallback>)> &method)
1965 {
1966 	callWithEachNetworkCallback(
1967 	    ifname, network_id, method, p2p_network_callbacks_map_);
1968 }
1969 
1970 /**
1971  * Helper function to invoke the provided callback method on all the
1972  * registered network callback hidl objects for the specified
1973  * |ifname| & |network_id|.
1974  *
1975  * @param ifname Name of the corresponding interface.
1976  * @param network_id ID of the corresponding network.
1977  * @param method Pointer to the required hidl method from
1978  * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
1979  */
callWithEachStaNetworkCallback(const std::string & ifname,int network_id,const std::function<Return<void> (android::sp<ISupplicantStaNetworkCallback>)> & method)1980 void HidlManager::callWithEachStaNetworkCallback(
1981     const std::string &ifname, int network_id,
1982     const std::function<
1983 	Return<void>(android::sp<ISupplicantStaNetworkCallback>)> &method)
1984 {
1985 	callWithEachNetworkCallback(
1986 	    ifname, network_id, method, sta_network_callbacks_map_);
1987 }
1988 }  // namespace implementation
1989 }  // namespace V1_2
1990 }  // namespace supplicant
1991 }  // namespace wifi
1992 }  // namespace hardware
1993 }  // namespace android
1994