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