(八十八)Android O WiFi启动流程梳理续——connectToSupplicant

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

  1. (四十四)Android O WiFi启动流程梳理 
  2. (五十八)Android O WiFi启动流程梳理续——setupForClientMode
  3. (五十九)Android O WiFi启动流程梳理续——enableSupplicant
  4. (八十六)探讨WiFi开关变化的原因

 

1.流程梳理

之前在(八十六)探讨WiFi开关变化的原因 中梳理到了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 successful
09-01 23:28:04.946  1561  2457 D WifiMonitor: connecting to supplicant
09-01 23:28:05.055  1561 18600 I SupplicantStaIfaceHal: IServiceNotification.onRegistration for: [email protected]::ISupplicant, default preexisting=false
09-01 23:28:05.101  1561 18600 D SupplicantStaIfaceHal: ISupplicantStaIface.registerCallback succeeded
09-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 succeeded
09-01 23:28:05.153  1561  2457 D WifiStateMachine: Supplicant connection established

这里可以得到

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

jiatai@jiatai:~/expand/aosp/aosp/hardware/interfaces/wifi$ find -iname ISupplicant.hal
./supplicant/1.0/ISupplicant.hal


jiatai@jiatai:~/expand/aosp/aosp/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0$ ls
hidl_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.cpp
hidl.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.hal


jiatai@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进行交互,待续。。。

(八十八)Android O WiFi启动流程梳理续——connectToSupplicant_第1张图片 ConnectToSupplicant by jiatai

 

你可能感兴趣的:(Wifi)