rk3399 wifi和eth0共存 调试
时间:2022-07-24
本文章向大家介绍rk3399 wifi和eth0共存 调试,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
需求
项目中Android 板通过有线连接poe摄像头, android app通过wifi跟外部通讯。采用的Android 8.1的代码。
网上搜索发现有不少实现该功能的文章,不过文章都有一些差异,对于不了解这些模块的人来说会不知道应该修改哪个。这里只简单记录下我的调试记录,还没深究
现象
这边照着网上几篇文章修改后,出现的现象是:eth0 处于Running的状态时, 去重连wifi, wifi只会显示saved,不会继续走configure流程
调试
- 最常见的的方法就是通过打印去了解信息,把涉及到NetworkFactory 和ConnectivityService的打印都打开
- 没有连接eth0时点击wifi连接的打印
09-03 01:59:40.998 465 561 D WifiStateMachine: connectToUserSelectNetwork netId 3, uid 1000, forceReconnect = false
09-03 01:59:41.033 465 561 D WifiStateMachine: CMD_START_CONNECT sup state DisconnectedState my state DisconnectedState nid=3 roam=false
09-03 01:59:43.300 465 561 D WifiStateMachine: CMD_START_CONNECT sup state ScanState my state DisconnectedState nid=3 roam=false
09-03 01:59:45.650 465 561 E WifiStateMachine: L2ConnectedState enter
- eth0处于running时,点击wifi连接的打印
09-03 02:02:47.526 465 561 D WifiStateMachine: connectToUserSelectNetwork netId 4, uid 1000, forceReconnect = false
09-03 02:02:47.564 465 561 E WifiStateMachine: CMD_START_CONNECT but no requests and not connected, bailing
由打印的差异 跟踪到代码 frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
case CMD_START_CONNECT:
/* connect command coming from auto-join */
netId = message.arg1;
int uid = message.arg2;
bssid = (String) message.obj;
synchronized (mWifiReqCountLock) {
if (!hasConnectionRequests()) {
loge("hasConnectionRequests :......");
if (mNetworkAgent == null) {
loge("CMD_START_CONNECT but no requests and not connected,"
+ " bailing");
break;
} else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
loge("CMD_START_CONNECT but no requests and connected, but app "
+ "does not have sufficient permissions, bailing");
break;
}
}
}
config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId);
logd("CMD_START_CONNECT sup state "
+ mSupplicantStateTracker.getSupplicantStateName()
+ " my state " + getCurrentState().getName()
+ " nid=" + Integer.toString(netId)
+ " roam=" + Boolean.toString(mIsAutoRoaming));
if (config == null) {
loge("CMD_START_CONNECT and no config, bail out...");
break;
}
private boolean hasConnectionRequests() {
return mConnectionReqCount > 0 || mUntrustedReqCount > 0;
}
从打印和代码分析,两个流程的差异主要在hasConnectionRequests这个函数
- 接下来主要跟踪hasConnectionRequests 从代码查到主要问题在mConnectionReqCount这个变量,所以查找修改这个变量的地方,还好只有两处:
@Override
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
synchronized (mWifiReqCountLock) {
loge("needNetworkFor mConnectionReqCount="+ mConnectionReqCount);
if (++mConnectionReqCount == 1) {
if (mWifiConnectivityManager != null && mUntrustedReqCount == 0) {
mWifiConnectivityManager.enable(true);
}
}
}
}
@Override
protected void releaseNetworkFor(NetworkRequest networkRequest) {
synchronized (mWifiReqCountLock) {
loge("releaseNetworkFor mConnectionReqCount="+ mConnectionReqCount);
Exception e = new Exception("log");
e.fillInStackTrace();
loge("Called: " , e);
if (--mConnectionReqCount == 0) {
if (mWifiConnectivityManager != null && mUntrustedReqCount == 0) {
mWifiConnectivityManager.enable(false);
}
}
}
}
为了能知道对这个变量的调用流程,一个简单的方法就是利用Exception打印出堆栈信息 Exception e = new Exception("log"); e.fillInStackTrace(); loge("Called: " , e);
- 堆栈打印信息忘记记下来了,这里只记下最后修改的地方 frameworks/base/core/java/android/net/NetworkFactory.java
private void evalRequest(NetworkRequestInfo n) {
if (VDBG) log("evalRequest");
Log.e("NetworkFactory", "evalRequest n.score:" + n.score + ", mScore:" + mScore);
if (n.requested == false && n.score < mScore &&
n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) && acceptRequest(n.request, n.score)) {
if (VDBG) log(" needNetworkFor");
needNetworkFor(n.request, n.score);
n.requested = true;
} else if (n.requested == true &&
(n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
if (VDBG) log(" releaseNetworkFor");
releaseNetworkFor(n.request);
n.requested = false;
} else {
if (VDBG) log(" done");
}
}
将下面两行注释掉 //releaseNetworkFor(n.request); //n.requested = false;
最终修改的地方有3处:
- 写一个启动脚本,在系统启动时配置eth0, ip地址与wifi不在同一个网断
ip route add 192.168.11.0/24 dev eth0 proto static table local_network
ip route flush cache
sleep 5s
ifconfig eth0 192.168.11.120
- 修改frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
private static final int NETWORK_SCORE = 30; //70;
- 修改frameworks/base/core/java/android/net/NetworkFactory.java 注释掉
//releaseNetworkFor(n.request);
//n.requested = false;
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel Task Scheduling(任务调度)在windows下的使用详解
- PHP 7.4中使用预加载的方法详解
- PHP设计模式之工厂模式(Factory)入门与应用详解
- Laravel 实现Controller向blade前台模板赋值的四种方式小结
- Referer原理与图片防盗链实现方法详解
- Laravel 简单实现Ajax滚动加载示例
- PHP设计模式之解释器(Interpreter)模式入门与应用详解
- Laravel 实现在Blade模版中使用全局变量代替路径的例子
- PHP实现关键字搜索后描红功能示例
- 如何在CentOS中安装PHP7.4的方法步骤
- Linux安装Python3如何和系统自带的Python2并存
- Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
- PHP学习记录之常用的魔术常量详解
- laravel orm 关联条件查询代码
- PHP实现财务审核通过后返现金额到客户的功能