Android WiFi的断开分析

news2024/11/30 14:36:36

1.wifi断开大体流程:

1.wifi断开 wlan-driver最先知道。

2.wlan-driver在与路由器连接的时候(未断开时), 会有周期性的beacon帧来维持连接,AP端一旦遇到突发事情,会立刻通过802.11协议的 deauth 帧/ reject 帧等 通知到 driver。

3. wlan-driver一旦收到802协议的 deauth帧/reject帧等后,马上断开与AP的连接。

4. 紧接着,wlan-driver的上层WifiStateMachine内部广播通知系统外部网络环境,系统跟Settings开始同步处理此次的断开。

2.wifi断开原因

3.wifi断开流程

4.代码流程

1. wpa_supplicant 部分

  • wpa_driver_nl80211_drv_init 其核心完成与drv通道绑定(既是与driver建立好暗号信息交流通道),一旦有变化及时通风报信
  • 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 函数里可以找到),结合 driver行为和空中包
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<ISupplicantStaIfaceCallback::State>(
			   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<Byte> 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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1253440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算器的模拟实现

计算器的模拟实现 一、实验题目&#xff1a;计算器二&#xff1a;实验目的&#xff1a;三&#xff1a;实验内容与实现1&#xff1a;【实验内容】2&#xff1a;【实验实现】1.计算器界面的实现&#xff0c;如下图所示&#xff1a;2&#xff1a;各项功能的实现&#xff0c;如下图…

canvas版放大镜

效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>放大镜</title><st…

C++ vector迭代器失效

STL中vector迭代器失效常见错误写法示例 最近在看STL容器失效的例子&#xff0c;涉及到vector数组迭代器失效的问题&#xff0c;如果不注意使用&#xff0c;很容易出现问题&#xff0c;我们先来看一下一个简单的示例程序&#xff0c;在数组nums中删除大于50的元素&#xff0c;…

运维高级-day01

shell回顾 1、快速生成版权控制信息&#xff0c;具体的内容自己替换 [root scripts]# cat ~/.vimrc autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()" func SetTitle() if expand("%:e") sh call setline(1,"#!/bin/bash")…

【数据库篇】关系模式的表示——(2)规范化

范式&#xff1a;范式是符合某一种级别的关系模式的集合 规范化&#xff1a;是指一个低一级的范式的关系模式&#xff0c;通过模式的分解转换为若干个高一级范式的关系模式的集合。 1NF 每个分量必须是不可分开的数据项&#xff0c;满足这个条件的关系模式就是1NF。 2NF 若…

代码随想录算法训练营第四十六天【动态规划part08】 | 139.单词拆分、背包总结

139.单词拆分 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 单词是物品&#xff0c;字符串s是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。 动规五部曲 确定dp数…

②⑩① 【MySQL】什么是分库分表?拆分策略有什么?什么是MyCat?

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 目录 ②⑩① 【MySQL】什么是分库分表&#xf…

定时器/计数器的应用

前言 对近期学习定时器进行简单的记录 参考链接 LED数码管的静态显示与动态显示&#xff08;KeilProteus&#xff09;-CSDN博客 外中断的应用-CSDN博客 【mcuclub】定时器/计数器_定时器/计数器的内部结构和工作方式-CSDN博客 5.图解定时器/计数器 - 知乎 (zhihu.com) 5…

CPU、GPU、TPU内存子系统架构

文章目录 CPU、GPU、TPU内存子系统架构概要CPUGPUTPU共同点和差异&#xff1a; CPU、GPU、TPU内存子系统架构 概要 Memory Subsystem Architecture&#xff0c;图源自TVM CPU CPU&#xff08;中央处理器&#xff09;的内存子系统&#xff1a;隐式管理 主内存&#xff08;…

VMware如何导出和导入镜像OVF虚拟机(以unbuntu为例)

前言&#xff1a;我下载了一个unbuntu的系统镜像&#xff0c;基于这个镜像创建了一个unbuntu的虚拟机&#xff0c;辛辛苦苦配置需要的开发环境&#xff0c;如&#xff1a;安装了mysql&#xff0c;安装了jdk等&#xff0c;此时&#xff0c;我的同事可能需要也是同一套类似环境&a…

视觉CV-AIGC一周最新技术精选(2023-11)

PG-Video-LLaVA: Pixel Grounding Large Video-Language Models https://github.com/mbzuai-oryx/Video-LLaVA将基于图像的大型多模态模型&#xff08;LMM&#xff09;扩展到视频领域是具有挑战性的。最近将基于图像的LMM扩展到视频的方法要么缺乏grounding定位能力&#xff08…

SQL sever2008中的游标

目录 一、游标概述 二、游标的实现 三、优缺点 3.1优点&#xff1a; 3.2缺点&#xff1a; 四、游标类型 4.1静态游标 4.2动态游标 4.3只进游标 4.4键集驱动游标 4.5显示游标&#xff1a; 4.6隐式游标 五、游标基本操作 5.1声明游标 5.1.1.IS0标准语法 5.1.1.1语…

nodejs+vue+python+PHP+微信小程序-书吧租阅管理系统的设计与实现-安卓-计算机毕业设计

在当今高度发达的信息中&#xff0c;信息管理改革已成为一种更加广泛和全面的趋势。为确保中国经济的持续发展&#xff0c;信息时代日益更新&#xff0c;书吧租阅管理系统仍在蓬勃发展。同时&#xff0c;随着信息社会的快速发展&#xff0c;各种管理系统面临着越来越多的数据需…

leetcode刷题日志-15.三数之和

这道题还是有点难度&#xff0c;我能想到的就是三重循环&#xff0c;但是题目限制不能重复&#xff0c;所以这道题三重循环完还要去重&#xff0c;太过于麻烦。看了题解以后&#xff0c;大佬们还是厉害&#xff0c;大概思路是这样子的&#xff1a;先对数组进行排序&#xff0c;…

pandas根据列正逆序排序

题目&#xff1a;根据 buy_quantity 列进行排名&#xff0c;相同值分配相同的最低排名。 import pandas as pd# 创建一个示例 DataFrame data {item_id: [1, 2, 3, 4, 5, 6, 7], buy_quantity: [1, 2, 2, 3, 3, 4, 5]} df pd.DataFrame(data)# 使用 rank() 函数为 buy_quant…

电商数据|淘宝商品数据接口接入|参数|获取商品订单物流|电商数据分析

授权认证 授权不是开放平台对服务商应用的授权 &#xff0c;而是需要开放平台的客户&#xff08;用户&#xff09;对服务商应用的授予&#xff0c;比如ERP应用&#xff0c;也就是淘宝的店铺商家对应用进行授权&#xff0c;使其能够拉取到店铺的订单来完成订单履约。 淘宝授权页…

C++ day39 动态规划 不同路径 不同路径Ⅱ

题目1&#xff1a;62 不同路径 题目链接 &#xff1a;不同路径 对题目的理解 机器人位于m*n的网格中的左上角start,求解走到网格右下角finish的移动路径 动规五部曲 1&#xff09;dp数组的含义以及下标i的含义 dp[i][j]&#xff1a;从start&#xff08;0&#xff0c;0&…

继承性和多态性实验

继承性和多态性实验 一、实验题目二、实验目的三、实验内容与实现1&#xff1a;【实验内容】2:【实验实现】雇员类&#xff08;Employee&#xff09;的实现&#xff0c;如下图所示&#xff1a;2&#xff1a;经理类&#xff08;Manager&#xff09;的实现&#xff0c;如下图所示…

Feast:概念

实体 实体是语义相关特征的集合。用户定义实体以映射其用例的领域。 例如&#xff0c;打车车服务可以将客户和司机作为实体&#xff0c;这些实体将相关特征分组&#xff0c;对应于这些客户和司机。 driver Entity(namedriver, join_keys[driver_id]) # 司机实体 customer E…

⑨【Stream】Redis流是什么?怎么用?: Stream [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ ⑨Redis Stream基本操作命令汇总 一、Redis流 …