(八十八)Android O WiFi启动流程梳理续——connectToSupplicant
发布日期:2021-06-30 15:25:16 浏览次数:2 分类:技术文章

本文共 19162 字,大约阅读时间需要 63 分钟。

前言:之前在如下几篇中梳理了Android wifi的启动流程,但是没有梳理完全,在发现少了一步connectToSupplicant,在加载驱动和将supplicant启动起来后,上层还要连接上supplicant,这样才算WiFi启动流程梳理了差不多。

  1.  

 

1.流程梳理

之前在 中梳理到了WiFiMonitor在supplicant启动以后会进行轮询,等待wpa_supplicant控制接口准备好后发送supplicant 连接完成的消息给WiFiStateMachine让状态机切换到SupplicantStartedState。

/**     * Wait for wpa_supplicant's control interface to be ready.     *     * TODO: Add unit tests for these once we remove the legacy code.     */    private boolean ensureConnectedLocked() {        if (mConnected) {            return true;        }        if (mVerboseLoggingEnabled) Log.d(TAG, "connecting to supplicant");        int connectTries = 0;        while (true) {            mConnected = mWifiInjector.getWifiNative().connectToSupplicant();            if (mConnected) {                return true;            }            if (connectTries++ < 50) {                try {                    Thread.sleep(100);                } catch (InterruptedException ignore) {                }            } else {                return false;            }        }    }

这边接着继续往下梳理

WifiNative

/**     * This method is called repeatedly until the connection to wpa_supplicant is established.     *     * @return true if connection is established, false otherwise.     * TODO: Add unit tests for these once we remove the legacy code.     */    public boolean connectToSupplicant() {        // Start initialization if not already started.        if (!mSupplicantStaIfaceHal.isInitializationStarted()                && !mSupplicantStaIfaceHal.initialize()) {            return false;        }        // Check if the initialization is complete.        return mSupplicantStaIfaceHal.isInitializationComplete();    }

另外WifiNative是在WifiInjector中初始化的。

mHalDeviceManager = new HalDeviceManager();        mWifiVendorHal =                new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread.getLooper());        mSupplicantStaIfaceHal = new SupplicantStaIfaceHal(mContext, mWifiMonitor);        mWificondControl = new WificondControl(this, mWifiMonitor,                new CarrierNetworkConfig(mContext));        mWifiNative = new WifiNative(SystemProperties.get("wifi.interface", "wlan0"),                mWifiVendorHal, mSupplicantStaIfaceHal, mWificondControl);    public WifiNative(String interfaceName, WifiVendorHal vendorHal,                      SupplicantStaIfaceHal staIfaceHal, WificondControl condControl) {        mTAG = "WifiNative-" + interfaceName;        mInterfaceName = interfaceName;        mWifiVendorHal = vendorHal;        mSupplicantStaIfaceHal = staIfaceHal;        mWificondControl = condControl;    }

看下connectToSupplicant中调用的3个方法

