Android P WiFi 鏈接以及獲取 IP 流程

wifi 鏈接&獲取IP 流程圖

- Android 每一次版本迭代與更新,對於設備開發商來講都是挺痛苦的一件事,不少的東西須要移植,須要適配,
 - 年復一年,日復一日,bug不停,需求不停,儘管再累也是將一些重要的東西記錄下來,分享給到你們,
 - 但願大家遇到相關問題,順着流程圖以及代碼主線,找到緣由(解決問題),
 - 老三樣,先上流程圖

在這裏插入圖片描述

代碼流程

1、關聯階段

1. WifiSettings.submit – > WifiManager

  • WifiSettings 乾的事情比較簡單,當在dialog完成ssid 以及密碼填充後,直接call WifiManager save 便可
  • WifiManager 收到Save 以後,就開始了wifi 鏈接之旅
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
void submit(WifiConfigController configController){
	... 
	mWifiManager.save(config, mSaveListener);
}

2. WifiSettings.submit – > WifiManager

  • WifiManager 這裏至關於傳達室,信件到了,而後按個鈴鐺,把信息傳達給WifiSerivceImpl
  • 主要是將SAVE_NETWORK 給到 WifiService(WifiServiceImpl 是真正幹活的)
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
public void save(WifiConfiguration config, ActionListener listener) {
    getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
}

3. WifiServiceImpl --> WifiStateMachine

  • WifiServiceImpl又將 SAVE_NETWORK 送到中級cmd處理站: WifiStateMachine
  • 這裏擴展一下,如咱們的移除熱點(其實也經過Settings 將remove cmd 送到WifiServieImpl進行下一步傳輸)
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
private class ClientHandler extends WifiHandler {
	case WifiManager.SAVE_NETWORK:
	{
		mWifiStateMachine.sendMessage(Message.obtain(msg));
}
}

4. WifiStateMachine–> WifiStateMachine

  • 從save network 鏈接熱點
  • 又一次轉化, 轉爲CMD_START_CONNECT送到內部狀態機(ConnectModeState )處理
  • 送到WifiNative 進行處理Connect,回顧以上(Android 基本套路大框架仍是不變的: apps – services – native – drv(kernel))
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
public void startConnectToNetwork(int networkId, int uid, String bssid) {
	sendMessage(CMD_START_CONNECT, networkId, uid, bssid);
}

class ConnectModeState extends State {
	case WifiManager.SAVE_NETWORK:
	   startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);// 鏈接熱點
	case CMD_START_CONNECT:
		mWifiNative.connectToNetwork(mInterfaceName, config); // 轉到wifiNative 進行connect 
}

5. WifiNative–> SupplicantStaIfaceHal --> WifMonitor

  • SupplicantStaIfaceHal 添加網絡,select (實則將connect 傳給到 wpa_supplicant)
  • wpa_supplicant完成一系列與路由器的之間的beacon幀(probe、assoc、4way-handshake 、group-handshake)後,再能取到路由器的頒發的承認證(既是拿到最後的compelted)
  • 最後,經過wifiMonitor上報wpa_supplicant 任務已完成,既是完成鏈接的第一階段(關聯階段)
  • WiFiMonitor上報的事件既是,NETWORK_CONNECTION_EVENT (又一次回到WifiStateMachine)
frameworks/opt/net/wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
 public boolean connectToNetwork(@NonNull String ifaceName, @NonNull WifiConfiguration config)
{
	  Pair<SupplicantStaNetworkHal, WifiConfiguration> pair =
                      addNetworkAndSaveConfig(ifaceName, config);
	 networkHandle.select(); 
}

public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,ArrayList<Byte> ssid) {
	if (newSupplicantState == SupplicantState.COMPLETED){
		mWifiMonitor.broadcastNetworkConnectionEvent(mIfaceName, getCurrentNetworkId(mIfaceName), bssidStr);
	}
}

2、獲取IP 階段

6. WifMonitor --> WifiStateMachine

  • 由5的NETWORK_CONNECTION_EVENT 事件上報,又一次回到了WifiStateMachine
  • 並且仍是在ConnectModeState 狀態機裏,爲啥?(又回到這裏)
  • 由於,1~5步只完成了關聯,還有最後一步(要獲取IP),拿到IP後才能算是一個有證的男人,
  • 革命還沒有成功,苦逼仍要繼續(且看下面是如何獲取IP …)
  • 先是,廣而告知(已取得真經),而後立馬切換到mObtainingIpState狀態機
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
class ConnectModeState extends State {
	case WifiMonitor.NETWORK_CONNECTION_EVENT:
		.... 
		sendNetworkStateChangeBroadcast(mLastBssid);
		transitionTo(mObtainingIpState);
}

7. WifiStateMachine.ObtainingIpState

  • ObtainingIpState 獲取IP 的流程中規中矩,先是update 系統的State
  • 停掉IpClient (自從Android N 後,獲取IP已廢棄了dhcpd,扶持了另外一位的IpClient 、IpManager來完成本身的事業 )
  • 清掉bssid以免其影響到漫遊致使斷鏈
  • Ipclient 開始接管舞臺(啓動獲取IP), 後面有空(將把這部分詳細講講的dhcp 協議以及常見的dhcp 問題),敬請期待
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
class ObtainingIpState extends State {
	... 
	setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
	clearTargetBssid("ObtainingIpAddress");
	stopIpClient();
	mIpClient.setHttpProxy(currentConfig.getHttpProxy());
	IpClient.buildProvisioningConfiguration(); 
	.... 
}
相關文章
相關標籤/搜索