//
怎样Wifi 与 4G 同时使用?
智能切换 同时是不可能的
设置-开发者选项- |
//
需求:通过4g访问外网,同时通过wifi访问内网。
android系统默认情况下,wifi连网时,4g数据链接会被强制断开,但实际有需要wifi和4g同时上网,为了满足这个要求,需要修改android的网络管理机制。
首先实现wifi连网时,不让4g数据链接被强制断开:
修改 frameworks/base/services/core/java/com/android/server/ConnectivityService.java
private void teardownUnneededNetwork(NetworkAgentInfo nai) {
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest nr = nai.networkRequests.valueAt(i);
// Ignore listening requests.
if (!isRequest(nr)) continue;
loge("Dead network still had at least " + nr);
break;
}
//nai.asyncChannel.disconnect();
}
把nai.asyncChannel.disconnect(); 行mark掉。
这样wifi连网,4g数据链接不会被强制断开了。
$ netcfg
rmnet0 UP 0.0.0.0/0 0x00000041 00:00:00:00:00:00
r_rmnet_data8 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data0 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data0 UP 10.66.94.93/30 0x00000041 00:00:00:00:00:00
rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
wlan0 UP 192.168.10.10/24 0x00001043 34:87:3d:31:e4:77
sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00
p2p0 UP 0.0.0.0/0 0x00001003 36:87:3d:31:e4:77
lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
dummy0 DOWN 0.0.0.0/0 0x00000082 d6:d1:38:38:ed:c8
但此时,网络访问默认还是走wifi通道,把wifi AP与外网断开,ping下192.168.10.1可以ping通,但www.baidu.com会发现ping不通,
指定network,再ping
ping -I rmnet_data0 www.baidu.com
会发现可以ping通,说明此时wifi和4g都已经连上网了。
APP程序可以通过setProcessDefaultNetwork把进程和network绑定来访问特定网络。但我们的要求是一个APP有的数据走wifi有的数据走4g,不希望APP和某个network绑定,这样就是要求默认走4g上网,访问内网ip则走wifi.即修改系统让4g的优先级优于wifi,修改route rule,使得访问内网ip时,则走wifi.
修改系统让4g的优先级优于wifi:
android5.1是依据网络评分来评定网络的优先级,默认情况下,wifi的评分比4g高。可以修改
frameworks/base/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
private int getCurrentScore(boolean pretendValidated) {
// TODO: We may want to refactor this into a NetworkScore class that takes a base score from
// the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
// score. The NetworkScore class would provide a nice place to centralize score constants
// so they are not scattered about the transports.
if(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return 150;
}
int score = currentScore;
if (isCneWqeEnabled) return score;
if (!everValidated && !pretendValidated) score -= UNVALIDATED_SCORE_PENALTY;
if (score < 0) score = 0;
if (networkMisc.explicitlySelected) score = EXPLICITLY_SELECTED_NETWORK_SCORE;
return score;
}
把4g网络评分强制改为150,这样可以确保总是大于wifi网络的评分。
更新系统,ping www.baidu.com可以ping通,说明此时系统优先走4g网络(wifi AP与外网断开)。 ping 192.168.10.1 不通。
修改route rule:
查看默认route rule:
ip rule
0: from all lookup local
10000: from all fwmark 0xc0000/0xd0000 lookup 99
13000: from all fwmark 0x10063/0x1ffff lookup 97
13000: from all fwmark 0x10064/0x1ffff lookup 1022
13000: from all fwmark 0x10065/0x1ffff lookup 1005
14000: from all oif wlan0 lookup 1022
14000: from all oif rmnet_data0 lookup 1005
15000: from all fwmark 0x0/0x10000 lookup 99
16000: from all fwmark 0x0/0x10000 lookup 98
17000: from all fwmark 0x0/0x10000 lookup 97
19000: from all fwmark 0x64/0x1ffff lookup 1022
19000: from all fwmark 0x65/0x1ffff lookup 1005
22000: from all fwmark 0x0/0xffff lookup 1005
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000: from all unreachable
尝试添加一条route rule:
ip rule add to 192.168.10.0/24 table wlan0 pref 100
修改后route rule:
0: from all lookup local
100: from all to 192.168.10.0/24 lookup 1022
10000: from all fwmark 0xc0000/0xd0000 lookup 99
13000: from all fwmark 0x10063/0x1ffff lookup 97
13000: from all fwmark 0x10064/0x1ffff lookup 1022
13000: from all fwmark 0x10065/0x1ffff lookup 1005
14000: from all oif wlan0 lookup 1022
14000: from all oif rmnet_data0 lookup 1005
15000: from all fwmark 0x0/0x10000 lookup 99
16000: from all fwmark 0x0/0x10000 lookup 98
17000: from all fwmark 0x0/0x10000 lookup 97
19000: from all fwmark 0x64/0x1ffff lookup 1022
19000: from all fwmark 0x65/0x1ffff lookup 1005
22000: from all fwmark 0x0/0xffff lookup 1005
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000: from all unreachable
这样就可以直接ping 通192.168.10.1了。
APP程序没有修改route rule的权限,我们想让系统在wifi连接AP后自动添加需要的一条route rule.
可以修改netd (system/netd/server/),netd有权限修改route rule.