/**     * Signals whether Initialization completed successfully.     */    public boolean isInitializationStarted() {        synchronized (mLock) {            return mIServiceManager != null;        }    }
/**     * Registers a service notification for the ISupplicant service, which triggers intialization of     * the ISupplicantStaIface     * @return true if the service notification was successfully registered     */    public boolean initialize() {        synchronized (mLock) {            if (mVerboseLoggingEnabled) {                Log.i(TAG, "Registering ISupplicant service ready callback.");            }            mISupplicant = null;            mISupplicantStaIface = null;            if (mIServiceManager != null) {                // Already have an IServiceManager and serviceNotification registered, don't                // don't register another.                return true;            }            try {                mIServiceManager = getServiceManagerMockable();                if (mIServiceManager == null) {                    Log.e(TAG, "Failed to get HIDL Service Manager");                    return false;                }                if (!linkToServiceManagerDeath()) {                    return false;                }                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it                   exists */                if (!mIServiceManager.registerForNotifications(                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {                    Log.e(TAG, "Failed to register for notifications to "                            + ISupplicant.kInterfaceName);                    mIServiceManager = null; // Will need to register a new ServiceNotification                    return false;                }            } catch (RemoteException e) {                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "                        + e);                supplicantServiceDiedHandler();            }            return true;        }    }
/**     * Wrapper functions to access static HAL methods, created to be mockable in unit tests     */    protected IServiceManager getServiceManagerMockable() throws RemoteException {        synchronized (mLock) {            return IServiceManager.getService();        }    }

这边的IServiceManager是hal的ServiceManager:import android.hidl.manager.V1_0.IServiceManager;

除此之外与hal相关的调用还有

import android.hardware.wifi.supplicant.V1_0.ISupplicant;import android.hardware.wifi.supplicant.V1_0.ISupplicantIface;import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason;import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;import android.hardware.wifi.supplicant.V1_0.IfaceType;import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;import android.hidl.manager.V1_0.IServiceManager;import android.hidl.manager.V1_0.IServiceNotification;

之后看会调用到registerForNotifications

aosp/system/hwservicemanager$ vim +374 ./ServiceManager.cpp

jiatai@jiatai:~/expand/aosp/aosp/system/libhidl/transport/manager/1.0$ ls

Android.bp  IServiceManager.hal  IServiceNotification.hal

Return
ServiceManager::registerForNotifications(const hidl_string& fqName, const hidl_string& name, const sp
& callback) { if (callback == nullptr) { return false; } pid_t pid = IPCThreadState::self()->getCallingPid(); if (!mAcl.canGet(fqName, pid)) { return false; } PackageInterfaceMap &ifaceMap = mServiceMap[fqName]; if (name.empty()) { auto ret = callback->linkToDeath(this, kPackageListenerDiedCookie); if (!ret.isOk()) { LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name; return false; } ifaceMap.addPackageListener(callback); return true; } HidlService *service = ifaceMap.lookup(name); auto ret = callback->linkToDeath(this, kServiceListenerDiedCookie); if (!ret.isOk()) { LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name; return false; } if (service == nullptr) { auto adding = std::make_unique
(fqName, name); adding->addListener(callback); ifaceMap.insertService(std::move(adding)); } else { service->addListener(callback); } return true;}

由于name传递进来的时候是空的,所以直接调用ifaceMap.addPackageListener(callback)

void ServiceManager::PackageInterfaceMap::addPackageListener(sp
listener) { for (const auto &instanceMapping : mInstanceMap) { const std::unique_ptr
&service = instanceMapping.second; if (service->getService() == nullptr) { continue; } auto ret = listener->onRegistration( service->getInterfaceName(), service->getInstanceName(), true /* preexisting */); if (!ret.isOk()) { LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName() << "/" << service->getInstanceName() << ": transport error " << "when sending notification for already registered instance."; return; } } mPackageListeners.push_back(listener);}

可以观察到registerForNotifications的时候传递了一个callback给hal层,mServiceNotificationCallback,这个callback这时候会被回调onRegistration。

private final IServiceNotification mServiceNotificationCallback =            new IServiceNotification.Stub() {        public void onRegistration(String fqName, String name, boolean preexisting) {            synchronized (mLock) {                if (mVerboseLoggingEnabled) {                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName                            + ", " + name + " preexisting=" + preexisting);                }                if (!initSupplicantService() || !initSupplicantStaIface()) {                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");                    supplicantServiceDiedHandler();                } else {                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");                }            }        }    };

看下对应的log打印:

09-01 23:28:04.946  1561  2457 D WifiStateMachine: Supplicant start successful09-01 23:28:04.946  1561  2457 D WifiMonitor: connecting to supplicant09-01 23:28:05.055  1561 18600 I SupplicantStaIfaceHal: IServiceNotification.onRegistration for: android.hardware.wifi.supplicant@1.0::ISupplicant, default preexisting=false09-01 23:28:05.101  1561 18600 D SupplicantStaIfaceHal: ISupplicantStaIface.registerCallback succeeded09-01 23:28:05.101  1561 18600 I SupplicantStaIfaceHal: Completed initialization of ISupplicant interfaces.09-01 23:28:05.149  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.setDebugParams succeeded09-01 23:28:05.153  1561  2457 D WifiStateMachine: Supplicant connection established

这里可以得到

  • fqName:android.hardware.wifi.supplicant@1.0::ISupplicant
  • name:default
  • preexisting:false

ISupplicant的hal文件和对应的服务端实现如下

jiatai@jiatai:~/expand/aosp/aosp/hardware/interfaces/wifi$ find -iname ISupplicant.hal./supplicant/1.0/ISupplicant.haljiatai@jiatai:~/expand/aosp/aosp/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0$ lshidl_constants.h  hidl.h    hidl_manager.cpp  hidl_return_util.h      iface_config_utils.h  p2p_iface.cpp  p2p_network.cpp  sta_iface.cpp  sta_network.cpp  supplicant.cpphidl.cpp          hidl_i.h  hidl_manager.h    iface_config_utils.cpp  misc_utils.h          p2p_iface.h    p2p_network.h    sta_iface.h    sta_network.h    supplicant.h

之后会调用如下两个方法:

  • initSupplicantService() 
  • initSupplicantStaIface()
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;    }

