一、Manager层调用到WifiNative

看一些关键性的操作:

启动Hal:startHal()

启动supplicant:startSupplicant()

加载驱动(loadDriver):setupInterfaceForClientMode()

启动WifiMonitor:WifiMonitor.startMonitoring()

这里我们就先选择 启动Hal:startHal() 这条线走下去。

//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) {

synchronized (mLock) {

if (!startHal()) {

Log.e(TAG, "Failed to start Hal");

mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();

return null;

}

if (!startSupplicant()) {

Log.e(TAG, "Failed to start supplicant");

mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();

return null;

}

Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);

if (iface == null) {

Log.e(TAG, "Failed to allocate new STA iface");

return null;

}

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();

return null;

}

if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {

Log.e(TAG, "Failed to setup iface in wificond on " + iface);

teardownInterface(iface.name);

mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();

return null;

}

if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {

Log.e(TAG, "Failed to setup iface in supplicant on " + iface);

teardownInterface(iface.name);

mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();

return null;

}

iface.networkObserver = new NetworkObserverInternal(iface.id);

if (!registerNetworkObserver(iface.networkObserver)) {

Log.e(TAG, "Failed to register network observer on " + iface);

teardownInterface(iface.name);

return null;

}

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);

return iface.name;

}

}

二、Native层

2.1 startHal()

/** Helper method invoked to start supplicant if there were no ifaces */

private boolean startHal() {

synchronized (mLock) {

if (!mIfaceMgr.hasAnyIface()) {

if (mWifiVendorHal.isVendorHalSupported()) {

if (!mWifiVendorHal.startVendorHal()) {

Log.e(TAG, "Failed to start vendor HAL");

return false;

}

} else {

Log.i(TAG, "Vendor Hal not supported, ignoring start.");

}

}

return true;

}

}

2.2 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() {

synchronized (sLock) {

if (!mHalDeviceManager.start()) {

mLog.err("Failed to start vendor HAL").flush();

return false;

}

mLog.info("Vendor Hal started successfully").flush();

return true;

}

}

2.3 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

* success.

*

* Note: direct call to HIDL.

*/

public boolean start() {

return startWifi();

}

private boolean startWifi() {

if (VDBG) Log.d(TAG, "startWifi");

synchronized (mLock) {

try {

if (mWifi == null) {

Log.w(TAG, "startWifi called but mWifi is null!?");

return false;

} else {

int triedCount = 0;

while (triedCount <= START_HAL_RETRY_TIMES) {

WifiStatus status = mWifi.start();

if (status.code == WifiStatusCode.SUCCESS) {

initIWifiChipDebugListeners();

managerStatusListenerDispatch();

if (triedCount != 0) {

Log.d(TAG, "start IWifi succeeded after trying "

+ triedCount + " times");

}

return true;

} else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {

// Should retry. Hal might still be stopping.

Log.e(TAG, "Cannot start IWifi: " + statusString(status)

+ ", Retrying...");

try {

Thread.sleep(START_HAL_RETRY_INTERVAL_MS);

} catch (InterruptedException ignore) {

// no-op

}

triedCount++;

} else {

// Should not retry on other failures.

Log.e(TAG, "Cannot start IWifi: " + statusString(status));

return false;

}

}

Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");

return false;

}

} catch (RemoteException e) {

Log.e(TAG, "startWifi exception: " + e);

return false;

}

}

}

2.4 WifiStatus status = mWifi.start()

mWifi是IWifi的服务端。至此我们开始进入HIDL。

/**

* Wrapper function to access the HIDL services. Created to be mockable in unit-tests.

*/

protected IWifi getWifiServiceMockable() {

try {

return IWifi.getService();

} catch (RemoteException e) {

Log.e(TAG, "Exception getting IWifi service: " + e);

return null;

}

}

三、 HIDL 接口调用

HIDL 读作 hide-l,Wifi到Andoid O之后所以Android P也一样不再使用jni,而是使用HIDL,Hardware Interface Define Language。

系统编译的时候会自动产生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

//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.

* Possible status codes:

* |WifiStatusCode.SUCCESS|,

* |WifiStatusCode.NOT_AVAILABLE|,

* |WifiStatusCode.UNKNOWN|

*/

@entry

@callflow(next={"registerEventCallback", "start", "stop", "getChip"})

start() generates (WifiStatus status);

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));

四、硬件WIFI调用

按照IWifi.java的代码接下来的调用路径应该在hardware/interfaces/wifi/1.0/default/,但没有发现这个路径下有wifi.cpp这个文件,hardware/interfaces/wifi/1.2/default/倒是有wifi.cpp,这个我也不清楚为什么,估计是HIDL的继承关系导致。

4.1 入口 Wifi::start

//hardware/interfaces/wifi/1.2/default/wifi.cpp

Return Wifi::start(start_cb hidl_status_cb) {

return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,

&Wifi::startInternal, hidl_status_cb);

}

WifiStatus Wifi::startInternal() {

if (run_state_ == RunState::STARTED) {

return createWifiStatus(WifiStatusCode::SUCCESS);

} else if (run_state_ == RunState::STOPPING) {

return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,

"HAL is stopping");

}

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_,

feature_flags_);

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";

} else {

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";

}

return wifi_status;

}

4.2 初始化 initializeModeControllerAndLegacyHal()

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);

}

4.3 mode_controller_->initialize()

//hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp

bool WifiModeController::initialize() {

if (!driver_tool_->LoadDriver()) {

LOG(ERROR) << "Failed to load WiFi driver";

return false;

}

return true;

}

4.4 driver_tool_->LoadDriver()

看driver_tool.cpp这里开始走到WPA适配层了。

//frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp

bool DriverTool::LoadDriver() {

return ::wifi_load_driver() == 0;

}

