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 ¶ms_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 ¶ms_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