android wifi 流程图_android系统启动后的 wifi 加载过程代码分析

本文详细分析了Android系统启动时WiFi的加载过程,包括系统启动、wpa_supplicant服务、WiFi服务的启动、WiFi状态跟踪以及与wpa_supplicant的交互。通过JNI方法,Android与wpa_supplicant通过socket通信,实现命令的发送和接收,控制WiFi的开启、扫描、连接和IP地址配置等操作。
摘要由CSDN通过智能技术生成

http://blog.csdn.net/wh_19910525/article/details/7390189

2012

=== Wifi 启动代码流程 ====================

1、系统启动 首先加载init.rc,这个文件 会加载所有service,init是Linux启动的 第一个 用户空间 的应用(属于linux进程,不属于Android应用)。

2、init.rc里有以下这句话:

Service wpa_supplicant /system/bin/wpa_supplicant –Dwext –iwlan0 –d –c /data/misc/wifi/wpa_supplicant.conf

3、加载linux内核模块/system/lib/modules/wlan.ko 这个wifi模块定义在/hardware/libhardware_legacy/wifi/wifi.c

4、在SystemServer启动的时候, 会生成一个ConnectivityService 的实例 ,

ConnectivityService 的 构造函数 会创建WifiService,

看看是怎么启动WiFi Service的:

if (DBG) Log.v(TAG, "Starting Wifi Service.");

mWifiStateTracker = new WifiStateTracker(context, handler);

WifiService wifiService = new WifiService(context, mWifiStateTracker);

ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

WifiStateTracker 会创建WifiMonitor  接收来自 底层 的事件, WifiService 和 WifiMonitor是整个模块的核心 。WifiService 负责 启动关闭 wpa_supplicant、启动关闭 WifiMonitor监视线程 和把 命令下发给

wpa_supplicant,  而WifiMonitor 则负责从 wpa_supplicant  接收事件通知。它们与本地库的连接都是通过JNI方法,具体实现方法在android_net_wifi_Wifi.cpp中,在这个文件中可以大致看出APP会给wpa_supplicant下哪些命令。这些命令通过wifi.c的wifi_command发送给wpa_supplicant,在发送命令的过程中实际是调用wpa_ctrl_request来完成命令发送的,wpa_ctrl_request是通过socket的方式与wpa_supplicant进行通信的,然后通过wpa_ctrl_recv来接收来自wpa_supplicant的命令,并返回标识给wifi_wait_for_event。

--------------------------------------

流程图对应的源代码路径为:

WifiEnabler,WifiSettings对应的路径如下:

rootfs/packages/apps/Settings/src/com/android/settings/wifi/

WifiManager,WifiMonitor,WifiStateTracker,WifiNative.对应的源代码路径如下:

rootfs/frameworrks/base/wifi/Java/android/net/wifi/

WifiService 对应代码的位置

rootfs/frameworks/base/services/java/com/android/server/

android_net_wifi_Wifi源代码路径如下:

rootfs/frameworks/base/core/jni/

wifi_command,wifi_wait_for_envent源代码路径如下:

/hardware/libhardware_legacy/wifi/wifi.c

wpa_ctrl_源代码路径如下:

rootfs/external/wpa_supplicant/wpa_ctrl.c

wpa_supplicant源代码路径如下:

rootfs/external/wpa_supplicant/

WIFI启动流程图:

一、使能 WIFIWireless Settings 在初始化的时候配置了由WifiEnabler 来处理 Wifi 按钮, 当用户按下 Wifi 按钮后, Android 会调用 WifiEnabler 的 onPreferenceChange, 再由 WifiEnabler 调用 WifiManager 的 setWifiEnabled 接口 函数,通过 AIDL,实际调用的是 WifiService 的

setWifiEnabled 函数, WifiService 接着向自身发送一条 MESSAGE_ENABLE_WIFI 消息, 在 处理该消息的代码 中做真正的使能工作: 首先装载 WIFI 内核模块(该模块的位置为 "/system/lib/modules/wlan.ko" ),然后启动 wpa_supplicant

( 配置文件 为"/data/misc/wifi/wpa_supplicant.conf") ,再通过 WifiStateTracker 来启动 WifiMonitor 中的 监视线程。

