硬件:rk3588
软件:Android 12
问题描述:系统时间不正确时,wifi连接异常,提示网络连接受限。无法上网。
分析过程:
系统时间方向
1. 查看报错信息
12-12 12:19:47.956 607 3951 D NetworkMonitor/105: PROBE_HTTPS https://www.google.cn/generate_204 Probe failed with exception javax.net.ssl.SSLHandshakeException: Chain validation failed
这个报错表示系统时间不在访问的地址的有效期内
1.1 通过谷歌浏览器查看网站时间
www.google.cn的有效期为2024.01.29-2024.04.22
1.2 通过date命令查看系统时间
rk3588_s:/ # date
Tue Dec 12 12:12:14 CST 2023
系统时间不在有效期内,将系统时间改为有效期内后,wifi连接正常。
系统时间的来源可以参考Android系统时间获取分析-CSDN博客,因为rtc硬件设计缺陷,导致每次开机后,使用软件版本编译时间作为系统时间,随着时间推移,当www.google.cn的有效期更新后,系统时间不在其有效期内,就会暴露问题。
路由器方向
使用开发板进行对比测试,将系统时间改到有效期以外,发现开发板依然可以正常连接wifi
对比log,过程很艰辛,还走了弯路,最终发现开发板进行了网络切换,而项目机没有切换
项目机异常
12-12 12:19:47.611 607 718 D ConnectivityService: NetReassign [no changes]
开发板正常
12-12 12:31:41.262 613 818 D ConnectivityService: NetReassign [67 : 100 → 101, 15 : 100 → 101, 69 : 100 → 101, 18 : 100 → 101, 42 : 100 → 101, 38 : 100 → 101, 29 : 100 → 101, 64 : 100 → 101, 20 : 100 → 101, 34 : 100 → 101, 25 : 100 → 101, 27 : 100 → 101, 23 : 100 → 101, 7 : 100 → 101, 1 : 100 → 101, 40 : 100 → 101]
12-12 12:31:41.264 613 818 D ConnectivityService: Switching to new default network for: uid/pid:1000/613 activeRequest: 1 callbackRequest: 1 [NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_VCN_MANAGED RequestorUid: 1000 RequestorPkg: android] ]] callback flags: 1 priority: 2147483647 using NetworkAgentInfo{network{101} handle{437197393933} ni{WIFI CONNECTED extra: } Score(60 ; KeepConnected : 0 ; Policies : TRANSPORT_PRIMARY&IS_UNMETERED&EVER_USER_SELECTED) explicitlySelected lp{{InterfaceName: wlan0 LinkAddresses: [ fe80::11d8:bab:fe0b:fecb/64,192.168.0.3/24 ] DnsAddresses: [ /192.168.0.1 ] Domains: null MTU: 0 ServerAddress: /192.168.0.1 TcpBufferSizes: 524288,1048576,2097152,262144,524288,1048576 Routes: [ fe80::/64 -> :: wlan0 mtu 0,192.168.0.0/24 -> 0.0.0.0 wlan0 mtu 0,0.0.0.0/0 -> 192.168.0.1 wlan0 mtu 0 ]}} nc{[ Transports: WIFI Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=12000Kbps LinkDnBandwidth>=30000Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="Zkjlwifi", BSSID=8c:46:27:82:97:a3, band=1, mMatchLocalOnlySpecifiers=false]> TransportInfo: <SSID: "Zkjlwifi", BSSID: 8c:46:27:82:97:a3, MAC: b4:6d:c2:45:c2:7e, Security type: 2, Supplicant state: COMPLETED, Wi-Fi standard: 4, RSSI: -49, Link speed: 72Mbps, Tx Link speed: 72Mbps, Max Supported Tx Link speed: 72Mbps, Rx Link speed: -1Mbps, Max Supported Rx Link speed: 72Mbps, Frequency: 2447MHz, Net ID: 0, Metered hint: false, score: 60, CarrierMerged: false, SubscriptionId: -1, IsPrimary: 1> SignalStrength: -49 OwnerUid: 1000 AdminUids: [1000] SSID: "Zkjlwifi"]}}
找到对应代码
packages\modules\Connectivity\service\src\com\android\server\ConnectivityService.java
public String toString() {
final StringJoiner sj = new StringJoiner(", " /* delimiter */,
"NetReassign [" /* prefix */, "]" /* suffix */);
if (mReassignments.isEmpty()) return sj.add("no changes").toString();
for (final RequestReassignment rr : getRequestReassignments()) {
sj.add(rr.toString());
}
return sj.toString();
}
跟踪代码找到mReassignments添加的地方
packages\modules\Connectivity\service\src\com\android\server\ConnectivityService.java
private NetworkReassignment computeNetworkReassignment(
@NonNull final Collection<NetworkRequestInfo> networkRequests) {
final NetworkReassignment changes = new NetworkReassignment();
// Gather the list of all relevant agents.
final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
if (!nai.everConnected) {
continue;
}
nais.add(nai);
}
for (final NetworkRequestInfo nri : networkRequests) {
// Non-multilayer listen requests can be ignored.
if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
continue;
}
NetworkAgentInfo bestNetwork = null;
NetworkRequest bestRequest = null;
for (final NetworkRequest req : nri.mRequests) {
bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier());
// Stop evaluating as the highest possible priority request is satisfied.
if (null != bestNetwork) {
bestRequest = req;
break;
}
}
if (null == bestNetwork && isDefaultBlocked(nri)) {
// Remove default networking if disallowed for managed default requests.
bestNetwork = mNoServiceNetwork;
}
if (nri.getSatisfier() != bestNetwork) {
// bestNetwork may be null if no network can satisfy this request.
changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
}
}
return changes;
}
添加日志,发现,获取的bestNetwork,一直都是 ETHERNET, 想起来项目机内置了路由器,关闭有线网后,wifi可以连接,和开发板现象一致。
rk3588_s:/ # ifconfig eth0 down
解决方法
从上面的分析可知,当上面的两种情况同时存在时,才会出现连接异常的问题,所以解决其中一个即可。
1. 修正系统时间
当连接wifi时,即便连接受限,也可以获取互联网时间,日志如下
12-12 12:19:47.950 607 3952 D NetworkMonitor/105: PROBE_HTTP http://www.google.cn/generate_204 time=253ms 22ret=204 22request={Connection=[close], User-Agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.32 Safari/537.36]} 22headers={null=[HTTP/1.1 204 No Content], Connection=[close], Content-Length=[0], Cross-Origin-Resource-Policy=[cross-origin], Date=[Wed, 21 Feb 2024 02:07:21 GMT], X-Android-Received-Millis=[1670818787949], X-Android-Response-Source=[NETWORK 204], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1670818787779]}
其中的时间字段 “Date=[Wed, 21 Feb 2024 02:07:21 GMT]”, 只要把这个时间设置给系统时间即可。
2. 使用wifi做bestNetwork
如果获取的bestNetwork为ETHERNET,而且bestNetwork.lastValidated == false,就在nais中找WIFI,如果找到,就将bestNetwork替换成wifi。
网线连接问题
后来测试,又发现,插入网线时,连接受限,实际能上网,只是状态不对。
原因是项目机内部有路由器,当给机器插入网线时,实际时路由器的wan口接入网线。机器侧虽然可以上网,但是没有触发网络变化,所以不会触发时间更新。所以网落还是处于validation fail的状态。而没有触发条件,默认的自动更新时间的周期为1天,所以把这个时间修改成一分钟,可以解决问题。
frameworks/base/core/res/res/values/config.xml
<integer name="config_ntpPollingInterval">86400000</integer>