美文网首页
Android之WIFI-WifiService关键类分析

Android之WIFI-WifiService关键类分析

作者: 锄禾豆 | 来源:发表于2022-02-19 21:44 被阅读0次

分析

构造方法涉及的关键类为

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的数据记录,都在这个文件中

相关文章

网友评论

      本文标题:Android之WIFI-WifiService关键类分析

      本文链接:https://www.haomeiwen.com/subject/lawqkrtx.html