前言:之前在如下几篇中梳理了Android wifi的启动流程,但是没有梳理完全,在(八十六)探讨WiFi开关变化的原因发现少了一步connectToSupplicant,在加载驱动和将supplicant启动起来后,上层还要连接上supplicant,这样才算WiFi启动流程梳理了差不多。
之前在(八十六)探讨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
之后会调用如下两个方法:
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初始化的。
流程应该梳理的没问题,但由于通过hidl调用到cpp的代码没怎么看懂,大体可以类比于aidl 中客户端获取了服务端的引用,开始与服务端进行交互,这边相当于可以通过sta_iface.cpp与wpa_supplicant进行交互,待续。。。