Home | History | Annotate | Download | only in 1.1
      1 /*
      2  * hidl interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2016, Jouni Malinen <j (at) w1.fi>
      4  * Copyright (c) 2004-2016, Roshan Pius <rpius (at) google.com>
      5  *
      6  * This software may be distributed under the terms of the BSD license.
      7  * See README for more details.
      8  */
      9 
     10 #include <algorithm>
     11 #include <regex>
     12 
     13 #include "hidl_manager.h"
     14 #include "misc_utils.h"
     15 
     16 extern "C" {
     17 #include "src/eap_common/eap_sim_common.h"
     18 }
     19 
     20 namespace {
     21 using android::hardware::hidl_array;
     22 
     23 constexpr uint8_t kWfdDeviceInfoLen = 6;
     24 // GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>]
     25 constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)";
     26 constexpr char kGsmAuthRegex3[] =
     27     "GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)";
     28 // UMTS-AUTH:<RAND>:<AUTN>
     29 constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)";
     30 constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN;
     31 constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
     32 constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
     33 constexpr u8 kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
     34 /**
     35  * Check if the provided |wpa_supplicant| structure represents a P2P iface or
     36  * not.
     37  */
     38 constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s)
     39 {
     40 	return (wpa_s->global->p2p_init_wpa_s == wpa_s);
     41 }
     42 
     43 /**
     44  * Creates a unique key for the network using the provided |ifname| and
     45  * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
     46  * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
     47  *
     48  * @param ifname Name of the corresponding interface.
     49  * @param network_id ID of the corresponding network.
     50  */
     51 const std::string getNetworkObjectMapKey(
     52     const std::string &ifname, int network_id)
     53 {
     54 	return ifname + "_" + std::to_string(network_id);
     55 }
     56 
     57 /**
     58  * Add callback to the corresponding list after linking to death on the
     59  * corresponding hidl object reference.
     60  */
     61 template <class CallbackType>
     62 int registerForDeathAndAddCallbackHidlObjectToList(
     63     const android::sp<CallbackType> &callback,
     64     const std::function<void(const android::sp<CallbackType> &)>
     65 	&on_hidl_died_fctor,
     66     std::vector<android::sp<CallbackType>> &callback_list)
     67 {
     68 #if 0   // TODO(b/31632518): HIDL object death notifications.
     69 	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
     70 	    callback, on_hidl_died_fctor);
     71 	// Use the |callback.get()| as cookie so that we don't need to
     72 	// store a reference to this |CallbackObjectDeathNotifier| instance
     73 	// to use in |unlinkToDeath| later.
     74 	// NOTE: This may cause an immediate callback if the object is already
     75 	// dead, so add it to the list before we register for callback!
     76 	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
     77 		death_notifier, callback.get()) != android::OK) {
     78 		wpa_printf(
     79 		    MSG_ERROR,
     80 		    "Error registering for death notification for "
     81 		    "supplicant callback object");
     82 		callback_list.erase(
     83 		    std::remove(
     84 			callback_list.begin(), callback_list.end(), callback),
     85 		    callback_list.end());
     86 		return 1;
     87 	}
     88 #endif  // TODO(b/31632518): HIDL object death notifications.
     89 	callback_list.push_back(callback);
     90 	return 0;
     91 }
     92 
     93 template <class ObjectType>
     94 int addHidlObjectToMap(
     95     const std::string &key, const android::sp<ObjectType> object,
     96     std::map<const std::string, android::sp<ObjectType>> &object_map)
     97 {
     98 	// Return failure if we already have an object for that |key|.
     99 	if (object_map.find(key) != object_map.end())
    100 		return 1;
    101 	object_map[key] = object;
    102 	if (!object_map[key].get())
    103 		return 1;
    104 	return 0;
    105 }
    106 
    107 template <class ObjectType>
    108 int removeHidlObjectFromMap(
    109     const std::string &key,
    110     std::map<const std::string, android::sp<ObjectType>> &object_map)
    111 {
    112 	// Return failure if we dont have an object for that |key|.
    113 	const auto &object_iter = object_map.find(key);
    114 	if (object_iter == object_map.end())
    115 		return 1;
    116 	object_iter->second->invalidate();
    117 	object_map.erase(object_iter);
    118 	return 0;
    119 }
    120 
    121 template <class CallbackType>
    122 int addIfaceCallbackHidlObjectToMap(
    123     const std::string &ifname, const android::sp<CallbackType> &callback,
    124     const std::function<void(const android::sp<CallbackType> &)>
    125 	&on_hidl_died_fctor,
    126     std::map<const std::string, std::vector<android::sp<CallbackType>>>
    127 	&callbacks_map)
    128 {
    129 	if (ifname.empty())
    130 		return 1;
    131 
    132 	auto iface_callback_map_iter = callbacks_map.find(ifname);
    133 	if (iface_callback_map_iter == callbacks_map.end())
    134 		return 1;
    135 	auto &iface_callback_list = iface_callback_map_iter->second;
    136 
    137 	// Register for death notification before we add it to our list.
    138 	return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
    139 	    callback, on_hidl_died_fctor, iface_callback_list);
    140 }
    141 
    142 template <class CallbackType>
    143 int addNetworkCallbackHidlObjectToMap(
    144     const std::string &ifname, int network_id,
    145     const android::sp<CallbackType> &callback,
    146     const std::function<void(const android::sp<CallbackType> &)>
    147 	&on_hidl_died_fctor,
    148     std::map<const std::string, std::vector<android::sp<CallbackType>>>
    149 	&callbacks_map)
    150 {
    151 	if (ifname.empty() || network_id < 0)
    152 		return 1;
    153 
    154 	// Generate the key to be used to lookup the network.
    155 	const std::string network_key =
    156 	    getNetworkObjectMapKey(ifname, network_id);
    157 	auto network_callback_map_iter = callbacks_map.find(network_key);
    158 	if (network_callback_map_iter == callbacks_map.end())
    159 		return 1;
    160 	auto &network_callback_list = network_callback_map_iter->second;
    161 
    162 	// Register for death notification before we add it to our list.
    163 	return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
    164 	    callback, on_hidl_died_fctor, network_callback_list);
    165 }
    166 
    167 template <class CallbackType>
    168 int removeAllIfaceCallbackHidlObjectsFromMap(
    169     const std::string &ifname,
    170     std::map<const std::string, std::vector<android::sp<CallbackType>>>
    171 	&callbacks_map)
    172 {
    173 	auto iface_callback_map_iter = callbacks_map.find(ifname);
    174 	if (iface_callback_map_iter == callbacks_map.end())
    175 		return 1;
    176 #if 0   // TODO(b/31632518): HIDL object death notifications.
    177 	const auto &iface_callback_list = iface_callback_map_iter->second;
    178 	for (const auto &callback : iface_callback_list) {
    179 		if (android::hardware::IInterface::asBinder(callback)
    180 			->unlinkToDeath(nullptr, callback.get()) !=
    181 		    android::OK) {
    182 			wpa_printf(
    183 			    MSG_ERROR,
    184 			    "Error deregistering for death notification for "
    185 			    "iface callback object");
    186 		}
    187 	}
    188 #endif  // TODO(b/31632518): HIDL object death notifications.
    189 	callbacks_map.erase(iface_callback_map_iter);
    190 	return 0;
    191 }
    192 
    193 template <class CallbackType>
    194 int removeAllNetworkCallbackHidlObjectsFromMap(
    195     const std::string &network_key,
    196     std::map<const std::string, std::vector<android::sp<CallbackType>>>
    197 	&callbacks_map)
    198 {
    199 	auto network_callback_map_iter = callbacks_map.find(network_key);
    200 	if (network_callback_map_iter == callbacks_map.end())
    201 		return 1;
    202 #if 0   // TODO(b/31632518): HIDL object death notifications.
    203 	const auto &network_callback_list = network_callback_map_iter->second;
    204 	for (const auto &callback : network_callback_list) {
    205 		if (android::hardware::IInterface::asBinder(callback)
    206 			->unlinkToDeath(nullptr, callback.get()) !=
    207 		    android::OK) {
    208 			wpa_printf(
    209 			    MSG_ERROR,
    210 			    "Error deregistering for death "
    211 			    "notification for "
    212 			    "network callback object");
    213 		}
    214 	}
    215 #endif  // TODO(b/31632518): HIDL object death notifications.
    216 	callbacks_map.erase(network_callback_map_iter);
    217 	return 0;
    218 }
    219 
    220 template <class CallbackType>
    221 void removeIfaceCallbackHidlObjectFromMap(
    222     const std::string &ifname, const android::sp<CallbackType> &callback,
    223     std::map<const std::string, std::vector<android::sp<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>
    242 void removeNetworkCallbackHidlObjectFromMap(
    243     const std::string &ifname, int network_id,
    244     const android::sp<CallbackType> &callback,
    245     std::map<const std::string, std::vector<android::sp<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>
    268 void callWithEachIfaceCallback(
    269     const std::string &ifname,
    270     const std::function<
    271 	android::hardware::Return<void>(android::sp<CallbackType>)> &method,
    272     const std::map<const std::string, std::vector<android::sp<CallbackType>>>
    273 	&callbacks_map)
    274 {
    275 	if (ifname.empty())
    276 		return;
    277 
    278 	auto iface_callback_map_iter = callbacks_map.find(ifname);
    279 	if (iface_callback_map_iter == callbacks_map.end())
    280 		return;
    281 	const auto &iface_callback_list = iface_callback_map_iter->second;
    282 	for (const auto &callback : iface_callback_list) {
    283 		if (!method(callback).isOk()) {
    284 			wpa_printf(
    285 			    MSG_ERROR, "Failed to invoke HIDL iface callback");
    286 		}
    287 	}
    288 }
    289 
    290 template <class CallbackTypeV1_0, class CallbackTypeV1_1>
    291 void callWithEachIfaceCallback_1_1(
    292     const std::string &ifname,
    293     const std::function<
    294 	android::hardware::Return<void>(android::sp<CallbackTypeV1_1>)> &method,
    295     const std::map<const std::string, std::vector<android::sp<CallbackTypeV1_0>>>
    296 	&callbacks_map)
    297 {
    298 	if (ifname.empty())
    299 		return;
    300 
    301 	auto iface_callback_map_iter = callbacks_map.find(ifname);
    302 	if (iface_callback_map_iter == callbacks_map.end())
    303 		return;
    304 	const auto &iface_callback_list = iface_callback_map_iter->second;
    305 	for (const auto &callback : iface_callback_list) {
    306 		android::sp<CallbackTypeV1_1> callback_1_1 =
    307 		    CallbackTypeV1_1::castFrom(callback);
    308 		if (callback_1_1 == nullptr)
    309 			continue;
    310 
    311 		if (!method(callback_1_1).isOk()) {
    312 			wpa_printf(
    313 			    MSG_ERROR, "Failed to invoke HIDL iface callback");
    314 		}
    315 	}
    316 }
    317 
    318 template <class CallbackType>
    319 void callWithEachNetworkCallback(
    320     const std::string &ifname, int network_id,
    321     const std::function<
    322 	android::hardware::Return<void>(android::sp<CallbackType>)> &method,
    323     const std::map<const std::string, std::vector<android::sp<CallbackType>>>
    324 	&callbacks_map)
    325 {
    326 	if (ifname.empty() || network_id < 0)
    327 		return;
    328 
    329 	// Generate the key to be used to lookup the network.
    330 	const std::string network_key =
    331 	    getNetworkObjectMapKey(ifname, network_id);
    332 	auto network_callback_map_iter = callbacks_map.find(network_key);
    333 	if (network_callback_map_iter == callbacks_map.end())
    334 		return;
    335 	const auto &network_callback_list = network_callback_map_iter->second;
    336 	for (const auto &callback : network_callback_list) {
    337 		if (!method(callback).isOk()) {
    338 			wpa_printf(
    339 			    MSG_ERROR,
    340 			    "Failed to invoke HIDL network callback");
    341 		}
    342 	}
    343 }
    344 
    345 int parseGsmAuthNetworkRequest(
    346     const std::string &params_str,
    347     std::vector<hidl_array<uint8_t, kGsmRandLenBytes>> *out_rands)
    348 {
    349 	std::smatch matches;
    350 	std::regex params_gsm_regex2(kGsmAuthRegex2);
    351 	std::regex params_gsm_regex3(kGsmAuthRegex3);
    352 	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
    353 	    !std::regex_match(params_str, matches, params_gsm_regex2)) {
    354 		return 1;
    355 	}
    356 	for (uint32_t i = 1; i < matches.size(); i++) {
    357 		hidl_array<uint8_t, kGsmRandLenBytes> rand;
    358 		const auto &match = matches[i];
    359 		WPA_ASSERT(match.size() >= 2 * rand.size());
    360 		if (hexstr2bin(match.str().c_str(), rand.data(), rand.size())) {
    361 			wpa_printf(
    362 			    MSG_ERROR, "Failed to parse GSM auth params");
    363 			return 1;
    364 		}
    365 		out_rands->push_back(rand);
    366 	}
    367 	return 0;
    368 }
    369 
    370 int parseUmtsAuthNetworkRequest(
    371     const std::string &params_str,
    372     hidl_array<uint8_t, kUmtsRandLenBytes> *out_rand,
    373     hidl_array<uint8_t, kUmtsAutnLenBytes> *out_autn)
    374 {
    375 	std::smatch matches;
    376 	std::regex params_umts_regex(kUmtsAuthRegex);
    377 	if (!std::regex_match(params_str, matches, params_umts_regex)) {
    378 		return 1;
    379 	}
    380 	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
    381 	if (hexstr2bin(
    382 		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
    383 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
    384 		return 1;
    385 	}
    386 	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
    387 	if (hexstr2bin(
    388 		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
    389 		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
    390 		return 1;
    391 	}
    392 	return 0;
    393 }
    394 }  // namespace
    395 
    396 namespace android {
    397 namespace hardware {
    398 namespace wifi {
    399 namespace supplicant {
    400 namespace V1_1 {
    401 namespace implementation {
    402 
    403 using namespace android::hardware::wifi::supplicant::V1_0;
    404 using namespace android::hardware::wifi::supplicant::V1_1;
    405 using V1_0::ISupplicantStaIfaceCallback;
    406 
    407 HidlManager *HidlManager::instance_ = NULL;
    408 
    409 HidlManager *HidlManager::getInstance()
    410 {
    411 	if (!instance_)
    412 		instance_ = new HidlManager();
    413 	return instance_;
    414 }
    415 
    416 void HidlManager::destroyInstance()
    417 {
    418 	if (instance_)
    419 		delete instance_;
    420 	instance_ = NULL;
    421 }
    422 
    423 int HidlManager::registerHidlService(struct wpa_global *global)
    424 {
    425 	// Create the main hidl service object and register it.
    426 	supplicant_object_ = new Supplicant(global);
    427 	if (supplicant_object_->registerAsService() != android::NO_ERROR) {
    428 		return 1;
    429 	}
    430 	return 0;
    431 }
    432 
    433 /**
    434  * Register an interface to hidl manager.
    435  *
    436  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    437  *
    438  * @return 0 on success, 1 on failure.
    439  */
    440 int HidlManager::registerInterface(struct wpa_supplicant *wpa_s)
    441 {
    442 	if (!wpa_s)
    443 		return 1;
    444 
    445 	if (isP2pIface(wpa_s)) {
    446 		if (addHidlObjectToMap<P2pIface>(
    447 			wpa_s->ifname,
    448 			new P2pIface(wpa_s->global, wpa_s->ifname),
    449 			p2p_iface_object_map_)) {
    450 			wpa_printf(
    451 			    MSG_ERROR,
    452 			    "Failed to register P2P interface with HIDL "
    453 			    "control: %s",
    454 			    wpa_s->ifname);
    455 			return 1;
    456 		}
    457 		p2p_iface_callbacks_map_[wpa_s->ifname] =
    458 		    std::vector<android::sp<ISupplicantP2pIfaceCallback>>();
    459 	} else {
    460 		if (addHidlObjectToMap<StaIface>(
    461 			wpa_s->ifname,
    462 			new StaIface(wpa_s->global, wpa_s->ifname),
    463 			sta_iface_object_map_)) {
    464 			wpa_printf(
    465 			    MSG_ERROR,
    466 			    "Failed to register STA interface with HIDL "
    467 			    "control: %s",
    468 			    wpa_s->ifname);
    469 			return 1;
    470 		}
    471 		sta_iface_callbacks_map_[wpa_s->ifname] =
    472 		    std::vector<android::sp<ISupplicantStaIfaceCallback>>();
    473 	}
    474 
    475 	// Invoke the |onInterfaceCreated| method on all registered callbacks.
    476 	callWithEachSupplicantCallback(std::bind(
    477 	    &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
    478 	    wpa_s->ifname));
    479 	return 0;
    480 }
    481 
    482 /**
    483  * Unregister an interface from hidl manager.
    484  *
    485  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    486  *
    487  * @return 0 on success, 1 on failure.
    488  */
    489 int HidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
    490 {
    491 	if (!wpa_s)
    492 		return 1;
    493 
    494 	// Check if this interface is present in P2P map first, else check in
    495 	// STA map.
    496 	// Note: We can't use isP2pIface() here because interface
    497 	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
    498 	// function is cleared by the core before notifying the HIDL interface.
    499 	bool success =
    500 	    !removeHidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
    501 	if (success) {  // assumed to be P2P
    502 		success = !removeAllIfaceCallbackHidlObjectsFromMap(
    503 		    wpa_s->ifname, p2p_iface_callbacks_map_);
    504 	} else {  // assumed to be STA
    505 		success = !removeHidlObjectFromMap(
    506 		    wpa_s->ifname, sta_iface_object_map_);
    507 		if (success) {
    508 			success = !removeAllIfaceCallbackHidlObjectsFromMap(
    509 			    wpa_s->ifname, sta_iface_callbacks_map_);
    510 		}
    511 	}
    512 	if (!success) {
    513 		wpa_printf(
    514 		    MSG_ERROR,
    515 		    "Failed to unregister interface with HIDL "
    516 		    "control: %s",
    517 		    wpa_s->ifname);
    518 		return 1;
    519 	}
    520 
    521 	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
    522 	callWithEachSupplicantCallback(std::bind(
    523 	    &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
    524 	    wpa_s->ifname));
    525 	return 0;
    526 }
    527 
    528 /**
    529  * Register a network to hidl manager.
    530  *
    531  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    532  * the network is added.
    533  * @param ssid |wpa_ssid| struct corresponding to the network being added.
    534  *
    535  * @return 0 on success, 1 on failure.
    536  */
    537 int HidlManager::registerNetwork(
    538     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
    539 {
    540 	if (!wpa_s || !ssid)
    541 		return 1;
    542 
    543 	// Generate the key to be used to lookup the network.
    544 	const std::string network_key =
    545 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
    546 
    547 	if (isP2pIface(wpa_s)) {
    548 		if (addHidlObjectToMap<P2pNetwork>(
    549 			network_key,
    550 			new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
    551 			p2p_network_object_map_)) {
    552 			wpa_printf(
    553 			    MSG_ERROR,
    554 			    "Failed to register P2P network with HIDL "
    555 			    "control: %d",
    556 			    ssid->id);
    557 			return 1;
    558 		}
    559 		p2p_network_callbacks_map_[network_key] =
    560 		    std::vector<android::sp<ISupplicantP2pNetworkCallback>>();
    561 		// Invoke the |onNetworkAdded| method on all registered
    562 		// callbacks.
    563 		callWithEachP2pIfaceCallback(
    564 		    wpa_s->ifname,
    565 		    std::bind(
    566 			&ISupplicantP2pIfaceCallback::onNetworkAdded,
    567 			std::placeholders::_1, ssid->id));
    568 	} else {
    569 		if (addHidlObjectToMap<StaNetwork>(
    570 			network_key,
    571 			new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
    572 			sta_network_object_map_)) {
    573 			wpa_printf(
    574 			    MSG_ERROR,
    575 			    "Failed to register STA network with HIDL "
    576 			    "control: %d",
    577 			    ssid->id);
    578 			return 1;
    579 		}
    580 		sta_network_callbacks_map_[network_key] =
    581 		    std::vector<android::sp<ISupplicantStaNetworkCallback>>();
    582 		// Invoke the |onNetworkAdded| method on all registered
    583 		// callbacks.
    584 		callWithEachStaIfaceCallback(
    585 		    wpa_s->ifname,
    586 		    std::bind(
    587 			&ISupplicantStaIfaceCallback::onNetworkAdded,
    588 			std::placeholders::_1, ssid->id));
    589 	}
    590 	return 0;
    591 }
    592 
    593 /**
    594  * Unregister a network from hidl manager.
    595  *
    596  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    597  * the network is added.
    598  * @param ssid |wpa_ssid| struct corresponding to the network being added.
    599  *
    600  * @return 0 on success, 1 on failure.
    601  */
    602 int HidlManager::unregisterNetwork(
    603     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
    604 {
    605 	if (!wpa_s || !ssid)
    606 		return 1;
    607 
    608 	// Generate the key to be used to lookup the network.
    609 	const std::string network_key =
    610 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
    611 
    612 	if (isP2pIface(wpa_s)) {
    613 		if (removeHidlObjectFromMap(
    614 			network_key, p2p_network_object_map_)) {
    615 			wpa_printf(
    616 			    MSG_ERROR,
    617 			    "Failed to unregister P2P network with HIDL "
    618 			    "control: %d",
    619 			    ssid->id);
    620 			return 1;
    621 		}
    622 		if (removeAllNetworkCallbackHidlObjectsFromMap(
    623 			network_key, p2p_network_callbacks_map_))
    624 			return 1;
    625 
    626 		// Invoke the |onNetworkRemoved| method on all registered
    627 		// callbacks.
    628 		callWithEachP2pIfaceCallback(
    629 		    wpa_s->ifname,
    630 		    std::bind(
    631 			&ISupplicantP2pIfaceCallback::onNetworkRemoved,
    632 			std::placeholders::_1, ssid->id));
    633 	} else {
    634 		if (removeHidlObjectFromMap(
    635 			network_key, sta_network_object_map_)) {
    636 			wpa_printf(
    637 			    MSG_ERROR,
    638 			    "Failed to unregister STA network with HIDL "
    639 			    "control: %d",
    640 			    ssid->id);
    641 			return 1;
    642 		}
    643 		if (removeAllNetworkCallbackHidlObjectsFromMap(
    644 			network_key, sta_network_callbacks_map_))
    645 			return 1;
    646 
    647 		// Invoke the |onNetworkRemoved| method on all registered
    648 		// callbacks.
    649 		callWithEachStaIfaceCallback(
    650 		    wpa_s->ifname,
    651 		    std::bind(
    652 			&ISupplicantStaIfaceCallback::onNetworkRemoved,
    653 			std::placeholders::_1, ssid->id));
    654 	}
    655 	return 0;
    656 }
    657 
    658 /**
    659  * Notify all listeners about any state changes on a particular interface.
    660  *
    661  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    662  * the state change event occured.
    663  */
    664 int HidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
    665 {
    666 	if (!wpa_s)
    667 		return 1;
    668 
    669 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    670 	    sta_iface_object_map_.end())
    671 		return 1;
    672 
    673 	// Invoke the |onStateChanged| method on all registered callbacks.
    674 	uint32_t hidl_network_id = UINT32_MAX;
    675 	std::vector<uint8_t> hidl_ssid;
    676 	if (wpa_s->current_ssid) {
    677 		hidl_network_id = wpa_s->current_ssid->id;
    678 		hidl_ssid.assign(
    679 		    wpa_s->current_ssid->ssid,
    680 		    wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
    681 	}
    682 	uint8_t *bssid;
    683 	// wpa_supplicant sets the |pending_bssid| field when it starts a
    684 	// connection. Only after association state does it update the |bssid|
    685 	// field. So, in the HIDL callback send the appropriate bssid.
    686 	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
    687 		bssid = wpa_s->pending_bssid;
    688 	} else {
    689 		bssid = wpa_s->bssid;
    690 	}
    691 	callWithEachStaIfaceCallback(
    692 	    wpa_s->ifname, std::bind(
    693 			       &ISupplicantStaIfaceCallback::onStateChanged,
    694 			       std::placeholders::_1,
    695 			       static_cast<ISupplicantStaIfaceCallback::State>(
    696 				   wpa_s->wpa_state),
    697 			       bssid, hidl_network_id, hidl_ssid));
    698 	return 0;
    699 }
    700 
    701 /**
    702  * Notify all listeners about a request on a particular network.
    703  *
    704  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    705  * the network is present.
    706  * @param ssid |wpa_ssid| struct corresponding to the network.
    707  * @param type type of request.
    708  * @param param addition params associated with the request.
    709  */
    710 int HidlManager::notifyNetworkRequest(
    711     struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
    712     const char *param)
    713 {
    714 	if (!wpa_s || !ssid)
    715 		return 1;
    716 
    717 	const std::string network_key =
    718 	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
    719 	if (sta_network_object_map_.find(network_key) ==
    720 	    sta_network_object_map_.end())
    721 		return 1;
    722 
    723 	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
    724 		callWithEachStaNetworkCallback(
    725 		    wpa_s->ifname, ssid->id,
    726 		    std::bind(
    727 			&ISupplicantStaNetworkCallback::
    728 			    onNetworkEapIdentityRequest,
    729 			std::placeholders::_1));
    730 		return 0;
    731 	}
    732 	if (type == WPA_CTRL_REQ_SIM) {
    733 		std::vector<hidl_array<uint8_t, 16>> gsm_rands;
    734 		hidl_array<uint8_t, 16> umts_rand;
    735 		hidl_array<uint8_t, 16> umts_autn;
    736 		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
    737 			ISupplicantStaNetworkCallback::
    738 			    NetworkRequestEapSimGsmAuthParams hidl_params;
    739 			hidl_params.rands = gsm_rands;
    740 			callWithEachStaNetworkCallback(
    741 			    wpa_s->ifname, ssid->id,
    742 			    std::bind(
    743 				&ISupplicantStaNetworkCallback::
    744 				    onNetworkEapSimGsmAuthRequest,
    745 				std::placeholders::_1, hidl_params));
    746 			return 0;
    747 		}
    748 		if (!parseUmtsAuthNetworkRequest(
    749 			param, &umts_rand, &umts_autn)) {
    750 			ISupplicantStaNetworkCallback::
    751 			    NetworkRequestEapSimUmtsAuthParams hidl_params;
    752 			hidl_params.rand = umts_rand;
    753 			hidl_params.autn = umts_autn;
    754 			callWithEachStaNetworkCallback(
    755 			    wpa_s->ifname, ssid->id,
    756 			    std::bind(
    757 				&ISupplicantStaNetworkCallback::
    758 				    onNetworkEapSimUmtsAuthRequest,
    759 				std::placeholders::_1, hidl_params));
    760 			return 0;
    761 		}
    762 	}
    763 	return 1;
    764 }
    765 
    766 /**
    767  * Notify all listeners about the end of an ANQP query.
    768  *
    769  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    770  * @param bssid BSSID of the access point.
    771  * @param result Result of the operation ("SUCCESS" or "FAILURE").
    772  * @param anqp |wpa_bss_anqp| ANQP data fetched.
    773  */
    774 void HidlManager::notifyAnqpQueryDone(
    775     struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
    776     const struct wpa_bss_anqp *anqp)
    777 {
    778 	if (!wpa_s || !bssid || !result || !anqp)
    779 		return;
    780 
    781 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    782 	    sta_iface_object_map_.end())
    783 		return;
    784 
    785 	ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data;
    786 	ISupplicantStaIfaceCallback::Hs20AnqpData hidl_hs20_anqp_data;
    787 	if (std::string(result) == "SUCCESS") {
    788 		hidl_anqp_data.venueName =
    789 		    misc_utils::convertWpaBufToVector(anqp->venue_name);
    790 		hidl_anqp_data.roamingConsortium =
    791 		    misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
    792 		hidl_anqp_data.ipAddrTypeAvailability =
    793 		    misc_utils::convertWpaBufToVector(
    794 			anqp->ip_addr_type_availability);
    795 		hidl_anqp_data.naiRealm =
    796 		    misc_utils::convertWpaBufToVector(anqp->nai_realm);
    797 		hidl_anqp_data.anqp3gppCellularNetwork =
    798 		    misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
    799 		hidl_anqp_data.domainName =
    800 		    misc_utils::convertWpaBufToVector(anqp->domain_name);
    801 
    802 		hidl_hs20_anqp_data.operatorFriendlyName =
    803 		    misc_utils::convertWpaBufToVector(
    804 			anqp->hs20_operator_friendly_name);
    805 		hidl_hs20_anqp_data.wanMetrics =
    806 		    misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
    807 		hidl_hs20_anqp_data.connectionCapability =
    808 		    misc_utils::convertWpaBufToVector(
    809 			anqp->hs20_connection_capability);
    810 		hidl_hs20_anqp_data.osuProvidersList =
    811 		    misc_utils::convertWpaBufToVector(
    812 			anqp->hs20_osu_providers_list);
    813 	}
    814 
    815 	callWithEachStaIfaceCallback(
    816 	    wpa_s->ifname, std::bind(
    817 			       &ISupplicantStaIfaceCallback::onAnqpQueryDone,
    818 			       std::placeholders::_1, bssid, hidl_anqp_data,
    819 			       hidl_hs20_anqp_data));
    820 }
    821 
    822 /**
    823  * Notify all listeners about the end of an HS20 icon query.
    824  *
    825  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    826  * @param bssid BSSID of the access point.
    827  * @param file_name Name of the icon file.
    828  * @param image Raw bytes of the icon file.
    829  * @param image_length Size of the the icon file.
    830  */
    831 void HidlManager::notifyHs20IconQueryDone(
    832     struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
    833     const u8 *image, u32 image_length)
    834 {
    835 	if (!wpa_s || !bssid || !file_name || !image)
    836 		return;
    837 
    838 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    839 	    sta_iface_object_map_.end())
    840 		return;
    841 
    842 	callWithEachStaIfaceCallback(
    843 	    wpa_s->ifname,
    844 	    std::bind(
    845 		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
    846 		std::placeholders::_1, bssid, file_name,
    847 		std::vector<uint8_t>(image, image + image_length)));
    848 }
    849 
    850 /**
    851  * Notify all listeners about the reception of HS20 subscription
    852  * remediation notification from the server.
    853  *
    854  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    855  * @param url URL of the server.
    856  * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
    857  */
    858 void HidlManager::notifyHs20RxSubscriptionRemediation(
    859     struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
    860 {
    861 	if (!wpa_s || !url)
    862 		return;
    863 
    864 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    865 	    sta_iface_object_map_.end())
    866 		return;
    867 
    868 	ISupplicantStaIfaceCallback::OsuMethod hidl_osu_method = {};
    869 	if (osu_method & 0x1) {
    870 		hidl_osu_method =
    871 		    ISupplicantStaIfaceCallback::OsuMethod::OMA_DM;
    872 	} else if (osu_method & 0x2) {
    873 		hidl_osu_method =
    874 		    ISupplicantStaIfaceCallback::OsuMethod::SOAP_XML_SPP;
    875 	}
    876 	callWithEachStaIfaceCallback(
    877 	    wpa_s->ifname,
    878 	    std::bind(
    879 		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
    880 		std::placeholders::_1, wpa_s->bssid, hidl_osu_method, url));
    881 }
    882 
    883 /**
    884  * Notify all listeners about the reception of HS20 immient deauth
    885  * notification from the server.
    886  *
    887  * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
    888  * @param code Deauth reason code sent from server.
    889  * @param reauth_delay Reauthentication delay in seconds sent from server.
    890  * @param url URL of the server.
    891  */
    892 void HidlManager::notifyHs20RxDeauthImminentNotice(
    893     struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
    894 {
    895 	if (!wpa_s || !url)
    896 		return;
    897 
    898 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    899 	    sta_iface_object_map_.end())
    900 		return;
    901 
    902 	callWithEachStaIfaceCallback(
    903 	    wpa_s->ifname,
    904 	    std::bind(
    905 		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
    906 		std::placeholders::_1, wpa_s->bssid, code, reauth_delay, url));
    907 }
    908 
    909 /**
    910  * Notify all listeners about the reason code for disconnection from the
    911  * currently connected network.
    912  *
    913  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    914  * the network is present.
    915  */
    916 void HidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
    917 {
    918 	if (!wpa_s)
    919 		return;
    920 
    921 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    922 	    sta_iface_object_map_.end())
    923 		return;
    924 
    925 	const u8 *bssid = wpa_s->bssid;
    926 	if (is_zero_ether_addr(bssid)) {
    927 		bssid = wpa_s->pending_bssid;
    928 	}
    929 
    930 	callWithEachStaIfaceCallback(
    931 	    wpa_s->ifname,
    932 	    std::bind(
    933 		&ISupplicantStaIfaceCallback::onDisconnected,
    934 		std::placeholders::_1, bssid, wpa_s->disconnect_reason < 0,
    935 		static_cast<ISupplicantStaIfaceCallback::ReasonCode>(
    936 		    abs(wpa_s->disconnect_reason))));
    937 }
    938 
    939 /**
    940  * Notify all listeners about association reject from the access point to which
    941  * we are attempting to connect.
    942  *
    943  * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
    944  * the network is present.
    945  */
    946 void HidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s)
    947 {
    948 	if (!wpa_s)
    949 		return;
    950 
    951 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
    952 	    sta_iface_object_map_.end())
    953 		return;
    954 
    955 	const u8 *bssid = wpa_s->bssid;
    956 	if (is_zero_ether_addr(bssid)) {
    957 		bssid = wpa_s->pending_bssid;
    958 	}
    959 
    960 	callWithEachStaIfaceCallback(
    961 	    wpa_s->ifname,
    962 	    std::bind(
    963 		&ISupplicantStaIfaceCallback::onAssociationRejected,
    964 		std::placeholders::_1, bssid,
    965 		static_cast<ISupplicantStaIfaceCallback::StatusCode>(
    966 		    wpa_s->assoc_status_code),
    967 		wpa_s->assoc_timed_out == 1));
    968 }
    969 
    970 void HidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
    971 {
    972 	if (!wpa_s)
    973 		return;
    974 
    975 	const std::string ifname(wpa_s->ifname);
    976 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
    977 		return;
    978 
    979 	const u8 *bssid = wpa_s->bssid;
    980 	if (is_zero_ether_addr(bssid)) {
    981 		bssid = wpa_s->pending_bssid;
    982 	}
    983 	callWithEachStaIfaceCallback(
    984 	    wpa_s->ifname,
    985 	    std::bind(
    986 		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
    987 		std::placeholders::_1, bssid));
    988 }
    989 
    990 void HidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
    991 {
    992 	if (!wpa_s)
    993 		return;
    994 
    995 	const std::string ifname(wpa_s->ifname);
    996 	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
    997 		return;
    998 
    999 	// wpa_supplicant does not explicitly give us the reason for bssid
   1000 	// change, but we figure that out from what is set out of |wpa_s->bssid|
   1001 	// & |wpa_s->pending_bssid|.
   1002 	const u8 *bssid;
   1003 	ISupplicantStaIfaceCallback::BssidChangeReason reason;
   1004 	if (is_zero_ether_addr(wpa_s->bssid) &&
   1005 	    !is_zero_ether_addr(wpa_s->pending_bssid)) {
   1006 		bssid = wpa_s->pending_bssid;
   1007 		reason =
   1008 		    ISupplicantStaIfaceCallback::BssidChangeReason::ASSOC_START;
   1009 	} else if (
   1010 	    !is_zero_ether_addr(wpa_s->bssid) &&
   1011 	    is_zero_ether_addr(wpa_s->pending_bssid)) {
   1012 		bssid = wpa_s->bssid;
   1013 		reason = ISupplicantStaIfaceCallback::BssidChangeReason::
   1014 		    ASSOC_COMPLETE;
   1015 	} else if (
   1016 	    is_zero_ether_addr(wpa_s->bssid) &&
   1017 	    is_zero_ether_addr(wpa_s->pending_bssid)) {
   1018 		bssid = wpa_s->pending_bssid;
   1019 		reason =
   1020 		    ISupplicantStaIfaceCallback::BssidChangeReason::DISASSOC;
   1021 	} else {
   1022 		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
   1023 		return;
   1024 	}
   1025 
   1026 	callWithEachStaIfaceCallback(
   1027 	    wpa_s->ifname, std::bind(
   1028 			       &ISupplicantStaIfaceCallback::onBssidChanged,
   1029 			       std::placeholders::_1, reason, bssid));
   1030 }
   1031 
   1032 void HidlManager::notifyWpsEventFail(
   1033     struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
   1034     uint16_t error_indication)
   1035 {
   1036 	if (!wpa_s || !peer_macaddr)
   1037 		return;
   1038 
   1039 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
   1040 	    sta_iface_object_map_.end())
   1041 		return;
   1042 
   1043 	callWithEachStaIfaceCallback(
   1044 	    wpa_s->ifname,
   1045 	    std::bind(
   1046 		&ISupplicantStaIfaceCallback::onWpsEventFail,
   1047 		std::placeholders::_1, peer_macaddr,
   1048 		static_cast<ISupplicantStaIfaceCallback::WpsConfigError>(
   1049 		    config_error),
   1050 		static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>(
   1051 		    error_indication)));
   1052 }
   1053 
   1054 void HidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
   1055 {
   1056 	if (!wpa_s)
   1057 		return;
   1058 
   1059 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
   1060 	    sta_iface_object_map_.end())
   1061 		return;
   1062 
   1063 	callWithEachStaIfaceCallback(
   1064 	    wpa_s->ifname, std::bind(
   1065 			       &ISupplicantStaIfaceCallback::onWpsEventSuccess,
   1066 			       std::placeholders::_1));
   1067 }
   1068 
   1069 void HidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
   1070 {
   1071 	if (!wpa_s)
   1072 		return;
   1073 
   1074 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
   1075 	    sta_iface_object_map_.end())
   1076 		return;
   1077 
   1078 	callWithEachStaIfaceCallback(
   1079 	    wpa_s->ifname,
   1080 	    std::bind(
   1081 		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
   1082 		std::placeholders::_1));
   1083 }
   1084 
   1085 void HidlManager::notifyP2pDeviceFound(
   1086     struct wpa_supplicant *wpa_s, const u8 *addr,
   1087     const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
   1088     u8 peer_wfd_device_info_len)
   1089 {
   1090 	if (!wpa_s || !addr || !info)
   1091 		return;
   1092 
   1093 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1094 	    p2p_iface_object_map_.end())
   1095 		return;
   1096 
   1097 	std::array<uint8_t, kWfdDeviceInfoLen> hidl_peer_wfd_device_info{};
   1098 	if (peer_wfd_device_info) {
   1099 		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
   1100 			wpa_printf(
   1101 			    MSG_ERROR, "Unexpected WFD device info len: %d",
   1102 			    peer_wfd_device_info_len);
   1103 		} else {
   1104 			os_memcpy(
   1105 			    hidl_peer_wfd_device_info.data(),
   1106 			    peer_wfd_device_info, kWfdDeviceInfoLen);
   1107 		}
   1108 	}
   1109 
   1110 	callWithEachP2pIfaceCallback(
   1111 	    wpa_s->ifname,
   1112 	    std::bind(
   1113 		&ISupplicantP2pIfaceCallback::onDeviceFound,
   1114 		std::placeholders::_1, addr, info->p2p_device_addr,
   1115 		info->pri_dev_type, info->device_name, info->config_methods,
   1116 		info->dev_capab, info->group_capab, hidl_peer_wfd_device_info));
   1117 }
   1118 
   1119 void HidlManager::notifyP2pDeviceLost(
   1120     struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
   1121 {
   1122 	if (!wpa_s || !p2p_device_addr)
   1123 		return;
   1124 
   1125 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1126 	    p2p_iface_object_map_.end())
   1127 		return;
   1128 
   1129 	callWithEachP2pIfaceCallback(
   1130 	    wpa_s->ifname, std::bind(
   1131 			       &ISupplicantP2pIfaceCallback::onDeviceLost,
   1132 			       std::placeholders::_1, p2p_device_addr));
   1133 }
   1134 
   1135 void HidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
   1136 {
   1137 	if (!wpa_s)
   1138 		return;
   1139 
   1140 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1141 	    p2p_iface_object_map_.end())
   1142 		return;
   1143 
   1144 	callWithEachP2pIfaceCallback(
   1145 	    wpa_s->ifname, std::bind(
   1146 			       &ISupplicantP2pIfaceCallback::onFindStopped,
   1147 			       std::placeholders::_1));
   1148 }
   1149 
   1150 void HidlManager::notifyP2pGoNegReq(
   1151     struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
   1152     u8 /* go_intent */)
   1153 {
   1154 	if (!wpa_s || !src_addr)
   1155 		return;
   1156 
   1157 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1158 	    p2p_iface_object_map_.end())
   1159 		return;
   1160 
   1161 	callWithEachP2pIfaceCallback(
   1162 	    wpa_s->ifname,
   1163 	    std::bind(
   1164 		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
   1165 		std::placeholders::_1, src_addr,
   1166 		static_cast<ISupplicantP2pIfaceCallback::WpsDevPasswordId>(
   1167 		    dev_passwd_id)));
   1168 }
   1169 
   1170 void HidlManager::notifyP2pGoNegCompleted(
   1171     struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
   1172 {
   1173 	if (!wpa_s || !res)
   1174 		return;
   1175 
   1176 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1177 	    p2p_iface_object_map_.end())
   1178 		return;
   1179 
   1180 	callWithEachP2pIfaceCallback(
   1181 	    wpa_s->ifname,
   1182 	    std::bind(
   1183 		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
   1184 		std::placeholders::_1,
   1185 		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
   1186 		    res->status)));
   1187 }
   1188 
   1189 void HidlManager::notifyP2pGroupFormationFailure(
   1190     struct wpa_supplicant *wpa_s, const char *reason)
   1191 {
   1192 	if (!wpa_s || !reason)
   1193 		return;
   1194 
   1195 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1196 	    p2p_iface_object_map_.end())
   1197 		return;
   1198 
   1199 	callWithEachP2pIfaceCallback(
   1200 	    wpa_s->ifname,
   1201 	    std::bind(
   1202 		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
   1203 		std::placeholders::_1, reason));
   1204 }
   1205 
   1206 void HidlManager::notifyP2pGroupStarted(
   1207     struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid, int persistent, int client)
   1208 {
   1209 	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
   1210 		return;
   1211 
   1212 	// For group notifications, need to use the parent iface for callbacks.
   1213 	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
   1214 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1215 	    p2p_iface_object_map_.end())
   1216 		return;
   1217 
   1218 	uint32_t hidl_freq = wpa_group_s->current_bss
   1219 				 ? wpa_group_s->current_bss->freq
   1220 				 : wpa_group_s->assoc_freq;
   1221 	std::array<uint8_t, 32> hidl_psk;
   1222 	if (ssid->psk_set) {
   1223 		os_memcpy(hidl_psk.data(), ssid->psk, 32);
   1224 	}
   1225 	bool hidl_is_go = (client == 0 ? true : false);
   1226 	bool hidl_is_persistent = (persistent == 1 ? true : false);
   1227 
   1228 	callWithEachP2pIfaceCallback(
   1229 	    wpa_s->ifname,
   1230 	    std::bind(
   1231 		&ISupplicantP2pIfaceCallback::onGroupStarted,
   1232 		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go,
   1233 		std::vector<uint8_t>{ssid->ssid, ssid->ssid + ssid->ssid_len},
   1234 		hidl_freq, hidl_psk, ssid->passphrase, wpa_group_s->go_dev_addr,
   1235 		hidl_is_persistent));
   1236 }
   1237 
   1238 void HidlManager::notifyP2pGroupRemoved(
   1239     struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
   1240     const char *role)
   1241 {
   1242 	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
   1243 		return;
   1244 
   1245 	// For group notifications, need to use the parent iface for callbacks.
   1246 	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
   1247 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1248 	    p2p_iface_object_map_.end())
   1249 		return;
   1250 
   1251 	bool hidl_is_go = (std::string(role) == "GO");
   1252 
   1253 	callWithEachP2pIfaceCallback(
   1254 	    wpa_s->ifname,
   1255 	    std::bind(
   1256 		&ISupplicantP2pIfaceCallback::onGroupRemoved,
   1257 		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go));
   1258 }
   1259 
   1260 void HidlManager::notifyP2pInvitationReceived(
   1261     struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
   1262     const u8 *bssid, int id, int op_freq)
   1263 {
   1264 	if (!wpa_s || !sa || !go_dev_addr || !bssid)
   1265 		return;
   1266 
   1267 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1268 	    p2p_iface_object_map_.end())
   1269 		return;
   1270 
   1271 	SupplicantNetworkId hidl_network_id;
   1272 	if (id < 0) {
   1273 		hidl_network_id = UINT32_MAX;
   1274 	}
   1275 	hidl_network_id = id;
   1276 
   1277 	callWithEachP2pIfaceCallback(
   1278 	    wpa_s->ifname,
   1279 	    std::bind(
   1280 		&ISupplicantP2pIfaceCallback::onInvitationReceived,
   1281 		std::placeholders::_1, sa, go_dev_addr, bssid, hidl_network_id,
   1282 		op_freq));
   1283 }
   1284 
   1285 void HidlManager::notifyP2pInvitationResult(
   1286     struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
   1287 {
   1288 	if (!wpa_s)
   1289 		return;
   1290 
   1291 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1292 	    p2p_iface_object_map_.end())
   1293 		return;
   1294 
   1295 	callWithEachP2pIfaceCallback(
   1296 	    wpa_s->ifname,
   1297 	    std::bind(
   1298 		&ISupplicantP2pIfaceCallback::onInvitationResult,
   1299 		std::placeholders::_1, bssid ? bssid : kZeroBssid,
   1300 		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
   1301 		    status)));
   1302 }
   1303 
   1304 void HidlManager::notifyP2pProvisionDiscovery(
   1305     struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
   1306     enum p2p_prov_disc_status status, u16 config_methods,
   1307     unsigned int generated_pin)
   1308 {
   1309 	if (!wpa_s || !dev_addr)
   1310 		return;
   1311 
   1312 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1313 	    p2p_iface_object_map_.end())
   1314 		return;
   1315 
   1316 	std::string hidl_generated_pin;
   1317 	if (generated_pin > 0) {
   1318 		hidl_generated_pin =
   1319 		    misc_utils::convertWpsPinToString(generated_pin);
   1320 	}
   1321 	bool hidl_is_request = (request == 1 ? true : false);
   1322 
   1323 	callWithEachP2pIfaceCallback(
   1324 	    wpa_s->ifname,
   1325 	    std::bind(
   1326 		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
   1327 		std::placeholders::_1, dev_addr, hidl_is_request,
   1328 		static_cast<ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode>(
   1329 		    status),
   1330 		config_methods, hidl_generated_pin));
   1331 }
   1332 
   1333 void HidlManager::notifyP2pSdResponse(
   1334     struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
   1335     const u8 *tlvs, size_t tlvs_len)
   1336 {
   1337 	if (!wpa_s || !sa || !tlvs)
   1338 		return;
   1339 
   1340 	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
   1341 	    p2p_iface_object_map_.end())
   1342 		return;
   1343 
   1344 	callWithEachP2pIfaceCallback(
   1345 	    wpa_s->ifname,
   1346 	    std::bind(
   1347 		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
   1348 		std::placeholders::_1, sa, update_indic,
   1349 		std::vector<uint8_t>{tlvs, tlvs + tlvs_len}));
   1350 }
   1351 
   1352 void HidlManager::notifyApStaAuthorized(
   1353     struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
   1354 {
   1355 	if (!wpa_s || !wpa_s->parent || !sta)
   1356 		return;
   1357 	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
   1358 	    p2p_iface_object_map_.end())
   1359 		return;
   1360 	callWithEachP2pIfaceCallback(
   1361 	    wpa_s->parent->ifname, std::bind(
   1362 			       &ISupplicantP2pIfaceCallback::onStaAuthorized,
   1363 			       std::placeholders::_1, sta, p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
   1364 }
   1365 
   1366 void HidlManager::notifyApStaDeauthorized(
   1367     struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
   1368 {
   1369 	if (!wpa_s || !wpa_s->parent || !sta)
   1370 		return;
   1371 	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
   1372 	    p2p_iface_object_map_.end())
   1373 		return;
   1374 
   1375 	callWithEachP2pIfaceCallback(
   1376 	    wpa_s->parent->ifname, std::bind(
   1377 			       &ISupplicantP2pIfaceCallback::onStaDeauthorized,
   1378 			       std::placeholders::_1, sta, p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
   1379 }
   1380 
   1381 void HidlManager::notifyExtRadioWorkStart(
   1382     struct wpa_supplicant *wpa_s, uint32_t id)
   1383 {
   1384 	if (!wpa_s)
   1385 		return;
   1386 
   1387 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
   1388 	    sta_iface_object_map_.end())
   1389 		return;
   1390 
   1391 	callWithEachStaIfaceCallback(
   1392 	    wpa_s->ifname,
   1393 	    std::bind(
   1394 		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
   1395 		std::placeholders::_1, id));
   1396 }
   1397 
   1398 void HidlManager::notifyExtRadioWorkTimeout(
   1399     struct wpa_supplicant *wpa_s, uint32_t id)
   1400 {
   1401 	if (!wpa_s)
   1402 		return;
   1403 
   1404 	if (sta_iface_object_map_.find(wpa_s->ifname) ==
   1405 	    sta_iface_object_map_.end())
   1406 		return;
   1407 
   1408 	callWithEachStaIfaceCallback(
   1409 	    wpa_s->ifname,
   1410 	    std::bind(
   1411 		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
   1412 		std::placeholders::_1, id));
   1413 }
   1414 
   1415 void HidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
   1416 {
   1417 	typedef V1_1::ISupplicantStaIfaceCallback::EapErrorCode EapErrorCode;
   1418 
   1419 	if (!wpa_s)
   1420 		return;
   1421 
   1422 	switch (static_cast<EapErrorCode>(error_code)) {
   1423 		case EapErrorCode::SIM_GENERAL_FAILURE_AFTER_AUTH:
   1424 		case EapErrorCode::SIM_TEMPORARILY_DENIED:
   1425 		case EapErrorCode::SIM_NOT_SUBSCRIBED:
   1426 		case EapErrorCode::SIM_GENERAL_FAILURE_BEFORE_AUTH:
   1427 		case EapErrorCode::SIM_VENDOR_SPECIFIC_EXPIRED_CERT:
   1428 			break;
   1429 		default:
   1430 			return;
   1431 	}
   1432 
   1433 	callWithEachStaIfaceCallback_1_1(
   1434 	    wpa_s->ifname,
   1435 	    std::bind(
   1436 		&V1_1::ISupplicantStaIfaceCallback::onEapFailure_1_1,
   1437 		std::placeholders::_1,
   1438 		static_cast<EapErrorCode>(error_code)));
   1439 }
   1440 
   1441 /**
   1442  * Retrieve the |ISupplicantP2pIface| hidl object reference using the provided
   1443  * ifname.
   1444  *
   1445  * @param ifname Name of the corresponding interface.
   1446  * @param iface_object Hidl reference corresponding to the iface.
   1447  *
   1448  * @return 0 on success, 1 on failure.
   1449  */
   1450 int HidlManager::getP2pIfaceHidlObjectByIfname(
   1451     const std::string &ifname, android::sp<ISupplicantP2pIface> *iface_object)
   1452 {
   1453 	if (ifname.empty() || !iface_object)
   1454 		return 1;
   1455 
   1456 	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
   1457 	if (iface_object_iter == p2p_iface_object_map_.end())
   1458 		return 1;
   1459 
   1460 	*iface_object = iface_object_iter->second;
   1461 	return 0;
   1462 }
   1463 
   1464 /**
   1465  * Retrieve the |ISupplicantStaIface| hidl object reference using the provided
   1466  * ifname.
   1467  *
   1468  * @param ifname Name of the corresponding interface.
   1469  * @param iface_object Hidl reference corresponding to the iface.
   1470  *
   1471  * @return 0 on success, 1 on failure.
   1472  */
   1473 int HidlManager::getStaIfaceHidlObjectByIfname(
   1474     const std::string &ifname, android::sp<ISupplicantStaIface> *iface_object)
   1475 {
   1476 	if (ifname.empty() || !iface_object)
   1477 		return 1;
   1478 
   1479 	auto iface_object_iter = sta_iface_object_map_.find(ifname);
   1480 	if (iface_object_iter == sta_iface_object_map_.end())
   1481 		return 1;
   1482 
   1483 	*iface_object = iface_object_iter->second;
   1484 	return 0;
   1485 }
   1486 
   1487 /**
   1488  * Retrieve the |ISupplicantP2pNetwork| hidl object reference using the provided
   1489  * ifname and network_id.
   1490  *
   1491  * @param ifname Name of the corresponding interface.
   1492  * @param network_id ID of the corresponding network.
   1493  * @param network_object Hidl reference corresponding to the network.
   1494  *
   1495  * @return 0 on success, 1 on failure.
   1496  */
   1497 int HidlManager::getP2pNetworkHidlObjectByIfnameAndNetworkId(
   1498     const std::string &ifname, int network_id,
   1499     android::sp<ISupplicantP2pNetwork> *network_object)
   1500 {
   1501 	if (ifname.empty() || network_id < 0 || !network_object)
   1502 		return 1;
   1503 
   1504 	// Generate the key to be used to lookup the network.
   1505 	const std::string network_key =
   1506 	    getNetworkObjectMapKey(ifname, network_id);
   1507 
   1508 	auto network_object_iter = p2p_network_object_map_.find(network_key);
   1509 	if (network_object_iter == p2p_network_object_map_.end())
   1510 		return 1;
   1511 
   1512 	*network_object = network_object_iter->second;
   1513 	return 0;
   1514 }
   1515 
   1516 /**
   1517  * Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided
   1518  * ifname and network_id.
   1519  *
   1520  * @param ifname Name of the corresponding interface.
   1521  * @param network_id ID of the corresponding network.
   1522  * @param network_object Hidl reference corresponding to the network.
   1523  *
   1524  * @return 0 on success, 1 on failure.
   1525  */
   1526 int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId(
   1527     const std::string &ifname, int network_id,
   1528     android::sp<ISupplicantStaNetwork> *network_object)
   1529 {
   1530 	if (ifname.empty() || network_id < 0 || !network_object)
   1531 		return 1;
   1532 
   1533 	// Generate the key to be used to lookup the network.
   1534 	const std::string network_key =
   1535 	    getNetworkObjectMapKey(ifname, network_id);
   1536 
   1537 	auto network_object_iter = sta_network_object_map_.find(network_key);
   1538 	if (network_object_iter == sta_network_object_map_.end())
   1539 		return 1;
   1540 
   1541 	*network_object = network_object_iter->second;
   1542 	return 0;
   1543 }
   1544 
   1545 /**
   1546  * Add a new |ISupplicantCallback| hidl object reference to our
   1547  * global callback list.
   1548  *
   1549  * @param callback Hidl reference of the |ISupplicantCallback| object.
   1550  *
   1551  * @return 0 on success, 1 on failure.
   1552  */
   1553 int HidlManager::addSupplicantCallbackHidlObject(
   1554     const android::sp<ISupplicantCallback> &callback)
   1555 {
   1556 	// Register for death notification before we add it to our list.
   1557 	auto on_hidl_died_fctor = std::bind(
   1558 	    &HidlManager::removeSupplicantCallbackHidlObject, this,
   1559 	    std::placeholders::_1);
   1560 	return registerForDeathAndAddCallbackHidlObjectToList<
   1561 	    ISupplicantCallback>(
   1562 	    callback, on_hidl_died_fctor, supplicant_callbacks_);
   1563 }
   1564 
   1565 /**
   1566  * Add a new iface callback hidl object reference to our
   1567  * interface callback list.
   1568  *
   1569  * @param ifname Name of the corresponding interface.
   1570  * @param callback Hidl reference of the callback object.
   1571  *
   1572  * @return 0 on success, 1 on failure.
   1573  */
   1574 int HidlManager::addP2pIfaceCallbackHidlObject(
   1575     const std::string &ifname,
   1576     const android::sp<ISupplicantP2pIfaceCallback> &callback)
   1577 {
   1578 	const std::function<void(
   1579 	    const android::sp<ISupplicantP2pIfaceCallback> &)>
   1580 	    on_hidl_died_fctor = std::bind(
   1581 		&HidlManager::removeP2pIfaceCallbackHidlObject, this, ifname,
   1582 		std::placeholders::_1);
   1583 	return addIfaceCallbackHidlObjectToMap(
   1584 	    ifname, callback, on_hidl_died_fctor, p2p_iface_callbacks_map_);
   1585 }
   1586 
   1587 /**
   1588  * Add a new iface callback hidl object reference to our
   1589  * interface callback list.
   1590  *
   1591  * @param ifname Name of the corresponding interface.
   1592  * @param callback Hidl reference of the callback object.
   1593  *
   1594  * @return 0 on success, 1 on failure.
   1595  */
   1596 int HidlManager::addStaIfaceCallbackHidlObject(
   1597     const std::string &ifname,
   1598     const android::sp<ISupplicantStaIfaceCallback> &callback)
   1599 {
   1600 	const std::function<void(
   1601 	    const android::sp<ISupplicantStaIfaceCallback> &)>
   1602 	    on_hidl_died_fctor = std::bind(
   1603 		&HidlManager::removeStaIfaceCallbackHidlObject, this, ifname,
   1604 		std::placeholders::_1);
   1605 	return addIfaceCallbackHidlObjectToMap(
   1606 	    ifname, callback, on_hidl_died_fctor, sta_iface_callbacks_map_);
   1607 }
   1608 
   1609 /**
   1610  * Add a new network callback hidl object reference to our network callback
   1611  * list.
   1612  *
   1613  * @param ifname Name of the corresponding interface.
   1614  * @param network_id ID of the corresponding network.
   1615  * @param callback Hidl reference of the callback object.
   1616  *
   1617  * @return 0 on success, 1 on failure.
   1618  */
   1619 int HidlManager::addP2pNetworkCallbackHidlObject(
   1620     const std::string &ifname, int network_id,
   1621     const android::sp<ISupplicantP2pNetworkCallback> &callback)
   1622 {
   1623 	const std::function<void(
   1624 	    const android::sp<ISupplicantP2pNetworkCallback> &)>
   1625 	    on_hidl_died_fctor = std::bind(
   1626 		&HidlManager::removeP2pNetworkCallbackHidlObject, this, ifname,
   1627 		network_id, std::placeholders::_1);
   1628 	return addNetworkCallbackHidlObjectToMap(
   1629 	    ifname, network_id, callback, on_hidl_died_fctor,
   1630 	    p2p_network_callbacks_map_);
   1631 }
   1632 
   1633 /**
   1634  * Add a new network callback hidl object reference to our network callback
   1635  * list.
   1636  *
   1637  * @param ifname Name of the corresponding interface.
   1638  * @param network_id ID of the corresponding network.
   1639  * @param callback Hidl reference of the callback object.
   1640  *
   1641  * @return 0 on success, 1 on failure.
   1642  */
   1643 int HidlManager::addStaNetworkCallbackHidlObject(
   1644     const std::string &ifname, int network_id,
   1645     const android::sp<ISupplicantStaNetworkCallback> &callback)
   1646 {
   1647 	const std::function<void(
   1648 	    const android::sp<ISupplicantStaNetworkCallback> &)>
   1649 	    on_hidl_died_fctor = std::bind(
   1650 		&HidlManager::removeStaNetworkCallbackHidlObject, this, ifname,
   1651 		network_id, std::placeholders::_1);
   1652 	return addNetworkCallbackHidlObjectToMap(
   1653 	    ifname, network_id, callback, on_hidl_died_fctor,
   1654 	    sta_network_callbacks_map_);
   1655 }
   1656 
   1657 /**
   1658  * Removes the provided |ISupplicantCallback| hidl object reference
   1659  * from our global callback list.
   1660  *
   1661  * @param callback Hidl reference of the |ISupplicantCallback| object.
   1662  */
   1663 void HidlManager::removeSupplicantCallbackHidlObject(
   1664     const android::sp<ISupplicantCallback> &callback)
   1665 {
   1666 	supplicant_callbacks_.erase(
   1667 	    std::remove(
   1668 		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
   1669 		callback),
   1670 	    supplicant_callbacks_.end());
   1671 }
   1672 
   1673 /**
   1674  * Removes the provided iface callback hidl object reference from
   1675  * our interface callback list.
   1676  *
   1677  * @param ifname Name of the corresponding interface.
   1678  * @param callback Hidl reference of the callback object.
   1679  */
   1680 void HidlManager::removeP2pIfaceCallbackHidlObject(
   1681     const std::string &ifname,
   1682     const android::sp<ISupplicantP2pIfaceCallback> &callback)
   1683 {
   1684 	return removeIfaceCallbackHidlObjectFromMap(
   1685 	    ifname, callback, p2p_iface_callbacks_map_);
   1686 }
   1687 
   1688 /**
   1689  * Removes the provided iface callback hidl object reference from
   1690  * our interface callback list.
   1691  *
   1692  * @param ifname Name of the corresponding interface.
   1693  * @param callback Hidl reference of the callback object.
   1694  */
   1695 void HidlManager::removeStaIfaceCallbackHidlObject(
   1696     const std::string &ifname,
   1697     const android::sp<ISupplicantStaIfaceCallback> &callback)
   1698 {
   1699 	return removeIfaceCallbackHidlObjectFromMap(
   1700 	    ifname, callback, sta_iface_callbacks_map_);
   1701 }
   1702 
   1703 /**
   1704  * Removes the provided network callback hidl object reference from
   1705  * our network callback list.
   1706  *
   1707  * @param ifname Name of the corresponding interface.
   1708  * @param network_id ID of the corresponding network.
   1709  * @param callback Hidl reference of the callback object.
   1710  */
   1711 void HidlManager::removeP2pNetworkCallbackHidlObject(
   1712     const std::string &ifname, int network_id,
   1713     const android::sp<ISupplicantP2pNetworkCallback> &callback)
   1714 {
   1715 	return removeNetworkCallbackHidlObjectFromMap(
   1716 	    ifname, network_id, callback, p2p_network_callbacks_map_);
   1717 }
   1718 
   1719 /**
   1720  * Removes the provided network callback hidl object reference from
   1721  * our network callback list.
   1722  *
   1723  * @param ifname Name of the corresponding interface.
   1724  * @param network_id ID of the corresponding network.
   1725  * @param callback Hidl reference of the callback object.
   1726  */
   1727 void HidlManager::removeStaNetworkCallbackHidlObject(
   1728     const std::string &ifname, int network_id,
   1729     const android::sp<ISupplicantStaNetworkCallback> &callback)
   1730 {
   1731 	return removeNetworkCallbackHidlObjectFromMap(
   1732 	    ifname, network_id, callback, sta_network_callbacks_map_);
   1733 }
   1734 
   1735 /**
   1736  * Helper function to invoke the provided callback method on all the
   1737  * registered |ISupplicantCallback| callback hidl objects.
   1738  *
   1739  * @param method Pointer to the required hidl method from
   1740  * |ISupplicantCallback|.
   1741  */
   1742 void HidlManager::callWithEachSupplicantCallback(
   1743     const std::function<Return<void>(android::sp<ISupplicantCallback>)> &method)
   1744 {
   1745 	for (const auto &callback : supplicant_callbacks_) {
   1746 		if (!method(callback).isOk()) {
   1747 			wpa_printf(MSG_ERROR, "Failed to invoke HIDL callback");
   1748 		}
   1749 	}
   1750 }
   1751 
   1752 /**
   1753  * Helper fucntion to invoke the provided callback method on all the
   1754  * registered iface callback hidl objects for the specified
   1755  * |ifname|.
   1756  *
   1757  * @param ifname Name of the corresponding interface.
   1758  * @param method Pointer to the required hidl method from
   1759  * |ISupplicantIfaceCallback|.
   1760  */
   1761 void HidlManager::callWithEachP2pIfaceCallback(
   1762     const std::string &ifname,
   1763     const std::function<Return<void>(android::sp<ISupplicantP2pIfaceCallback>)>
   1764 	&method)
   1765 {
   1766 	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
   1767 }
   1768 
   1769 /**
   1770  * Helper fucntion to invoke the provided callback method on all the
   1771  * registered V1.1 iface callback hidl objects for the specified
   1772  * |ifname|.
   1773  *
   1774  * @param ifname Name of the corresponding interface.
   1775  * @param method Pointer to the required hidl method from
   1776  * |V1_1::ISupplicantIfaceCallback|.
   1777  */
   1778 void HidlManager::callWithEachStaIfaceCallback_1_1(
   1779     const std::string &ifname,
   1780     const std::function<Return<void>
   1781 	(android::sp<V1_1::ISupplicantStaIfaceCallback>)> &method)
   1782 {
   1783 	callWithEachIfaceCallback_1_1(ifname, method, sta_iface_callbacks_map_);
   1784 }
   1785 
   1786 /**
   1787  * Helper fucntion to invoke the provided callback method on all the
   1788  * registered iface callback hidl objects for the specified
   1789  * |ifname|.
   1790  *
   1791  * @param ifname Name of the corresponding interface.
   1792  * @param method Pointer to the required hidl method from
   1793  * |ISupplicantIfaceCallback|.
   1794  */
   1795 void HidlManager::callWithEachStaIfaceCallback(
   1796     const std::string &ifname,
   1797     const std::function<Return<void>(android::sp<ISupplicantStaIfaceCallback>)>
   1798 	&method)
   1799 {
   1800 	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
   1801 }
   1802 
   1803 /**
   1804  * Helper function to invoke the provided callback method on all the
   1805  * registered network callback hidl objects for the specified
   1806  * |ifname| & |network_id|.
   1807  *
   1808  * @param ifname Name of the corresponding interface.
   1809  * @param network_id ID of the corresponding network.
   1810  * @param method Pointer to the required hidl method from
   1811  * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
   1812  */
   1813 void HidlManager::callWithEachP2pNetworkCallback(
   1814     const std::string &ifname, int network_id,
   1815     const std::function<
   1816 	Return<void>(android::sp<ISupplicantP2pNetworkCallback>)> &method)
   1817 {
   1818 	callWithEachNetworkCallback(
   1819 	    ifname, network_id, method, p2p_network_callbacks_map_);
   1820 }
   1821 
   1822 /**
   1823  * Helper function to invoke the provided callback method on all the
   1824  * registered network callback hidl objects for the specified
   1825  * |ifname| & |network_id|.
   1826  *
   1827  * @param ifname Name of the corresponding interface.
   1828  * @param network_id ID of the corresponding network.
   1829  * @param method Pointer to the required hidl method from
   1830  * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
   1831  */
   1832 void HidlManager::callWithEachStaNetworkCallback(
   1833     const std::string &ifname, int network_id,
   1834     const std::function<
   1835 	Return<void>(android::sp<ISupplicantStaNetworkCallback>)> &method)
   1836 {
   1837 	callWithEachNetworkCallback(
   1838 	    ifname, network_id, method, sta_network_callbacks_map_);
   1839 }
   1840 }  // namespace implementation
   1841 }  // namespace V1_1
   1842 }  // namespace wifi
   1843 }  // namespace supplicant
   1844 }  // namespace hardware
   1845 }  // namespace android
   1846