Android P WiFi的 Disconnect 流程 汇总

文章目录

    • WiFi 断开Flow框架
      • 1. wifi 断开原因总结
      • 2. wifi 断开处理流程
    • 代码流程
      • 1. wpa_supplicant 部分
      • 2. wpa_supplicant --> hidl --> SupplicantStaIfaceHal
      • 3. WifiMonitor --> WifiStateMachine --> 广播通知系统

WiFi 断开Flow框架

设备WiFi 断开的原因有多种多样,但断开流程大体不变;
所以遇到wif i断开问题不要慌,不要慌,本文将毫无保留分享处理断开问题思路,
这里抛砖引玉,给你们走出困境中一些实用的指南tips。
还是老三样,先上流程图

  • 春江水暖鸭先知,同样的wifi断开 drv先知
  • wlan drv 在与路由器连接的时候(未断开时),私下里面会有周期性的beacon帧来维持地下恋情,AP端一旦遇到突发事项,通过的特殊暗号(802.11 协议,deauth 帧/ reject帧等)立刻通知到drv;
  • wlan drv 一旦收到暗号后,马上独善其身(断开与AP端的链接),撇清与AP的关系,宣布自己的净身而立;
  • 紧接着,wlan drv 后援部队(wifiStateMachine 内部广播通知系统外部网络环境),系统跟Settins开始同步处理断开的烂摊子;
  • 后面有时间将详细解读断开暗号(关于802.11协议),敬请期待。

1. wifi 断开原因总结

Android P WiFi的 Disconnect 流程 汇总_第1张图片

2. wifi 断开处理流程

Android P WiFi的 Disconnect 流程 汇总_第2张图片

代码流程

1. wpa_supplicant 部分

  • wpa_driver_nl80211_drv_init 其核心完成与drv 通道绑定(既是与drv建立好暗号信息交流通道),一旦有变化及时通风报信
  • nl80211_init_bss埋下的是第一步棋,监听(解读)bss 802.11 数据帧
  • process_bss_event 专门处理802.11 数据帧,将之送往到mlme_event处理,mlme完成分拣之后,装往wpa_supplicant_event大车上
  • wpa_supplicant_event大车把每个event 送到对应的cmd中心处理站,进行卸货进一步分发处理,处理完后通过wpas_notify_state_changed上报给wpas_hidl_notify_state_changed
  • wpas_hidl_notify_state_changed完成接力赛最后一棒,将事件上报给到SupplicantStaIfaceHal
  • 这里,断开的所有原因(将在wpa_supplicant_event 函数里可以找到),结合drv 行为 + 空中包
external/wpa_supplicant_8/hostapd/src/drivers/driver_nl80211.c
static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,void *global_priv, int hostapd,const u8 *set_addr,
const char *driver_params){
	if (nl80211_init_bss(bss))
		goto failed;
}
static int nl80211_init_bss(struct i802_bss *bss)
{
	... 
	 nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,process_bss_event, bss);
}

external/wpa_supplicant_8/src/drivers/driver_nl80211_event.c
int process_bss_event(struct nl_msg *msg, void *arg)
{
		switch (gnlh->cmd) {
		case NL80211_CMD_FRAME:
		case NL80211_CMD_FRAME_TX_STATUS:
		mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
		   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
		   tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
		   tb[NL80211_ATTR_COOKIE],
		   tb[NL80211_ATTR_RX_SIGNAL_DBM],
		   tb[NL80211_ATTR_STA_WME]);
	break;
}

external/wpa_supplicant_8/wpa_supplicant/events.c
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,union wpa_event_data *data)
{
	case EVENT_AUTH: 
	case .... 
	...
}

wpa_supplicant_set_state --wpa_supplicant.c
	wpas_notify_state_changed	-- hidi_manager.cpp
		wpas_hidl_notify_state_changed	-- hidl.cpp
		

2. wpa_supplicant --> hidl --> SupplicantStaIfaceHal

  • wpa_supplicant把接力棒交给了 wpa_supplicant下面的 hidl.cpp,由他来完成事件的上报以及通知WifiMonitor
  • 仍然是老套路,自从Android 的版本升级之后,cpp 与 java 之间的通信也是在不断变化,从之前的aidl到现在的hidl,总是在变(作为程序员只有不断主动积极适应变化,不然饭碗不保)
  • SupplicantStaIfaceHal 收到上报事件之后,通知这一长期合作伙伴WiFiMonitor,将消息通知到系统各个模块
external/wpa_supplicant_8/wpa_supplicant/hidl/1.1/hidl.cpp
{
	.... 
	hidl_manager->notifyStateChange(wpa_s);
}

external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/hidl_manager.cpp
{
	....
	callWithEachStaIfaceCallback(
    wpa_s->ifname, std::bind(
		       &ISupplicantStaIfaceCallback::onStateChanged,
		       std::placeholders::_1,
		       static_cast(
			   wpa_s->wpa_state),
		       bssid, hidl_network_id, hidl_ssid));
}

frameworks/opt/net/wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
	 public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,ArrayList ssid) {
 		mWifiMonitor.broadcastSupplicantStateChangeEvent( mIfaceName, 
 			getCurrentNetworkId(mIfaceName), wifiSsid, bssidStr, 		newSupplicantState);
 }

3. WifiMonitor --> WifiStateMachine --> 广播通知系统

  • WifiMonitor 传输 SUPPLICANT_STATE_CHANGE_EVENT cmd 给到wifiStateMachine;
  • WifiStateMachine是cmd 核心处理枢纽,每个wifi 相关的cmd 都会送到这里被分发执行;
  • 这里重点有DisconnectingState 与ConnectModeState 状态机,将会根据wpa_supplicant 所处的状态(disconnect 或者 completed状态),处理行为不一样
  • 如为disconnect ,则转到handleNetworkDisconnect();处理; 如为completed,则开启ip gaining;
  • 最后点好狼烟(发广播WifiManager.NETWORK_STATE_CHANGED_ACTION),通知远方的联盟兄弟危险来了(wifi 状态发生变化了),处理&同步断开的状态flow
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMonitor.java
public void broadcastSupplicantStateChangeEvent(String iface, int networkId, WifiSsid wifiSsid,....)
{
 		sendMessage(iface, SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,new StateChangeResult(networkId, wifiSsid, bssid, newSupplicantState));
}

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
class ConnectModeState extends State {
{
     .....  
	 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
	 	SupplicantState state = handleSupplicantStateChange(message);
	 	 if (state == SupplicantState.DISCONNECTED
				   && mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
			   if (mVerboseLoggingEnabled) {
				   log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
			   }
			   handleNetworkDisconnect();
			   transitionTo(mDisconnectedState);
		   }
		   
		if (state == SupplicantState.COMPLETED) {
	       mIpClient.confirmConfiguration();
	       mWifiScoreReport.noteIpCheck();
	   }
}

 class DisconnectingState extends State {
	   case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
	   	handleNetworkDisconnect();
	   	transitionTo(mDisconnectedState);
}


你可能感兴趣的:(Android)