4.4 wifi_load_driver()

int wifi_load_driver() {

#ifdef WIFI_DRIVER_MODULE_PATH

if (is_wifi_driver_loaded()) {

return 0;

}

if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;

#endif

#ifdef WIFI_DRIVER_STATE_CTRL_PARAM

if (is_wifi_driver_loaded()) {

return 0;

}

if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1;

#endif

property_set(DRIVER_PROP_NAME, "ok");

return 0;

}

4.5 结果

调用驱动,通知上层:

insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)

wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0)

property_set(DRIVER_PROP_NAME, "ok");

结束

五、 wpa_supplicant

wpa_supplicant是一个开源项目,已经被移植到Linux,Windows以及很多嵌入式系统上。它是WPA的应用层认证客户端,负责完成认证相关的登录、加密等工作。wpa_supplicant的源代码目录为:/external/wpa_supplicant_8/

wpa_supplicant是一个独立运行的守护进程,其核心是一个消息循环,在消息循环中处理WPA状态机、控制命令、驱动事件、配置信息等。wpa_supplicant有很多控制接口,也提供命令行和通行界面的控制模式:而Android与wpa_supplicant的通信通过Socket完成。

六、 Linux Kernel

Wifi的内核驱动程序

kernel/driver/net/wireless/

vendor/gcom/opensource/wlan/

完~~~

文 | 力卉编程

android wifihal 流程,Wifi笔记 | 启动流程 Native层相关推荐

  1. wifisetting.java_Wifi 笔记 | 启动流程

    csd:csdn_of_coder/article/details/51541094 aosp: Android O Android网络各个模式中,Wifi应该是目前最常用的一种网络方式了:下面就简单 ...

  2. Android 深入研究之 ✨ Activity启动流程+Activity生命周期✨

    Activity分析目录 前言 Activity生命周期 1.activity的四个状态 2.activity的生命周期 3.activity优先级 Activity启动流程 Activity的启动流 ...

  3. Android系统开机到Launcher启动流程分析

    本文基于Android10.0的源码. 由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的. 常见基础问题: SystemServer系统服务进程是如何创建的?Lau ...

  4. 深入分析Android 9.0源代码——Activity启动流程

    引言 点击此处查看<深入分析Android 9.0源代码>系列的组织结构和相关说明. 1 应用进程发起启动请求 本章的调用流程如下图所示: (Context) Activity Instr ...

  5. 深入分析Android 9.0源代码——Service启动流程(startService方式)

    引言 点击此处查看<深入分析Android 9.0源代码>系列的组织结构和相关说明. 1 应用进程发起启动请求 本章的调用流程如下图所示: (Context)ContextWrapperC ...

  6. android源码学习- APP启动流程(android12源码)

    前言: 百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分).所以我结合网上现有的文章,以及源码的阅读和调试, ...

  7. Android 11.0 ActivityManagerService的启动流程

    首先推荐一篇文章,ActivityManagerService-AMS启动流程-[Android取经之路].这篇文章是以Android 10.0源码为基础分析的,写的很详细也很棒,我学习AMS的启动就 ...

  8. App 启动流程与 Activity 启动流程梳理

    目录 前言 流程图 启动流程 第一阶段(Launcher 向 AMS 发送启动请求) 第二阶段(AMS 启动 Activity, 并告知 Launcher pasue) 第三阶段 (App 进程的 A ...

  9. linux uboot启动流程分析,uboot启动流程分析

    uboot版本为NXP维护的2016.03版本 下载地址为http://git.freescale.com/git/... 分析uboot的启动流程,需要编译一下uboot,然后打开链接脚本 u-bo ...

最新文章

  1. mysql多表联查分页_sqlserver多表联合查询和多表分页查询的代码讲解
  2. ubuntu常见错误–Could not get lock /var/lib/dpkg/lock解决
  3. MATLAB实战系列(十二)-如何用人工鱼群算法解决带时间窗车辆路径(CVRP)问题(附MATLAB代码)
  4. PIE SDK影像坏线修复
  5. java zip malformed_关于Java解压文件的一些坑及经验分享(MALFORMED异常)
  6. linux redis客户端_为什么单线程Redis能那么快?
  7. granule size oracle,_ksmg_granule_size oracle内存分配粒度
  8. apk(安卓手机应用软件)解包汉化过程简单陈述 [转贴]
  9. hiberanate 主键查询慢_hibernate 新加数据 查询 缓存 变慢
  10. 求树中某结点的父结点(长子-兄弟表示法)
  11. typedef struct LNode *p和typedef struct LNode笔记
  12. 美团外卖Android平台化架构演进实践
  13. Java url中文转码
  14. html js设置旋转动画效果图,原生JS实现逼真的图片3D旋转效果详解
  15. php中COM函数的使用
  16. word常用宏方法介绍
  17. 创业公司 JPEGmini 可以将照片缩小5倍,但保证图片质量和分辨率
  18. //苏嵌//张朋//2018.07.11
  19. .net RPC框架选型(一)
  20. 09-单片机模块化程序: μCOS-II中内存管理程序使用说明

热门文章

  1. Codeforce 106B Choosing Laptop
  2. Microsoft Solitaire Collection拦截广告
  3. 牛客网华为机试(持续更新ing)
  4. javascript代码混淆与加解密
  5. ARFoundation系列讲解 - 11 检查设备是否支持AR功能
  6. python json模块有什么用_Python的json模块应用总结
  7. tengine mysql_tengine全自动安装
  8. 微信小程序后台持续定位功能使用详解
  9. Matlab 沿X运动触发事件,Matlab RoboticToolBox(一)Link参数、三自由度/四自由度逆运动学...
  10. 服务网格:棋到中盘方见势