一 前言
在上一篇分析了wifi启动的流程,从Android应用层一直分析到了Java框架层,这次我们接着往下走流程。如果没有看上一篇的建议先回头看看 Wifi模块—源码分析Wifi启动1(Android P)这样能更好地认知和把握wifi的启动过程。
二 图示调用流程
这个调用流程图也是基于上一篇的流程图进一步完善的得到的。
三 代码具体流程
1 应用层
直接看 Wifi模块—源码分析Wifi启动1(Android P)。
2 java 框架层
前面部分直接看 Wifi模块—源码分析Wifi启动1(Android P),这一层也不标注明确的节点数值,因为这一层的前面调用流程部分并未全部加到这里。所以直接去看前面一篇会更清晰。
我们直接从WifiNative.java这个类开始看。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
* Setup an interface for Client mode operations. * * This method configures an interface in STA mode in all the native daemons * (wificond, wpa_supplicant & vendor HAL). * @param lowPrioritySta The requested STA has a low request priority (lower probability of * getting created, higher probability of getting destroyed). * @param interfaceCallback Associated callback for notifying status changes for the iface. * @return Returns the name of the allocated interface, will be null on failure. public String setupInterfaceForClientMode(boolean lowPrioritySta, @NonNull InterfaceCallback interfaceCallback) { Log.e(TAG, "Failed to start Hal"); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal(); if (!startSupplicant()) { Log.e(TAG, "Failed to start supplicant"); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant(); Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA); Log.e(TAG, "Failed to allocate new STA iface"); iface.externalListener = interfaceCallback; iface.name = createStaIface(iface, lowPrioritySta); if (TextUtils.isEmpty(iface.name)) { Log.e(TAG, "Failed to create STA iface in vendor HAL"); mIfaceMgr.removeIface(iface.id); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal(); if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) { Log.e(TAG, "Failed to setup iface in wificond on " + iface); teardownInterface(iface.name); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond(); if (!mSupplicantStaIfaceHal.setupIface(iface.name)) { Log.e(TAG, "Failed to setup iface in supplicant on " + iface); teardownInterface(iface.name); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant(); iface.networkObserver = new NetworkObserverInternal(iface.id); if (!registerNetworkObserver(iface.networkObserver)) { Log.e(TAG, "Failed to register network observer on " + iface); teardownInterface(iface.name); mWifiMonitor.startMonitoring(iface.name); // Just to avoid any race conditions with interface state change callbacks, // update the interface state before we exit. onInterfaceStateChanged(iface, isInterfaceUp(iface.name)); initializeNwParamsForClientInterface(iface.name); Log.i(TAG, "Successfully setup " + iface);
看一些关键性的操作:
启动Hal:startHal()
启动supplicant:startSupplicant()
加载驱动(loadDriver):setupInterfaceForClientMode()
启动WifiMonitor:WifiMonitor.startMonitoring()
这里我们就选择 启动Hal:startHal() 这条线走下去。
/** Helper method invoked to start supplicant if there were no ifaces */ private boolean startHal() { if (!mIfaceMgr.hasAnyIface()) { if (mWifiVendorHal.isVendorHalSupported()) { if (!mWifiVendorHal.startVendorHal()) { Log.e(TAG, "Failed to start vendor HAL"); Log.i(TAG, "Vendor Hal not supported, ignoring start.");
看mWifiVendorHal.startVendorHal()。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java
* Bring up the HIDL Vendor HAL. * @return true on success, false otherwise. public boolean startVendorHal() { if (!mHalDeviceManager.start()) { mLog.err("Failed to start vendor HAL").flush(); mLog.info("Vendor Hal started successfully").flush();
看mHalDeviceaManager.start()。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java
* Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or * the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on * Note: direct call to HIDL.
继续看startWifi()。
private boolean startWifi() { if (VDBG) Log.d(TAG, "startWifi"); Log.w(TAG, "startWifi called but mWifi is null!?"); while (triedCount <= START_HAL_RETRY_TIMES) { WifiStatus status = mWifi.start(); if (status.code == WifiStatusCode.SUCCESS) { initIWifiChipDebugListeners(); managerStatusListenerDispatch(); Log.d(TAG, "start IWifi succeeded after trying " + triedCount + " times"); } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) { // Should retry. Hal might still be stopping. Log.e(TAG, "Cannot start IWifi: " + statusString(status) Thread.sleep(START_HAL_RETRY_INTERVAL_MS); } catch (InterruptedException ignore) { // Should not retry on other failures. Log.e(TAG, "Cannot start IWifi: " + statusString(status)); Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times"); } catch (RemoteException e) { Log.e(TAG, "startWifi exception: " + e);
主要看WifiStatus status = mWifi.start(),先看下mWifi是什么。
* Wrapper function to access the HIDL services. Created to be mockable in unit-tests. protected IWifi getWifiServiceMockable() { return IWifi.getService(); } catch (RemoteException e) { Log.e(TAG, "Exception getting IWifi service: " + e);
这里返回的是IWifi的服务端。至此我们开始进入HIDL。
3 HIDL
HIDL 读作 hide-l,Wifi到Andoid O之后所以Android P也一样不再使用jni,而是使用HIDL,Hardware Interface Define Language。
3.1 hardware/interfaces/wifi/1.0/IWifi.hal
* Perform any setup that is required to make use of the module. If the module * is already started then this must be a noop. * Must trigger |IWifiEventCallback.onStart| on success. * @return status WifiStatus of the operation. * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.NOT_AVAILABLE|, * |WifiStatusCode.UNKNOWN| @callflow(next={"registerEventCallback", "start", "stop", "getChip"}) start() generates (WifiStatus status);
系统编译的时候会自动产生IWifi.java文件。
out/soong/.intermediates/hardware/interfaces/wifi/1.0/android.hardware.wifi_V1.0-java_gen_java/gen/android/hardware/wifi/V1_0/IWifi.java
IWifi.java的getService方法
public static IWifi getService(String serviceName) throws android.os.RemoteException { return IWifi.asInterface(android.os.HwBinder.getService("android.hardware.wifi@1.0::IWifi",serviceName));
再看一下 IWifi.java的asInterface方法。
IWifi.asInterface(android.os.HwBinder.getService("android.hardware.wifi@1.0::IWifi",serviceName));
从而我们就可以知道IWifi对应的服务端了。
3.2 hardware/interfaces/wifi/1.2/default/wifi.cpp
按照IWifi.java的代码接下来的调用路径应该在hardware/interfaces/wifi/1.0/default/,但没有发现这个路径下有wifi.cpp这个文件,hardware/interfaces/wifi/1.2/default/倒是有wifi.cpp,这个我也不清楚为什么。那就先按这个调用流程走下去吧。
Return<void> Wifi::start(start_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, hidl_status_cb);
看startInternal()。
WifiStatus Wifi::startInternal() { if (run_state_ == RunState::STARTED) { return createWifiStatus(WifiStatusCode::SUCCESS); } else if (run_state_ == RunState::STOPPING) { return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, WifiStatus wifi_status = initializeModeControllerAndLegacyHal(); if (wifi_status.code == WifiStatusCode::SUCCESS) { // Create the chip instance once the HAL is started. chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_, run_state_ = RunState::STARTED; for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onStart().isOk()) { LOG(ERROR) << "Failed to invoke onStart callback"; LOG(INFO) << "Wifi HAL started"; for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onFailure(wifi_status).isOk()) { LOG(ERROR) << "Failed to invoke onFailure callback"; LOG(ERROR) << "Wifi HAL start failed";
WifiStatus Wifi::initializeModeControllerAndLegacyHal() { if (!mode_controller_->initialize()) { LOG(ERROR) << "Failed to initialize firmware mode controller"; return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); legacy_hal::wifi_error legacy_status = legacy_hal_->initialize(); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to initialize legacy HAL: " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); return createWifiStatus(WifiStatusCode::SUCCESS);
接着看wifi_mode_controller.cpp得initialize()方法。
3.3 hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp
bool WifiModeController::initialize() { if (!driver_tool_->LoadDriver()) { LOG(ERROR) << "Failed to load WiFi driver";
再继续看driver_tool.cpp这里开始走到WPA适配层了。
4 WPA适配层(硬件抽象层 HAL)
HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,可以顺利实现相关功能,而不会影响或更改更高级别的系统。HAL 实现会被封装成模块,并由 Android 系统适时地加载。
wpa_supplicant适配层是通用的wpa_supplicant的封装,在Android中作为WiFi部分的硬件抽象层来使用。wpa_supplicant适配层主要用于与wpa_supplicant守护进程的通信,以提供给Android框架使用,它实现了加载、控制和消息监控等功能。
4.1frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp
bool DriverTool::LoadDriver() { return ::wifi_load_driver() == 0;
4.2 frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp
#ifdef WIFI_DRIVER_MODULE_PATH if (is_wifi_driver_loaded()) { if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1; #ifdef WIFI_DRIVER_STATE_CTRL_PARAM if (is_wifi_driver_loaded()) { if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1; property_set(DRIVER_PROP_NAME, "ok");
看is_wifi_driver_loaded()。
int is_wifi_driver_loaded() { char driver_status[PROPERTY_VALUE_MAX]; #ifdef WIFI_DRIVER_MODULE_PATH char line[sizeof(DRIVER_MODULE_TAG) + 10]; if (!property_get(DRIVER_PROP_NAME, driver_status, NULL) || strcmp(driver_status, "ok") != 0) { return 0; /* driver not loaded */ #ifdef WIFI_DRIVER_MODULE_PATH * If the property says the driver is loaded, check to * make sure that the property setting isn't just left * over from a previous manual shutdown or a runtime if ((proc = fopen(MODULE_FILE, "r")) == NULL) { PLOG(WARNING) << "Could not open " << MODULE_FILE; property_set(DRIVER_PROP_NAME, "unloaded"); while ((fgets(line, sizeof(line), proc)) != NULL) { if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) { property_set(DRIVER_PROP_NAME, "unloaded");
5 wpa_supplicant
wpa_supplicant是一个开源项目,已经被移植到Linux,Windows以及很多嵌入式系统上。它是WPA的应用层认证客户端,负责完成认证相关的登录、加密等工作。wpa_supplicant的源代码目录为:
/external/wpa_supplicant_8/
wpa_supplicant是一个独立运行的守护进程,其核心是一个消息循环,在消息循环中处理WPA状态机、控制命令、驱动事件、配置信息等。wpa_supplicant有很多控制接口,也提供命令行和通行界面的控制模式:而Android与wpa_supplicant的通信通过Socket完成
6 Linux Kernel
Wifi的内核驱动程序
kernel/driver/net/wireless/
vendor/gcom/opensource/wlan/
|