分析
构造方法涉及的关键类为
WifiStateMachine
WifiController
WifiController最后仍是调用WifiStateMachine
框架
WifiService -- wpa_supplicant -- 驱动
WifiService:
直接控制:
WifiStateMachine --> WifiNative --> com_android_server_wifi_WifiNative.cpp --> wifi.c(hardware\libhardware_legacy\wifi)
接受消息:
WifiMonitor --> WifiStateMachine
wpa_supplicant:
wpa_supplicant
WPA,是Wi-Fi Protected Access,Wi-Fi安全访问的简称。wpa_supplicant是开源项目源码,被谷歌修改后加入android移动平台,它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的。
WPA_Supplicant功能:通过socket(不管是wpa_supplicant与上层还是wpa_supplicant与驱动都采用socket通讯)与驱动交互上报数据给用户,而用户可以通过socket发送命令给wpa_supplicant调动驱动来对WiFi芯片操作。简单的说,wpa_supplicant就是wifi驱动和用户(wifi应用程序)的中间件,支持相关协议和加密认证。
WifiStateMachine
WifiNative 直接操作wpa_supplicant
WifiMonitor 监听wpa_supplicant消息
Wifi
状态机深入分析
1.关闭Wifi时,WifiStateMachine 处于何种状态机?
默认状态InitialState
2.打开wifi时,WifiStateMachine 处于何种状态?
DisconnectedState
3.连接wifi成功,WifiStateMachine 处于何种状态?
ConnectedState
4.执行扫描wifi时,WifiStateMachine 处于何种状态?
DisconnectedState
5.是不是打开wifi本身就会自动扫描?
对。打开wifi会触发扫描服务,扫描服务会触发wpa_supplicant扫描,而扫描的结果通过WifiMonitor通知扫描服务。(注意:WifiMonitor本身的启动wifi正常打开时,才启动)
WifiScannerService自动触发扫描服务。也就是framework进行触发工作。
WifiStateMachine DriverStartedState 进行WifiScanner创建
6.开机怎么自动连接wifi的?
扫描服务跟wpa_supplicant通信,如果发现wpa_supplicant.conf有数据,则自动连接
String listStr = mWifiNative.listNetworks(last_id);
1.获取的是wpa_supplicant.conf中保存的数据
2.java层调用,关键类为:WifiConfigStore.java
7.开机无法自动连上网络的情况?
如果所保存ap不稳定,会导致连接不上
可以关注日志WifiMonitor
执行扫描
扫描命令的执行
D WifiNative-wlan0: doBoolean: SCAN TYPE=ONLY
D WifiNative-wlan0: SCAN TYPE=ONLY: returned true
扫描命令执行之后的WifiMonitor监听回复
D WifiMonitor: Event [IFNAME=wlan0 CTRL-EVENT-SCAN-STARTED ]
D WifiMonitor: wlan0 cnt=105 dispatchEvent: CTRL-EVENT-SCAN-STARTED
D WifiMonitor: handleEvent 14 CTRL-EVENT-SCAN-STARTED
W WifiMonitor: handleEvent unknown: 14 CTRL-EVENT-SCAN-STARTED
D WifiMonitor: Event [IFNAME=wlan0 CTRL-EVENT-SCAN-RESULTS ]
D WifiMonitor: wlan0 cnt=109 dispatchEvent: CTRL-EVENT-SCAN-RESULTS
D WifiMonitor: handleEvent 4 CTRL-EVENT-SCAN-RESULTS
回到各个状态机监听的情况,使用:SCAN_RESULTS_EVENT
WifiManager.startScan
最后仍是落地WifiScanningServiceImpl
wpa启动
device/rockchip/common/init.connectivity.rc:100:service wpa_supplicant /system/bin/wpa_supplicant \
大的流程
wifiService -- wpa_supplicant
1.wpa_supplicant 向 wifiservice发送消息 格式:CTRL-EVENT
关注WifiMonitor
2.wifiService 向 wpa_supplicant发送消息 格式多种多样
关注WifiNative
常用:ADD_NETWORK、SET_NETWORK、SCAN TYPE=ONLY、STATUS
3.wifiservice调用wpa_supplicant,使用的wpa_supplicant对外的接口。可查wpa_ctrl.h
关键接口:
//创建一个wpa控制端对象wpa_ctrl。Android平台中,参数ctrl_path代表unix域socket的位置
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
void wpa_ctrl_close(struct wpa_ctrl *ctrl);//注销wpa_ctrl控制对象
//客户端发送命令给wpa_supplicant,回复的消息保存在reply中
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
char *reply, size_t *reply_len,void (*msg_cb)(char *msg, size_t len));
//打开通知事件监听功能
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
//打开通知事件监听功能的wpa_ctrl对象能直接调用下面的函数来接收unsolicited event
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
详细步骤
wpa_supplicant什么时候被启动?
打开wifi时启动。
mWifiNative.startSupplicant(mP2pSupported) -- wifi.c
wifi.c
int wifi_start_supplicant(int p2p_supported)
{
···
property_set("ctl.start", supplicant_name);
···
}
即通过"setprop ctrl.start wpa_supplicant"触发init进程fork子进程WPAS
init.**.rc
service p2p_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-I/system/etc/wifi/p2p_supplicant_overlay.conf \
-puse_p2p_group_interface=1p2p_device=1 \
-m/data/misc/wifi/p2p_supplicant.conf \
-e/data/misc/wifi/entropy.bin -O/data/misc/wifi/sockets \
-g@android:wpa_wlan0
class main
socket wpa_wlan0 dgram 660 wifi wifi
disabled
oneshot
特别注意/data/misc/wifi/wpa_supplicant.conf已经被传进去了。
后续wifi的数据记录,都在这个文件中
网友评论