版权声明:本文为博主原创文章,未经授权禁止转载,O(∩_∩)O谢谢 https://blog.csdn.net/sinat_20059415/article/details/84890034
前言:之前Android O wpa_supplicant初始化学习(三)—— hidl 中梳理了发现的一个hidl Service的注册,SupplicantStaIfaceHal涉及了不止一个。
1.SupplicantStaIfaceHal
SupplicantStaIfaceHal中涉及的hidl
1.1 SupplicantService
private boolean initSupplicantService() {
synchronized (mLock) {
try {
mISupplicant = getSupplicantMockable();
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.getService exception: " + e);
return false;
}
if (mISupplicant == null) {
Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
return false;
}
if (!linkToSupplicantDeath()) {
return false;
}
}
return true;
}
这里server应该是对应的Android O wpa_supplicant初始化学习(三)—— hidl 梳理的supplicant.cpp
1.2 SupplicantStaIface
private boolean initSupplicantStaIface() {
synchronized (mLock) {
/** List all supplicant Ifaces */
final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
try {
mISupplicant.listInterfaces((SupplicantStatus status,
ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
if (status.code != SupplicantStatusCode.SUCCESS) {
Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
return;
}
supplicantIfaces.addAll(ifaces);
});
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
return false;
}
if (supplicantIfaces.size() == 0) {
Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
return false;
}
Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
Mutable<String> ifaceName = new Mutable<>();
for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
if (ifaceInfo.type == IfaceType.STA) {
try {
mISupplicant.getInterface(ifaceInfo,
(SupplicantStatus status, ISupplicantIface iface) -> {
if (status.code != SupplicantStatusCode.SUCCESS) {
Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
return;
}
supplicantIface.value = iface;
});
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.getInterface exception: " + e);
return false;
}
ifaceName.value = ifaceInfo.name;
break;
}
}
if (supplicantIface.value == null) {
Log.e(TAG, "initSupplicantStaIface got null iface");
return false;
}
mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
mIfaceName = ifaceName.value;
if (!linkToSupplicantStaIfaceDeath()) {
return false;
}
if (!registerCallback(mISupplicantStaIfaceCallback)) {
return false;
}
return true;
}
}
protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
synchronized (mLock) {
return ISupplicantStaIface.asInterface(iface.asBinder());
}
}
本文梳理下SupplicantStaIface
2. hidl 添加流程梳理
2.1 wpa_supplicant.c
/**
* wpa_supplicant_add_iface - Add a new network interface
* @global: Pointer to global data from wpa_supplicant_init()
* @iface: Interface configuration options
* @parent: Parent interface or %NULL to assign new interface as parent
* Returns: Pointer to the created interface or %NULL on failure
*
* This function is used to add new network interfaces for %wpa_supplicant.
* This can be called before wpa_supplicant_run() to add interfaces before the
* main event loop has been started. In addition, new interfaces can be added
* dynamically while %wpa_supplicant is already running. This could happen,
* e.g., when a hotplug network adapter is inserted.
*/
struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
struct wpa_interface *iface,
struct wpa_supplicant *parent)
{
struct wpa_supplicant *wpa_s;
struct wpa_interface t_iface;
struct wpa_ssid *ssid;
if (global == NULL || iface == NULL)
return NULL;
wpa_s = wpa_supplicant_alloc(parent);
if (wpa_s == NULL)
return NULL;
wpa_s->global = global;
t_iface = *iface;
if (global->params.override_driver) {
wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
"('%s' -> '%s')",
iface->driver, global->params.override_driver);
t_iface.driver = global->params.override_driver;
}
if (global->params.override_ctrl_interface) {
wpa_printf(MSG_DEBUG, "Override interface parameter: "
"ctrl_interface ('%s' -> '%s')",
iface->ctrl_interface,
global->params.override_ctrl_interface);
t_iface.ctrl_interface =
global->params.override_ctrl_interface;
}
if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
wpa_printf(MSG_DEBUG, "Failed to add interface %s",
iface->ifname);
wpa_supplicant_deinit_iface(wpa_s, 0, 0);
return NULL;
}
/* Notify the control interfaces about new iface */
if (wpas_notify_iface_added(wpa_s)) {
wpa_supplicant_deinit_iface(wpa_s, 1, 0);
return NULL;
}
/* Notify the control interfaces about new networks for non p2p mgmt
* ifaces. */
if (iface->p2p_mgmt == 0) {
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
wpas_notify_network_added(wpa_s, ssid);
}
wpa_s->next = global->ifaces;
global->ifaces = wpa_s;
wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
#ifdef CONFIG_P2P
if (wpa_s->global->p2p == NULL &&
!wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
wpas_p2p_add_p2pdev_interface(
wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
wpa_printf(MSG_INFO,
"P2P: Failed to enable P2P Device interface");
/* Try to continue without. P2P will be disabled. */
}
#endif /* CONFIG_P2P */
return wpa_s;
}
其中关注
/* Notify the control interfaces about new iface */
if (wpas_notify_iface_added(wpa_s)) {
wpa_supplicant_deinit_iface(wpa_s, 1, 0);
return NULL;
}
2.2 notify.c
int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
{
if (!wpa_s->p2p_mgmt) {
if (wpas_dbus_register_iface(wpa_s))
return -1;
if (wpas_dbus_register_interface(wpa_s))
return -1;
}
/* HIDL interface wants to keep track of the P2P mgmt iface. */
if (wpas_hidl_register_interface(wpa_s))
return -1;
return 0;
}
2.3 hidl.cpp
int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
{
if (!wpa_s || !wpa_s->global->hidl)
return 1;
wpa_printf(
MSG_DEBUG, "Registering interface to hidl control: %s",
wpa_s->ifname);
HidlManager *hidl_manager = HidlManager::getInstance();
if (!hidl_manager)
return 1;
return hidl_manager->registerInterface(wpa_s);
}
2.4 hidl_manager.cpp
/**
* Register an interface to hidl manager.
*
* @param wpa_s |wpa_supplicant| struct corresponding to the interface.
*
* @return 0 on success, 1 on failure.
*/
int HidlManager::registerInterface(struct wpa_supplicant *wpa_s)
{
if (!wpa_s)
return 1;
if (isP2pIface(wpa_s)) {
if (addHidlObjectToMap<P2pIface>(
wpa_s->ifname,
new P2pIface(wpa_s->global, wpa_s->ifname),
p2p_iface_object_map_)) {
wpa_printf(
MSG_ERROR,
"Failed to register P2P interface with HIDL "
"control: %s",
wpa_s->ifname);
return 1;
}
p2p_iface_callbacks_map_[wpa_s->ifname] =
std::vector<android::sp<ISupplicantP2pIfaceCallback>>();
} else {
if (addHidlObjectToMap<StaIface>(
wpa_s->ifname,
new StaIface(wpa_s->global, wpa_s->ifname),
sta_iface_object_map_)) {
wpa_printf(
MSG_ERROR,
"Failed to register STA interface with HIDL "
"control: %s",
wpa_s->ifname);
return 1;
}
sta_iface_callbacks_map_[wpa_s->ifname] =
std::vector<android::sp<ISupplicantStaIfaceCallback>>();
}
// Invoke the |onInterfaceCreated| method on all registered callbacks.
callWithEachSupplicantCallback(std::bind(
&ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
wpa_s->ifname));
return 0;
}
template <class ObjectType>
int addHidlObjectToMap(
const std::string &key, const android::sp<ObjectType> object,
std::map<const std::string, android::sp<ObjectType>> &object_map)
{
// Return failure if we already have an object for that |key|.
if (object_map.find(key) != object_map.end())
return 1;
object_map[key] = object;
if (!object_map[key].get())
return 1;
return 0;
}
3. hidl 获取流程梳理
hidl添加好了看上层是如何获取的
3.1 SupplicantStaIfaceHal.java
private boolean initSupplicantStaIface() {
synchronized (mLock) {
/** List all supplicant Ifaces */
final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
try {
mISupplicant.listInterfaces((SupplicantStatus status,
ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
if (status.code != SupplicantStatusCode.SUCCESS) {
Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
return;
}
supplicantIfaces.addAll(ifaces);
});
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
return false;
}
if (supplicantIfaces.size() == 0) {
Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
return false;
}
Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
Mutable<String> ifaceName = new Mutable<>();
for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
if (ifaceInfo.type == IfaceType.STA) {
try {
mISupplicant.getInterface(ifaceInfo,
(SupplicantStatus status, ISupplicantIface iface) -> {
if (status.code != SupplicantStatusCode.SUCCESS) {
Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
return;
}
supplicantIface.value = iface;
});
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.getInterface exception: " + e);
return false;
}
ifaceName.value = ifaceInfo.name;
break;
}
}
if (supplicantIface.value == null) {
Log.e(TAG, "initSupplicantStaIface got null iface");
return false;
}
mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
mIfaceName = ifaceName.value;
if (!linkToSupplicantStaIfaceDeath()) {
return false;
}
if (!registerCallback(mISupplicantStaIfaceCallback)) {
return false;
}
return true;
}
}
protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
synchronized (mLock) {
return ISupplicantStaIface.asInterface(iface.asBinder());
}
}
涉及了list和get
3.2 supplicant.cpp
3.2.1 listInterfaces
Return<void> Supplicant::listInterfaces(listInterfaces_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&Supplicant::listInterfacesInternal, _hidl_cb);
}
std::pair<SupplicantStatus, std::vector<ISupplicant::IfaceInfo>>
Supplicant::listInterfacesInternal()
{
std::vector<ISupplicant::IfaceInfo> ifaces;
for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
wpa_s = wpa_s->next) {
if (wpa_s->global->p2p_init_wpa_s == wpa_s) {
ifaces.emplace_back(ISupplicant::IfaceInfo{
IfaceType::P2P, wpa_s->ifname});
} else {
ifaces.emplace_back(ISupplicant::IfaceInfo{
IfaceType::STA, wpa_s->ifname});
}
}
return {{SupplicantStatusCode::SUCCESS, ""}, std::move(ifaces)};
}
3.2.2 getInterface
Return<void> Supplicant::getInterface(
const IfaceInfo& iface_info, getInterface_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&Supplicant::getInterfaceInternal, _hidl_cb, iface_info);
}
std::pair<SupplicantStatus, sp<ISupplicantIface>>
Supplicant::getInterfaceInternal(const IfaceInfo& iface_info)
{
struct wpa_supplicant* wpa_s =
wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
if (!wpa_s) {
return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""},
nullptr};
}
HidlManager* hidl_manager = HidlManager::getInstance();
if (iface_info.type == IfaceType::P2P) {
android::sp<ISupplicantP2pIface> iface;
if (!hidl_manager ||
hidl_manager->getP2pIfaceHidlObjectByIfname(
wpa_s->ifname, &iface)) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
iface};
}
// Set this flag true here, since there is no HIDL initialize method for the p2p
// config, and the supplicant interface is not ready when the p2p iface is created.
wpa_s->conf->persistent_reconnect = true;
return {{SupplicantStatusCode::SUCCESS, ""}, iface};
} else {
android::sp<ISupplicantStaIface> iface;
if (!hidl_manager ||
hidl_manager->getStaIfaceHidlObjectByIfname(
wpa_s->ifname, &iface)) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
iface};
}
return {{SupplicantStatusCode::SUCCESS, ""}, iface};
}
}
3.3 hidl_manager.cpp
/**
* Retrieve the |ISupplicantStaIface| hidl object reference using the provided
* ifname.
*
* @param ifname Name of the corresponding interface.
* @param iface_object Hidl reference corresponding to the iface.
*
* @return 0 on success, 1 on failure.
*/
int HidlManager::getStaIfaceHidlObjectByIfname(
const std::string &ifname, android::sp<ISupplicantStaIface> *iface_object)
{
if (ifname.empty() || !iface_object)
return 1;
auto iface_object_iter = sta_iface_object_map_.find(ifname);
if (iface_object_iter == sta_iface_object_map_.end())
return 1;
*iface_object = iface_object_iter->second;
return 0;
}