代码如下:

WifiService.java (frameworks/base/services/java/com/android/server)调用 setWifiEnabled()里面的sendEnableMessage(enable, true, Binder.getCallingUid());来发送一则消息

Message msg = Message.obtain(mWifiHandler, (enable? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),(persist ? 1 : 0), uid);

msg.sendToTarget();发送给自身的消息。

当enable的时候 会调用setWifiEnabledBlocking这个函数,这个函数会做setWifiEnabledState ,然后做四件事:

1. 调用JNI的WifiNative.loadDriver  -->加载 Wifi驱动

2. 调用JNI的WifiNative.startSupplicant  -->启动wifi_start_supplicant

3.启动 event loop.

4. 更新wifi的状态

成功启动wifi之后 setWifiEnabledBlocking运行mWifiStateTracker.startEventLoop();事件循环,来监视事件mWifiMonitor.startMonitoring();MonitorThread().start() 一直在线程里循环调用WifiNative.waitForEvent();

当 使能 成功后,会广播发送 WIFI_STATE_CHANGED_ACTION 这个 Intent 通知外界 WIFI已 经 成功能了。WifiEnabler创 建 的 时 候 就 会 向 Android 注册 接收WIFI_STATE_CHANGED_ACTION, 因此它会收到该 Intent, 从而开始扫描。

二、 查找 AP

扫描的入口函数是 WifiService 的 startScan, 它其实也就是往 wpa_supplicant 发送 SCAN 命令。

当 wpa_supplicant 处理完 SCAN 命令后, 它会向 控制通道 发送 事件 通知 扫描完成, 从而wifi_wait_for_event函数会接收到该事件, 由此 WifiMonitor 中的 MonitorThread 会被执行来 处理 这个事件。对每一个扫描返回的 AP, WifiLayer会调用

WifiSettings 的 onAccessPointSetChanged 函数, 从而最终把该 AP 加到 GUI 显示列表中。

三、配置 AP 参数

当用户在 WifiSettings 界面上选择了一个 AP 后,会显示配置 AP 参数的一个对话框,此对话框会显示当前选择的AP信号强度,若此AP设置了密码则需要用户输入密码才能登录。用户配置好之后,点击

连接按钮,onClick函数会被调用。

四、连接

当用户在 AcessPointDialog 中 选择好 加密方式 和 输入密钥 之后,再点击 连接按钮, Android就会去连接这个 AP。

WifiLayer 会先检测这个 AP 是不是之前被配置过, 这个是通过 向 wpa_supplicant 发送 LIST_NETWORK 命令并且比较 返回值 来实现的,

// Need WifiConfiguration for the AP

WifiConfiguration config = findConfiguredNetwork(state);

如果 wpa_supplicant 没有这个 AP 的配置信息, 则会向 wpa_supplicant 发送 ADD_NETWORK  命令来添加该 AP,

if (config == null)

{

// Connecting for the first time, need to create it

config = addConfiguration(state, ADD_CONFIGURATION_ENABLE|ADD_CONFIGURATION_SAVE);

}

ADD_NETWORK 命令 会返回一个 ID , WifiLayer 再用这个返回的 ID 作为 参数 向wpa_supplicant 发送 ENABLE_NETWORK 命令,从而让 wpa_supplicant 去连接该 AP。

五、配置 IP 地址

当 wpa_supplicant 成功连接上 AP 之后, 它会向 控制通道 发送 事件通知连接上 AP 了,

wifi.c的wifi_wait_for_event函数阻塞调用,从而 wifi_wait_for_event 函数会 接收 到该事件,由此 WifiMonitor 中的 MonitorThread 会被执行来 处理 这个事件,

WifiMonitor 再调用 WifiStateTracker 的 notifyStateChange,WifiStateTracker 则接着会往自身发送 EVENT_DHCP_START 消息 来 启动 DHCP 去获取 IP 地址, 然后再广播发送NETWORK_STATE_CHANGED_ACTION

这个 Intent, 最后由 WifiSettings类来响应,改变状态和界面信息。

注意:wpa_ctrl_request,通过socket方式向wpa_supplicant发送命令,以select模式阻塞在wpa_supplicant发送和接收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值