您的位置:首页 > 大数据 > 人工智能

3系统启动后的 wifi 加载过程- http://blog.csdn.net/wh_19910525/article/details/7390189

2012-12-04 11:46 513 查看
============================ Wifi 启动代码流程 ====================

1、系统启动 首先加载init.rc,这个文件 会加载所有serviceinit是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启动流程图:



一、 使能 WIFI

Wireless 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 -->[b]启动[/b]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发送和接收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