`
quanminchaoren
  • 浏览: 911889 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

    STM32单片机通过ESP8266WiFi模块与Android APP实现数据传输.rar

    STM32单片机通过ESP8266WiFi模块与Android APP实现数据传输,包含STM32单片机的源代码和手机APP的源代码,里面也有apk文件可以直接安装使用。代码全部测试过,都可以正常的运行和使用。关注宫中浩“闲饭疙瘩”,并...

    串口wifi模块 第三代串口wifi模块使用技巧

    03串口Wifi模块是基于Uart接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户串口数据到无线网络之间的转换。通过Uart-Wifi模块,传统的串口设备也能轻松接...

    串口wifi-03模块例程代码

    03串口Wifi模块是基于Uart接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户串口数据到无线网络之间的转换。通过Uart-Wifi模块,传统的串口设备也能轻松接...

    老罗android开发视频教程全集百度网盘下载

    Android进阶高级:蓝牙/WIFI SMS/MMS 应用实现 深层次解析GPS原理,实现LocationManager/LocationProvider 进行定位/跟踪/查找/趋近警告以及Geocoder正逆向编解码等技术细节 2D图形库(Graphics/View)详解 SDCARD/...

    《Android开发精要》范怀宇 PDF

    第10章分析了Android的各种网络连接方式,涵盖NFC和基于Wifi的P2P连接等内容;第11章讲解了Android的定位服务、地址解析服务、地图服务的框架实现;第12章仔细分析了Android各种多媒体功能的实现机制;第13章对...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    Android百度地图定位模块资料+

    定位功能:通过GPS、网络定位(WIFI、基站)混合定位模式,返回当前所处的位置信息反地理编码功能:解析当前所处的位置坐标,获得详细的地址描述信息。定位SDK支持多样化服务与定位策略,用户可通过设置不同的定位...

    高性价比WIFI图传方案使用WEB配网发送get请求获取天气预报教程(免费版)-电路方案

    有一篇CSDN的博客论述了WIFI模块各种常见的配网方式说明及其比较,证明了最好的配网方式是WEB配网,反正个人觉得微信配网很麻烦,因为要使用微信,没有微信就没有办法了。在这一期项目中:将要实现一个WEB配网方式,...

    小型物联网系统——家居网关设计-电路方案

    zigbee智能家居+wifi(智能网关)+Android APP 独家珍藏免费分享—智能家居控制系统完整设计方案 智能手表不要买,自己也可以DIY制作(制作资料开源) 重金购买的国赛机密资料 — 智能家居原理图、程序(软硬件开源,...

    【RT-Thread作品秀】数采一期下位机-电路方案

    详情参考SocketIO),下位机采集或汇总的数据并通过 WIFI 上传云端远程实时监视,也可本地连接串口与 PC 端通讯,上位机通过自定义解析数据后展示到相关订阅端(可同时同步到多个Android手机)。对于物联网初创公司...

Global site tag (gtag.js) - Google Analytics