Android WIFI模块分析
一:什么是WIFI
WIFI是一种无线连接技术。可用于手机、电脑、PDA等终端。
WIFI技术产生的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11标准的,但WIFI不等同无线网络。
二:Android平台下的WIFI模块
简介一下,WIFI模块的基本功能:
1. 开关WIFI
除了在WIFI设置界面能够开关WIFI,还有其它的方法能够设置。要查看这些开关状态是否一致。还有就是飞行模式对WIFI开关的影响。因为WIFI开和关都有一个时间过程,而飞行模式的开关瞬间完毕,所以有时会出现冲突。
2. 开关新可用网络提醒
新可用网络的定义是自WIFI模块开启后,从未发现过的,为加密的网络。
仅仅有满足了新可用网络的定义,才会有提醒。
3. 连接断开网络
连接断开各种不同加密类型的网络(具体类型下文有具体解释)
4. 手动加入网络
须要路由器关闭SIID广播。
可手动输入SIID。网络加密类型,password。
对于OPAL手机来说,路由器隐藏了SSID,手动加入的网络是无法连接的。
5. 搜索网络
手动点击搜索button能够搜索网络。也能够等待WIFI模块自己主动搜索网络。
6. 休眠设置
因为WIFI模块是用电大户,全部为了省电,Android的WIFI加了一个休眠策略。能够设置永远不断开,充电时不断开和锁屏时断开。要測试休眠设置
是否有效,能够在路由器上PING手机的IP,PING通就是连接状态。OPAL手机的休眠策略属于全然失效,如今的情况是不管选哪个都会一直保持连接,
锁屏后15分钟再休眠。
7. 设置静态IP
Android系统里对IP设置的输入限制非常有问题。我一直觉得这是弱智的限制。正常IP的范围在0-255之间,android对IP输入的限制是整数0到整数255之间,也就是说0000.000200.001.001这样一个IP都能合法输入。
三:对WIFI模块深入了解一点点
1、WIFI的基本执行流程

【初始化】
1 在SystemServer启动的时候,会生成一个ConnectivityService的实例。
2 ConnectivityService的构造函数会创建WifiService。
3
WifiStateTracker会创建WifiMonitor接收来自底层的事件,WifiService和WifiMonitor是整个模块的核心。
WifiService负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程和把命令下发给
wpa_supplicant,而WifiMonitor则负责从wpa_supplicant接收事件通知。
【连接AP】
1 WirelessSettings在初始化的时候配置了由WifiEnabler来处理Wifibutton。
2 当用户按下Wifibutton后,
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
中的监视线程。
3当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION这个Intent通知外界WIFI已 经 成 功 使 能 了
。WifiEnabler创 建 的 时 候 就 会 向Android注 冊 接
收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而開始扫描。
【查找AP】
1 扫描的入口函数是WifiService的startScan,它事实上也就是往wpa_supplicant发送SCAN命令。
2 当wpa_supplicant处理完SCAN命令后,它会向控制通道发送事件通知扫描完毕,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被运行来出来这个事件。
3 WifiStateTracker则接着广播发送SCAN_RESULTS_AVAILABLE_ACTION这个Intent。
4
WifiLayer注冊了接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent,所以它的相关处理函数
handleScanResultsAvailable会被调用,在该函数中,先会去拿到SCAN的结果(终于是往wpa_supplicant发送
SCAN_RESULT命令并读取返回值来实现的),List<scanresult> list =
mWifiManager.getScanResults();对每个扫描返回的AP,WifiLayer会调用WifiSettings的
onAccessPointSetChanged函数,从而终于把该AP加到GUI显示列表中。
【配置AP參数】
当用户在WifiSettings界面上选择了一个AP后,会显示配置AP參数的一个对话框。
showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
【连接】
当用户在AcessPointDialog中选择好加密方式和输入密钥之后,再点击连接button,Android就会去连接这个AP。
1 WifiLayer会先检測这个AP是不是之前被配置过,这个是通过向wpa_supplicant发送LIST_NETWORK命令而且比較返回值来实现的,
//Need WifiConfiguration for the AP
WifiConfiguration config = findConfiguredNetwork(state);
假设wpa_supplicant没有这个AP的配置信息,则会向wpa_supplicant发送ADD_NETWORK命令来加入该AP
2 ADD_NETWORK命令会返回一个ID,WifiLayer再用这个返回的ID作为參数向wpa_supplicant发送ENABLE_NETWORK命令,从而让wpa_supplicant去连接该AP。
【配置IP地址】
1 当wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP了,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被运行来出来这个事件。
2 WifiMonitor再调用WifiStateTracker的notifyStateChange,WifiStateTracker则接着会往自身发送EVENT_DHCP_START消息来启动DHCP去获取IP地址。
3 然后再广播发送NETWORK_STATE_CHANGED_ACTION这个Intent。
4
WifiLayer注冊了接收NETWORK_STATE_CHANGED_ACTION这个Intent,所以它的相关处理函数
handleNetworkStateChanged会被调用,当DHCP拿到IP地址之后,会再发送EVENT_DHCP_SUCCEEDED消息。
5 WifiLayer处 理EVENT_DHCP_SUCCEEDED消息,会再次广播发送。
至此为止,整个连接过程完毕。
2、wpa_supplicant
Android平台使用的WiFi控制框架是基于大名鼎鼎的wpa_supplicant,它是一个安全中间件。为各种无线网卡提供统一的安全机制,例如以下图所看到的:

