Android Wifi工作流程.docx
- 文档编号:29458440
- 上传时间:2023-07-23
- 格式:DOCX
- 页数:79
- 大小:2.57MB
Android Wifi工作流程.docx
《Android Wifi工作流程.docx》由会员分享,可在线阅读,更多相关《Android Wifi工作流程.docx(79页珍藏版)》请在冰豆网上搜索。
AndroidWifi工作流程
Android Wifi的工作流程
一、WIFI工作相关部分
Wifi网卡状态
1. WIFI_STATE_DISABLED:
WIFI网卡不可用
2. WIFI_STATE_DISABLING:
WIFI正在关闭
3. WIFI_STATE_ENABLED:
WIFI网卡可用
4. WIFI_STATE_ENABLING:
WIFI网卡正在打开
5. WIFI_STATE_UNKNOWN:
未知网卡状态
WIFI访问网络需要的权限
"android.permission.CHANGE_NETWORK_STATE">
修改网络状态的权限
android:
name="android.permission.CHANGE_WIFI_STATE">
修改WIFI状态的权限
"android.permission.ACCESS_NETWORK_STATE">
访问网络权限
"android.permission.ACCESS_WIFI_STATE">
访问WIFI权限
WIFI核心模块
n WifiService
由SystemServer启动的时候生成的ConnecttivityService创建,负责启动关闭wpa_supplicant,启动和关闭WifiMonitor线程,把命令下发给wpa_supplicant以及跟新WIFI的状态
n WifiMonitor
负责从wpa_supplicant接收事件通知
n Wpa_supplicant
1、读取配置文件
2、初始化配置参数,驱动函数
3、让驱动scan当前所有的bssid
4、检查扫描的参数是否和用户设置的想否
5、如果相符,通知驱动进行权限认证操作
6、连上AP
n Wifi驱动模块
厂商提供的source,主要进行loadfirmware和kernel的wireless进行通信
n Wifi电源管理模块
主要控制硬件的GPIO和上下电,让CPU和Wifi模组之间通过sdio接口通信
二、Wifi工作步骤
1 Wifi模块初期化
2 Wifi启动
3 查找热点(AP)
4 配置AP
5 配置AP参数
6 Wifi连接
7 IP地址配置
三、WIFI的架构和流程
1、WIFI的基本架构
1、wifi用户空间的程序和库:
external/wpa_supplicant/
生成库libwpaclient.so和守护进程wpa_supplicant
2、hardware/libhardware_legary/wifi/是wifi管理库
3、JNI部分:
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
4、JAVA部分:
frameworks/base/services/java/com/android/server/
frameworks/base/wifi/java/android/net/wifi/
5、WIFISettings应用程序位于:
packages/apps/Settings/src/com/android/settings/wifi/
6、WIFI驱动模块 wlan.ko
wpa_supplicant通过wireless_ext接口和驱动通信
7、WIFI硬件模块
2、WIFI在Android中如何工作
Android使用一个修改版wpa_supplicant作为daemon来控制WIFI,代码位于external/wpa_supplicant。
wpa_supplicant是通过socket与hardware/libhardware_legacy/wifi/wifi.c通信。
UI通过.wifipackage(frameworks/base/wifi/java/android/net/wifi/)发送命令给wifi.c。
相应的JNI实现位于frameworks/base/core/jni/android_net_wifi_Wifi.cpp。
更高一级的网络管理位于frameworks/base/core/java/android/net。
3、配置Android支持WIFI
在BoardConfig.mk中添加:
BOARD_HAVE_WIFI:
=true
BOARD_WPA_SUPPLICANT_DRIVER:
=WEXT
这将在external/wpa_supplicant/Android.mk设置WPA_BUILD_SUPPLICANT为true,默认使用驱动driver_wext.c。
如果使用定制的wpa_supplicant驱动(例如wlan0),可以设置:
BOARD_WPA_SUPPLICANT_DRIVER:
=wlan0
4、使能wpa_supplicant调试信息
默认wpa_supplicant设置为MSG_INFO,为了输出更多信息,可修改:
1、在common.c中设置wpa_debug_level=MSG_DEBUG;
2、在common.c中把#definewpa_printf宏中的
if((level)>=MSG_INFO)
改为
if((level)>=MSG_DEBUG)
5、配置wpa_supplicant.conf
wpa_supplicant是通过wpa_supplicant.conf中的ctrl_interface=来指定控制socket的,应该在AndroidBoard.mk中配置好复制到$(TARGET_OUT_ETC)/wifi(也就是/system/etc/wifi/wpa_supplicant.conf)这个位置会在init.rc中再次检测的。
一般的wpa_supplicant.conf配置为:
ctrl_interface=DIR=/data/system/wpa_supplicantGROUP=wifi
update_config=1
fast_reauth=1
有时,驱动需要增加:
ap_scan=1
如果遇到AP连接问题,需要修改ap_scan=0来让驱动连接,代替wpa_supplicant。
如果要连接到non-WPAoropenwirelessnetworks,要增加:
network={
key_mgmt=NONE
}
6、配置路径和权限
Google修改的wpa_supplicant要运行在wifi用户和组下的。
代码可见wpa_supplicant/os_unix.c
中的os_program_init()函数。
如果配置不对,会出现下面错误:
E/WifiHW ( ):
Unabletoopenconnectiontosupplicanton
"/data/system/wpa_supplicant/wlan0":
Nosuchfileordirectorywillappear.
确认init.rc中有如下配置:
mkdir/system/etc/wifi0770wifiwifi
chmod0770/system/etc/wifi
chmod0660/system/etc/wifi/wpa_supplicant.conf
chownwifiwifi/system/etc/wifi/wpa_supplicant.conf
#wpa_supplicantsocket
mkdir/data/system/wpa_supplicant0771wifiwifi
chmod0771/data/system/wpa_supplicant
#wpa_supplicantcontrolsocketforandroidwifi.c
mkdir/data/misc/wifi0770wifiwifi
mkdir/data/misc/wifi/sockets0770wifiwifi
chmod0770/data/misc/wifi
chmod0660/data/misc/wifi/wpa_supplicant.conf
如果系统的/system目录为只读,那应该使用路径/data/misc/wifi/wpa_supplicant.conf。
7、运行wpa_supplicant和dhcpcd
在init.rc中确保有如下语句:
servicewpa_supplicant/system/bin/logwrapper/system/bin/wpa_supplicant-dd
-Dwext-iwlan0-c/data/misc/wifi/wpa_supplicant.conf
userroot
groupwifiinet
socketwpa_wlan0dgram660wifiwifi
oneshot
servicedhcpcd/system/bin/logwrapper/system/bin/dhcpcd-d-Bwlan0
disabled
oneshot
根据所用的WIFI驱动名字,修改wlan0为自己驱动的名字。
8、编译WIFI驱动为module或kernelbuiltin
1、编译为module
在BoardConfig.mk中添加:
WIFI_DRIVER_MODULE_PATH:
="/system/lib/modules/xxxx.ko"
WIFI_DRIVER_MODULE_ARG:
="" #forexamplenohwcrypt
WIFI_DRIVER_MODULE_NAME:
="xxxx" #forexamplewlan0
WIFI_FIRMWARE_LOADER:
=""
2、编译为kernelbuiltin
1)在hardware/libhardware_legacy/wifi/wifi.c要修改interface名字,
2)在init.rc中添加:
setpropwifi.interface"wlan0"
3)在hardware/libhardware_legacy/wifi/wifi.c中当insmod/rmmod时,
直接return0。
9、WIFI需要的firmware
Android不使用标准的hotplugbinary,WIFI需要的firmware要复制到/etc/firmware。
或者复制到WIFI驱动指定的位置,然后WIFI驱动会自动加载。
10、修改WIFI驱动适合Android
Google修改的wpa_supplicant要求SIOCSIWPRIVioctl发送命令到驱动,及接收信息,例如signalstrength,macaddressoftheAP,linkspeed等。
所以要正确实现WIFI驱动,需要从SIOCSIWPRIVioctl返回RSSI(signalstrength)和MACADDR信息。
如果没实现这个ioctl,会出现如下错误:
E/wpa_supplicant( ):
wpa_driver_priv_driver_cmdfailed
wpa_driver_priv_driver_cmdRSSIlen=4096
E/wpa_supplicant( ):
wpa_driver_priv_driver_cmdfailed
D/wpa_supplicant( ):
wpa_driver_priv_driver_cmdLINKSPEEDlen=4096
E/wpa_supplicant( ):
wpa_driver_priv_driver_cmdfailed
I/wpa_supplicant( ):
CTRL-EVENT-DRIVER-STATEHANGED
10、设置dhcpcd.conf
一般/system/etc/dhcpcd/dhcpcd.conf的配置为:
interfacewlan0
optionsubnet_mask,routers,domain_name_server
四、WIFI模块分析
Wifi模块学习流程
最近研究Wifi模块,查了不少的相关资料,但发现基本上是基于android2.0版本的的分析,而现在研发的android移动平台基本上都是2.3的版本,跟2.0版本的差别,在Wifi模块上也是显而易见的。
2.3版本Wifi模块没有了WifiLayer,之前的WifiLayer主要负责一些复杂的Wifi功能,如AP选择等以提供给用户自定义,而新的版本里面的这块内容基本上被WifiSettings所代替
本文就是基于android2.3版本的Wifi分析,主要分为两部分来分别说明:
(a) Wifi的启动流程(有代码供参考分析)
(b) Wifi模块相关文件的解析
(c) Wpa_supplicant解析
Awifi的基本运行流程(针对代码而言)
首先给一张我网上down下来的图,针对2.3版本之前的,由于不怎么擅长画这些,大家也就将就点,只要能助理解就可以了
(一)初始化
a.流程
1.在SystemServer启动的时候会生成一个ConnectivityService的实例
2.ConnectivityService的构造函数会创建WifiService
3.WifiStateTracker会创建WifiMonitor接受来自底层的事件,WifiService和WifiMonitor是整个wifi模块的核心,WifiService负责启动和关闭wpa_supplicant,启动和关闭WifiMonitor监视线程和把命令下方给wpa_supplicant,而WifiMonitor则负责从wpa_supplicant接受事件通知
b.代码分析
要想使用Wifi模块,必须首先使能Wifi,当你第一次按下Wifi使能按钮时,WirelessSettings会实例化一个WifiEnabler对象,实例化代码如下:
packages/apps/settings/src/com/android/settings/WirelessSettings.java
[java] viewplaincopy
1.protected void onCreate(Bundle savedInstanceState) {
2.
3. super.onCreate(savedInstanceState);
4.……
5. CheckBoxPreferencewifi = (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI);
6.
7. mWifiEnabler= new WifiEnabler(this, wifi);
8.……
9.}
WifiEnabler类的定义大致如下,它实现了一个监听接口,当WifiEnabler对象被初始化后,它监听到你按键的动作,会调用响应函数onPreferenceChange(),这个函数会调用WifiManager的setWifiEnabled()函数。
[java] viewplaincopy
1.public class WifiEnabler implementsPreference.OnPreferenceChangeListener {
2.……
3.public boolean onPreferenceChange(Preference preference,Object value) {
4. booleanenable = (Boolean) value;
5.……
6.if (mWifiManager.setWifiEnabled(enable)) {
7. mCheckBox.setEnabled(false);
8.……
9.}
10.……
11.}
我们都知道Wifimanager只是个服务代理,所以它会调用WifiService的setWifiEnabled()函数,而这个函数会调用sendEnableMessage()函数,了解android消息处理机制的都知道,这个函数最终会给自己发送一个MESSAGE_ENABLE_WIFI的消息,被WifiService里面定义的handlermessage()函数处理,会调用setWifiEnabledBlocking()函数。
下面是调用流程:
mWifiEnabler.onpreferencechange()===>mWifiManage.setWifienabled()===>mWifiService.setWifiEnabled()===>mWifiService.sendEnableMessage()
===>mWifiService.handleMessage()===>mWifiService.setWifiEnabledBlocking().
在setWifiEnabledBlocking()函数中主要做如下工作:
加载Wifi驱动,启动wpa_supplicant,注册广播接收器,启动WifiThread监听线程。
代码如下:
1.……
2.if (enable) {
3. if (!
mWifiStateTracker.loadDriver()) {
4. Slog.e(TAG, "Failed toload Wi-Fi driver.");
5. setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
6. return false;
7. }
8. if (!
mWifiStateTracker.startSupplicant()) {
9. mWifiStateTracker.unloadDriver();
10. Slog.e(TAG, "Failed tostart supplicant daemon.");
11. setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
12. return false;
13. }
14. registerForBroadcasts();
15. mWifiStateTracker.startEventLoop();
16.……
至此,Wifi使能(开启)结束,自动进入扫描阶段。
(二)扫描AP
当驱动加载成功后,如果配置文件的AP_SCAN=1,扫描会自动开始,WifiMonitor将会从supplicant收到一个消息EVENT_DRIVER_STATE_CHANGED,调用handleDriverEvent(),然后调用mWifiStateTracker.notifyDriverStarted(),该函数向消息队列添加EVENT_DRIVER_STATE_CHANGED,handlermessage()函数处理消息时调用scan()函数,并通过WifiNative将扫描命令发送到wpa_supplicant。
看代码Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
[java] viewplaincopy
1.private void handleDriverEvent(Stringstate) {
2. if (state == null) {
3. return;
4. }
5. if (state.equals("STOPPED")) {
6. mWifiStateTracker.notifyDriverStopped();
7. } else if (state.equals("STARTED")) {
8. mWifiStateTracker.notifyDriverStarted();
9. } else if (state.equals("HANGED")) {
10. mWifiStateTracker.notifyDriverHung();
11. }
12.}
Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
[java] viewplaincopy
1....
2.case EVENT_DRIVER_STATE_CHANGED:
3. switch(msg.arg1) {
4. case DRIVER_STARTED:
5.
6.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Wifi工作流程 Wifi 工作 流程