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