Android Wifi 連接相關流程
在Wifi打開的流程中分析過,會通過WifiCond啟動Wap_supplicant服務,然後監聽Wap_supplicant是否啟動完成,啟動完成後會和Wap_supplicant服務建立連接。同時創建一個mISupplicantStaIface的Binder代理對象,他主要用來完成Wifi的連接工作。
這裡就分析Wifi連接的流程:
應用就是通過WifiManager的connect函數來發起連接的。
1 WifiManager.connect函數
getChannel返回的是WifiManager的成員變數mAsyncChannel:他是一個AsyncChannel類實例,這個在Wifi掃描的文章中分析過,他內部有一個Messager指向WifiServiceImpl,也就是說在這個函數裡面發送了一條CONNECT_NETWORK的消息到WifiServiceImpl的消息隊列裡面,同時還攜帶了WifiConfiguration。
config: 是當前需要連接的Wifi的配置信息,包含Wifi的SSID,密碼等等。
2 WifiServiceImpl 中的ClientHandler對CONNECT_NETWORK消息的處理:
首先獲取config,以及networkId,這個networkId和Wifi存儲相關以後專門分析。
然後檢查要連接的Wifi 的config,最後把該消息又發送到了WifiStateMachine的消息隊列裡面。
3 在WifiStateMachine狀態機中由ConnectModeState狀態處理該消息(CONNECT_NETWORK)具體如下:
這部分處理主要做了如下幾件事情:
3.1 從消息中取出WifiConfiguration然後調用WifiConfigManager保存當前Wifi配置。這部分代碼會在Wifi存儲的文章中來詳細分析。
3.2 調用connectToUserSelectNetwork函數完成連接Wifi的動作。
3.3 如果連接失敗返回連接失敗的消息CONNECT_NETWORK_FAILED
3.4 如果連接成功則返回連接成功的消息CONNECT_NETWORK_SUCCEEDED
這裡重點分析connectToUserSelectNetwork函數是如何完成Wifi連接的。
4 connectToUserSelectNetwork函數
這個函數主要省略的部分主要是對WiFiConfiguration做一些檢查和更新,然後調用了startConnectToNetwork函數:
startConnectToNetwork就是往消息隊列裡面發送了CMD_START_CONNECT的消息。攜帶了NetworkId和BSSID
首先這條消息還是發送到了WifiStateMachine狀態機的消息隊列裡面,
NetworkId: Wifi存儲的一個Id 可以通過這個Id拿到WiFiConfiguration。
bssid: Wifi的Mac地址
5 WifiStateMachine狀態機的ConnectModeState狀態處理CMD_START_CONNECT消息:
這裡主要做的事情是:
5.1 獲取NetId然後調用WifiConfigManager的介面獲取WiFiConfiguration,這裡需要注意的是我們在第一次連接的時候,是需要帶Password的。獲取NetId然後調用WifiConfigManager的介面獲取WiFiConfiguration,這裡需要注意的是我們在第一次連接的時候,是需要帶Password的。
5.2 調用mWifiNative的connectToNetwork函數發起連接。
6 mWifiNative的connectToNetwork函數
首先暫停Wifi掃描,然後直接調用mSupplicantStaIfaceHal的connectToNetwork函數並帶上 configuration
7 mSupplicantStaIfaceHal的connectToNetwork函數
在這個函數裡面主要首先會對WiFiConfiguration做一些檢查,最後調用了 addNetworkAndSaveConfig(config); 函數具體代碼如下:
這個函數主要做了兩件事情;
1 調用addNetwork函數,獲取一個SupplicantStaNetworkHal類的實例:network 在他的內部包含一個實現了ISupplicantStaNetwork介面的Binder代理對象。
2 調用network的saveWifiConfiguration通過上面創建的ISupplicantStaNetwork介面的Binder代理對象把Config相關的數據傳到wap_supplicant服務。
接下來詳細分析這兩點。
8 關於ISupplicantStaNetwork介面的Binder代理對象以及network的獲取:
mISupplicantStaIface: 前面在分析Wifi打開流程的時候有說過,他對的Binder本地對象是wap_supplication服務中的StaIface,用於wap_supplication服務交互的。
StaIface的 addNetwork 函數會返回一個 ISupplicantNetwork 介面的Binder對象。並把這個binder代理對象保存到
SupplicantStaNetworkHal 的成員變數:mISupplicantStaNetwork。
然後返回一個 SupplicantStaNetworkHal 類實例。
關於ISupplicantNetwork介面的binder代理對象解釋:
他對應的binder本地對象實際上是wap_supplicant 服務中的 StaNetwork(sta_network.cpp中)這個binder主要是用來保存需要連接一個Wifi的網路設置以及wifi相關信息。
在接下來的代碼中我們能看到這個功能。
9 關於Network的存儲:SupplicantStaNetworkHal的 saveWifiConfiguration(config)函數:
9.1 保存Wificonfig的數據到wap_supplication服務中。
這個函數首先會檢查Wificonfig的各種數據,然後各種調用setxx的函數比如:setSsid函數
mISupplicantStaNetwork在上一步有說明,他是一個ISupplicantNetwork介面Binder代理對象。對應在wap_supplicant服務中Binder本地對象是StaNetwork
這裡調用mISupplicantStaNetwork.setSsid(ssid);就是把Wificonfig的信息保存到wap_supplicant服務中。
類似這樣的介面很多這裡不一一分析了:
9.2 註冊mISupplicantStaNetworkCallback
這裡還是調用mISupplicantStaNetwork的registerCallback把 ISupplicantStaNetworkCallback介面的binder對象callback註冊到wap_supplicant服務中。
ISupplicantStaNetworkCallback:這個bidner對象會返回一些關於連接當前Wificonfig對應的Wifi的一些認證信息
總結一下:
實際上發起Wifi連接的過程就是把WiFiConfiguration的數據發送到Wap_supplicant服務的過程。
Wifi連接的發起完成了,連接的狀態呢?成功還是失敗?
這裡有必要先說清楚兩個事情:
說明1: Wap_supplicant服務起來後,會創建一個會創建一個mISupplicantStaIface的Binder代理對象來完成上面的連接,同時他還會註冊一個mISupplicantStaIfaceCallback的Binder對象到Wap_supplicant服務用於返回Wifi的狀態信息。
當Wifi連接成功後會收到mISupplicantStaIfaceCallback這個Binder對象會被回調把連接的狀態傳送到framework層。
說明2: 在WifiStateMachine狀態機的構造函數中會有如下代碼:
意思就是當WifiMonitor在發送NETWORK_CONNECTION_EVENT消息的時候,就會用WifiStateMachine的Handler把該消息發送到WifiStateMachine狀態機中。
10 Wifi連接成功後收到的回調:
SupplicantStaIfaceHalCallback的onStateChanged 會執行如下代碼:
這裡實際上就是調用了WifiMonitor的 broadcastNetworkConnectionEvent發送了一條NETWORK_CONNECTION_EVENT的消息,包含了NetworkId和bssid
前面也說過這條消息是由WifiStateMachine狀態機來處理的。
11 WifiStateMachine處理NETWORK_CONNECTION_EVENT消息:
mLastNetworkId:保存當前連接的Wifi的NetworkId
mLastBssid:保存當前連接的Wifi的BSSID
mWifiInfo:保存當前連接的Wifi一些信息,應用可以通過WifiManager的介面getConnectionInfo來獲取。
這裡主要工作如下:
1 更新WifiStateMachine中保存的當前連接的Wifi信息。
2 調用WifiConfigManager的介面保存或更新WiFiConfiguration信息。
3 最後調用sendNetworkStateChangeBroadcast函數發出,網路狀態改變的廣播NETWORK_STATE_CHANGED_ACTION
到這裡整個Wifi的連接和狀態的通知都分析完了。
TAG:一個人的Android |