获取ISupplicant服务端对应的引用。

private boolean initSupplicantStaIface() {        synchronized (mLock) {            /** List all supplicant Ifaces */            final ArrayList
supplicantIfaces = new ArrayList<>(); try { mISupplicant.listInterfaces((SupplicantStatus status, ArrayList
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
supplicantIface = new Mutable<>(); Mutable
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; } }

Supplicant.cpp

Return
Supplicant::listInterfaces(listInterfaces_cb _hidl_cb){ return validateAndCall( this, SupplicantStatusCode::FAILURE_IFACE_INVALID, &Supplicant::listInterfacesInternal, _hidl_cb);}std::pair
>Supplicant::listInterfacesInternal(){ std::vector
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)};}Return
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
>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
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
iface; if (!hidl_manager || hidl_manager->getStaIfaceHidlObjectByIfname( wpa_s->ifname, &iface)) { return { {SupplicantStatusCode::FAILURE_UNKNOWN, ""}, iface}; } return { {SupplicantStatusCode::SUCCESS, ""}, iface}; }}

之后调用

protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {        synchronized (mLock) {            return ISupplicantStaIface.asInterface(iface.asBinder());        }    }
/** See ISupplicantStaNetwork.hal for documentation */    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {        synchronized (mLock) {            final String methodStr = "registerCallback";            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;            try {                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);                return checkStatusAndLogFailure(status, methodStr);            } catch (RemoteException e) {                handleRemoteException(e, methodStr);                return false;            }        }    }    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {        mContext = context;        mWifiMonitor = monitor;        mISupplicantStaIfaceCallback = new SupplicantStaIfaceHalCallback();    }
jiatai@jiatai:~/expand/aosp/aosp/hardware/interfaces$ find -iname ISupplicantStaIface.hal ./wifi/supplicant/1.0/ISupplicantStaIface.haljiatai@jiatai:~/expand/aosp/aosp/external/wpa_supplicant_8/wpa_supplicant/hidl$ grep "initiateTdlsSetup" ./ -nr./1.0/sta_iface.cpp:262:Return
StaIface::initiateTdlsSetup(

ISupplicantStaIface应该是对应sta_iface.cpp的引用

Return
StaIface::registerCallback( const sp
&callback, registerCallback_cb _hidl_cb){ return validateAndCall( this, SupplicantStatusCode::FAILURE_IFACE_INVALID, &StaIface::registerCallbackInternal, _hidl_cb, callback);}SupplicantStatus StaIface::registerCallbackInternal( const sp
&callback){ HidlManager *hidl_manager = HidlManager::getInstance(); if (!hidl_manager || hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) { return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; } return {SupplicantStatusCode::SUCCESS, ""};}

hidl_manager.cpp

/** * Add a new iface callback hidl object reference to our * interface callback list. * * @param ifname Name of the corresponding interface. * @param callback Hidl reference of the callback object. * * @return 0 on success, 1 on failure. */int HidlManager::addStaIfaceCallbackHidlObject(    const std::string &ifname,    const android::sp
&callback){ const std::function
&)> on_hidl_died_fctor = std::bind( &HidlManager::removeStaIfaceCallbackHidlObject, this, ifname, std::placeholders::_1); return addIfaceCallbackHidlObjectToMap( ifname, callback, on_hidl_died_fctor, sta_iface_callbacks_map_);}

最后通过判断如下方法返回值来得出初始化是否完成。

/**     * Signals whether Initialization completed successfully.     */    public boolean isInitializationComplete() {        synchronized (mLock) {            return mISupplicantStaIface != null;        }    }

而mISupplicantStaIface是在刚提及的initSupplicantStaIface初始化的。

 

2. 总结

流程应该梳理的没问题,但由于通过hidl调用到cpp的代码没怎么看懂,大体可以类比于aidl 中客户端获取了服务端的引用,开始与服务端进行交互,这边相当于可以通过sta_iface.cpp与wpa_supplicant进行交互,待续。。。

connectToSupplicant时序图
ConnectToSupplicant by jiatai

 

转载地址:https://jiatai.blog.csdn.net/article/details/82291044 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:(八十九) Android O 探索WiFi直连默认名称由来
下一篇:(八十七) WiFi & DHCP

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月13日 14时39分09秒