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