相应上述结构。基于Android的手机中的WiFi控制分为三大组件:
1 client程序,包含wpa_cli命令行或java图形界面程序,通过unix本地socket与wpa_supplicant daemon服务通信。发送命令并接收结果。
2 wpa_supplicant
daemon服务,相应上述中间部分,功能是“上传下达”。全部client通过它控制硬件网卡,通过发送字符串命令控制是否扫描AP,提取扫描结果和是否关联
AP等操作,同一时候将驱动的运行状态发送给用户。
该服务是设计支持多种无线网卡芯片,因此各个厂商共同提供了一个通用接口给wpa_supplicant调
用。
3 网卡驱动。
在手机内存的/etc/wpa_supplicant.conf中我们能够直接看到WIFI支持的网络类型。每种类型都有样例,比方:
#Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and
# group cipher.
#network={
# ssid="example"
# bssid=00:11:22:33:44:55
# proto=WPA RSN
# key_mgmt=WPA-PSK WPA-EAP
# pairwise=CCMP
# group=CCMP
# psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
#}
不同类型的网络,不同的參数等等。应有尽有。
四:对WIFI模块的LOG了解多一点点
我们在上面已经知道WIFI的启动过程。在功能执行中也会输出对应的日志信息,以下就来具体了解一下。(请注意,WIFI开启后会更改电池状态等其它状
态。
关闭WIFI时。android的策略是卸载驱动来省电。如有缺失就是问题。只是下文删去了与WIFI无关的LOG。)
1、开启WIFI&自己主动搜索
E/WifiHW ( 1201): ==JOHN DEBUG==: [WIFI] Load Driver
载入驱动
D/SettingsWifiEnabler( 1321): Received wifi state changed from Disabled to Enabling
接收到广播:WIFI正在开启
D/WifiService( 1201): ACTION_BATTERY_CHANGED pluggedType: 2
电池状态改变
E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008
filename:/system/lib/modules/dhd.ko
args:firmware_path=/system/wlan/broadcom/rtecdc.bin
nvram_path=/system/wlan/broadcom/nvram.txt
WIFI硬件:载入内核模块
I/wpa_supplicant( 2490): CTRL-EVENT-STATE-CHANGE id=-1 state=2
wpa_supplicant发出事件通知
V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=2]
WifiMonitor从wpa_supplicant接收事件通知
I/wpa_supplicant( 2490): CTRL-EVENT-SCAN-RESULTS Ready
wpa_supplicant发出事件通知:准备好開始搜索网络了
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 4096
wpa_supplicant发出事件通知:驱动命令行.主动搜索.LEN
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 0, 11
wpa_supplicant发出事件通知:驱动命令行.主动搜索.LEN
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 4096
wpa_supplicant发出事件通知:驱动命令行.被动搜索.LEN
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 0, 12
wpa_supplicant发出事件通知:驱动命令行.被动搜索.LEN=0.12
D/SettingsWifiEnabler( 1321): Received wifi state changed from Enabling to Enabled
接收到广播:WIFI已经开启
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd RSSI len = 4096
wpa_supplicant发出事件通知:
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd RSSI len = 4, 4
wpa_supplicant发出事件通知:
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd LINKSPEED len = 4096
wpa_supplicant发出事件通知:
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd LinkSpeed 54 len = 12, 12
wpa_supplicant发出事件通知:
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd MACADDR len = 4096
wpa_supplicant发出事件通知:驱动命令行.MAC地址.LEN
E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd Macaddr = 44:A4:2D:27:25:BE
wpa_supplicant发出事件通知:驱动命令行.MAC地址
E/wpa_supplicant( 2490): len = 28, 28
wpa_supplicant发出事件通知:
V/WifiStateTracker( 1201): Connection to supplicant established, state=SCANNING
WIFI状态跟踪:连接请求确认,状态=搜索
D/NetworkStateTracker( 1201): setDetailed state, ld =IDLE and new state=SCANNING
网络状态跟踪:更新显示为搜索状态
V/WifiStateTracker( 1201): Changing supplicant state: SCANNING ==> INACTIVE
WIFI状态跟踪:更改请求状态:搜索中->不活动
2、点击连接&获取状态
E/WifiHW ( 1201): ==JOHN DEBUG==: [WIFI] Load Driver
WIFI硬件:载入驱动
D/SettingsWifiEnabler( 1321): Received wifi state changed from Disabled to Enabling
收到广播,WIFI状态正在开启
E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008
filename:/system/lib/modules/dhd.ko
args:firmware_path=/system/wlan/broadcom/rtecdc.bin
nvram_path=/system/wlan/broadcom/nvram.txt
WIFI硬件:载入内核模块
E/WifiHW ( 1201): ==JOHN DEBUG==: return of insmod : ret = 0, Unknown error: 0
WIFI硬件:返回装载模块报告:返回指令0,未知错误0
……
I/wpa_supplicant( 2490): Trying to associate with 1c:bd:b9:f6:a7:9f (SSID='LosAngeles' freq=2412 MHz)
wpa_supplicant发出事件通知:尝试连接,(SSID='LosAngeles'频段=2412 MHz)
V/WifiMonitor( 1201):Event[Trying to associate with 1c:bd:b9:f6:a7:9f (SSID='LosAngeles' freq=2412 MHz)]
WifiMonitor接收wpa_supplicant的事件
V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=3]
WifiMonitor接收事件
V/WifiStateTracker( 1201): Changing supplicant state: SCANNING ==> ASSOCIATING
WIFI状态跟踪:更改请求状态:搜索中->匹配中
D/NetworkStateTracker( 1201): setDetailed state, ld =SCANNING and new state=CONNECTING
网络状态跟踪:更新显示为正在连接状态
D/ConnectivityService( 1201): ConnectivityChange for WIFI: CONNECTING/CONNECTING
连接管理服务:改变WIFI连接状态:正在连接/正在连接
V/WifiStateTracker( 1201): Changing supplicant state: ASSOCIATING ==> ASSOCIATED
WIFI状态跟踪:更改请求状态:匹配中->已匹配
D/NetworkStateTracker( 1201): setDetailed state, ld =CONNECTING and new state=CONNECTING
网络状态跟踪:更新显示为正在连接状态
I/wpa_supplicant( 2490): Associated with 1c:bd:b9:f6:a7:9f
wpa_supplicant发出事件通知:已和1c:bd:b9:f6:a7:9f匹配
V/WifiMonitor( 1201): Event [Associated with 1c:bd:b9:f6:a7:9f]
WifiMonitor接收wpa_supplicant的事件
V/WifiStateTracker( 1201): Changing supplicant state: ASSOCIATED ==> FOUR_WAY_HANDSHAKE
WIFI状态跟踪:更改请求状态:已匹配->TCP中断连接
D/NetworkStateTracker( 1201): setDetailed state, ld =CONNECTING and new state=AUTHENTICATING
网络状态跟踪:更新显示为鉴定中
D/ConnectivityService( 1201): Dropping ConnectivityChange for WIFI: CONNECTING/AUTHENTICATING
连接管理服务:抛出WIFI连接状态改变:已连接/鉴定中
V/WifiStateTracker( 1201): Changing supplicant state: FOUR_WAY_HANDSHAKE ==> GROUP_HANDSHAKE
WIFI状态跟踪:更改请求状态:TCP中断连接->确认标志位
D/NetworkStateTracker( 1201): setDetailed state, ld =AUTHENTICATING and new state=AUTHENTICATING
网络状态跟踪:更新显示为鉴定中
I/wpa_supplicant( 2490): WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f [PTK=CCMP GTK=TKIP]
wpa_supplicant发出事件通知:WPA:与1c:bd:b9:f6:a7:9f确定标志位
I/wpa_supplicant( 2490): CTRL-EVENT-STATE-CHANGE id=0 state=7
wpa_supplicant发出事件通知:
I/wpa_supplicant( 2490): CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9f completed (auth) [id=0 id_str=]
wpa_supplicant发出事件通知:连接完毕
V/WifiMonitor( 1201): Event [WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f [PTK=CCMP GTK=TKIP]]
WifiMonitor接收wpa_supplicant事件
V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=0 state=7]
WifiMonitor接收wpa_supplicant事件
V/WifiMonitor( 1201): Event [CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9f completed (auth) [id=0 id_str=]]
WifiMonitor接收wpa_supplicant事件
V/WifiStateTracker( 1201): Changing supplicant state: GROUP_HANDSHAKE ==> COMPLETED
WIFI状态跟踪:更改请求状态:确认标志位->完毕
V/WifiStateTracker( 1201): New network state is CONNECTED
WIFI状态跟踪:新网络状态为已连接
D/NetworkStateTracker( 1201): setDetailed state, ld =AUTHENTICATING and new state=OBTAINING_IPADDR
网络状态跟踪:更新显示为获取IP地址
D/ConnectivityService( 1201): Dropping ConnectivityChange for WIFI: CONNECTING/OBTAINING_IPADDR
连接管理服务:抛出WIFI
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?
v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(32) | 评论(0) | 转发(0) |
Android WIFI模块分析的更多相关文章
- Android 下载模块分析(DownloadManager和DownloadProvider)
Android下载模块主要有2个部分组成:DownloadManager和DownloadProvider:其中DownloadManager提供接口供调用,具体的实现是 DownloadProvid ...
- android Camera模块分析
Android Camera Module Architecture and Bottom layer communication mechanism ----------- ...
- Android Wi-Fi基本操作
从用户角度看,Android Wi-Fi模块自下向上可以看为5层:硬件驱动程序,wpa_suppplicant,JNI,WiFi API,WifiSettings应用程序. 1.wpa_supplic ...
- Android WIFI 分析(一)
本文基于<深入理解Android WiFi NFC和GPS 卷>和 Android N 代码结合分析 WifiService 是 Frameworks中负责wifi功能的核心服务,它主 ...
- android wifi ANR问题分析总结
android wifi ANR问题分析总结 1 看看main进程阻塞在那里? 2 调用关系的函数阻塞在那里? 3 最终阻塞函数的阻塞前的log以及状态
- Android开发—智能家居系列】(二):用手机对WIFI模块进行配置
在实际开发中,我开发的这款APP是用来连接温控器,并对温控器进行控制的.有图为证,哈哈. 上一篇文章[Android开发—智能家居系列](一):智能家居原理的文末总结中写到: 手机APP控制智能温控器 ...
- android 基于wifi模块通信开发
这篇文章主要是我写完手机与wifi模块通信后所用来总结编写过程的文章,下面,我分几点来说一下编写的大概流程. 一.拉出按钮控件并设置它的点击事件 二.设置wifi权限 三.打开和关闭wifi 四.扫描 ...
- 【Android开发—智能家居系列】(三):手机连接WIFI模块
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 概述 实现连接WIFI的功能会用到一个工具类,源码可以点击链接下载.网上这些类似的工具类里的代码差不多是一样的.连接无线网主要有 ...
- android——wifi系统架构
1. 系统架构 Android WiFi系统引入了wpa_supplicant,它的整个WiFi系统以wpa_supplicant为核心来定义上层用户接口和下层驱动接口.整个WiFi系统架构如下图所示 ...
随机推荐
- vuex相关知识点
vuex简单理解转载博客 vuex从入门到入门------state:从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态------Getters:可以很容易地在任何组件中使用它- ...
- jsp jstl标签库 el表达式
一.JSTL标签是什么? 提供了对国际化(I18N)的支持,它可以根据发出请求的客户端地域的不同来显示不同的语言. 同时还提供了格式化数据和日期的方法.实现这些功能需要I18N格式标签库(I18N-c ...
- [SQL server] IF ELSE 和 CASE WHEN 的用法
/*判断一个数如果大于10,按10统计,如果小于0,按0统计*/ --方法a DECLARE @AA INT SET @AA=15 IF @AA>10 SELECT 10 ELSE IF @AA ...
- 【LeetCode】Reverse Nodes in k-Group(k个一组翻转链表)
这是LeetCode里的第25道题. 题目要求: 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最 ...
- 【容器人必看】你一定要来 ECUG Con 2018 的三个理由!
引领国内云领域风向的高端峰会 ECUG Con 2018,即将在 12 月 22-23 日 深圳南山 全新启程!如果你的工作和容器内容相关联,如果你的兴趣和容器技术有交集,如果你是「容器人」,那么这就 ...
- HDU——2612Find a way(多起点多终点BFS)
Find a way Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- VBA Split()函数
Split()函数返回一个数组,其中包含基于分隔符分割的特定数量的值. 语法 Split(expression[,delimiter[,count[,compare]]]) 参数说明 Expressi ...
- 常州模拟赛d6t3 噪音
FJ有M个牛棚,编号1至M,刚开始所有牛棚都是空的.FJ有N头牛,编号1至N,这N头牛按照编号从小到大依次排队走进牛棚,每一天只有一头奶牛走进牛棚.第i头奶牛选择走进第p[i]个牛棚.由于奶牛是群体动 ...
- Fruit Ninja
Fruit Ninja 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 Fruit Ni ...
- 关于事件委托和时间冒泡(以及apply和call的事项)
搜索事件委托和事件冒泡,网上一大堆乱七八糟的解释,当然意思都对,没毛病. but,真的无聊. 事件冒泡:事件会从点击的元素开始依次向上流出,直到html,遇见事件监听则执行. 事件委托:原因——父元素 ...