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