Android wifi模块解析

  1. 什么是 WIFI

WIFI模块 - 风雨独行 - 寻路

WIFI 是一种无线连接技术,可用于 PC , PDA ,手机 等终端。 WIFI 的目的是改善基于 IEEE802.11 标准的无线网络产品之间的互通性,也就是说 WIFI 是基于 802.11 标准的,但 WIFI 不等同无线网络。

 

  1. android 平台下的 WIFI 模块

简单介绍一下, WIFI 模块的基本功能:

  1. 开关 WIFI

除了在 WIFI 设置界面可以开关 WIFI ,还有其他 的入口可以开关,要查看这些开关状态是否一致。还有就是飞行模式对 WIFI 开关的影响,由于 WIFI 开和关都有一个时间过程,而飞行模式的开关瞬间完成,所以有时会出现冲突。

  1. 开关新可用网络提醒

新可用网络的定义是自 WIFI 模块开启后,从未发现过的,为加密的网络。只有满足了新可用网络的定义,才会有提醒。

  1. 连接断开网络

连接断开各种不同加密类型的网络(具体类型下文有详解)

  1. 手动添加网络

需要路由器关闭 SIID 广播。可手动输入 SIID ,网络加密类型,密码。对于 OPAL 手机来说,路由器隐藏了 SSID ,手动添加的网络是无法连接的。

  1. 搜索网络

手动点击搜索按钮可以搜索网络,也可以等待 WIFI 模块自动搜索网络。

  1. 休眠设置

由于 WIFI 模块是用电大户,所有为了省电, android WIFI 加了一个休眠策略,可以设置永远不断开,充电时不断开和锁屏时断开。要测试 休眠设置是否有效,可以在路由器上 PING 手机的 IP PING 通就是连接状态。 OPAL 手机的休眠策略属于完全失效,现在的情况是无论选哪个都会一直保持连接,锁屏后 15 分钟再休眠。

  1. 设置静态 IP

Android 系统里对 IP 设置的输入限制很有问题,我一直认为这是弱智的限制。正常 IP 的范围在 0-255 之间, android IP 输入的限制是整数 0 到整数 255 之间,也就是说 0000.000200.001.001 这样一个 IP 都能合法输入。

 

  1. WIFI 模块深入了解一点点

  1. WIFI 的基本运行流程

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 来处理 Wifi 按钮

2 当用户按下 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 中的监视线程

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 中选择好加密方式和输入密钥之后 , 再点击连接按钮 ,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 ,它是一个安全中间件,为各种无线网卡提供统一的安全机制,如下图所示:

WIFI模块 - 风雨独行 - 寻路

对应上述结构,基于 Android 的手机中的 WiFi 控制分为三大组件:
1
)客户端程序,包括 wpa_cli 命令行或 java 图形界面程序,通过 unix 本地 socket
wpa_supplicant daemon
服务通信,发送命令并接收结果;
2
wpa_supplicant daemon 服务,对应上述中间部分,功能是“上传下达”。所有客户端通过它控制硬件网卡,通过发送字符串命令控制是否扫描 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

#}

不同类型的网络,不同的参数等等,应有尽有。

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值