Android 乙太網轉 WiFi 熱點 (並在同一網段 192.168.0.xx)
命令如下:
首先開啟盒子的 wifi 熱點功能,再用以下命令
ip link set eth0 up;
ip link add eth1 type bridge ; ip link set eth0 master eth1;
busybox ifconfig eth0 0.0.0.0
ip link set wlan0 master eth1
busybox ifconfig wlan0 0.0.0.0
ip link set eth1 down;ip link set eth1 up;
/system/bin/iptables -F
/system/bin/iptables -X
/system/bin/iptables -t nat -F
同時,系統層要改兩個地方
1 frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
// If we don't already have an interface, and if this interface matches
// our regex, start tracking it.
- if (!iface.matches(mIfaceMatch) || isTrackingInterface())
+ Log.d(TAG, "edit by Wade Started tracking interface " + iface + " " + isTrackingInterface());
+ if (!iface.matches("eth1") || isTrackingInterface())
2 device/rockchip/common/init.rockchip.rc
加一個 service
service dhcpcd_eth1 /system/bin/dhcpcd -aABDKL
class late_start
disabled
oneshot
分析和說明。
1.命令分析:
發現路由不對( ping -I eth1 閘道器 okay, ping 閘道器 no okay),就加了一條,busybox route add default gw 192.168.0.1 dev eth1 ,路由對了。可以ping 通
路由對了,ping 171.90.249.254 ( ping IP 可以,但是域名不行)。網上找資料用android 的 ndc resolver setnetdns ppp0 8.8.8.8 8.8.4.4 解決問題。
自此,盒子 ping 外網可以了。
ping 沒有問題,但是在 機子上用瀏覽器卻上不了網,
隨便找了一個 app ,加了一個測試程式碼來測試是否有 dns 或者 interface:
public void onClick(View v) {
System.out.println("test by Wade get dns test !");
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
for(Network network :connectivityManager.getAllNetworks())
{
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
if (networkInfo.isConnected()) {
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
linkProperties.getDnsServers().toString();
System.out.println("test by Wade get dns test !" + linkProperties.getDnsServers().toString());
System.out.println("test by Wade get interface test !" + linkProperties.getInterfaceName().toString());
System.out.println("test by Wade get interface test !" + linkProperties.getAllInterfaceNames().toString());
}
}
}
發現在 eth1 (網橋,我把 br0 改成了 eth1)的時候.. interface 為空,也就是 android 認為沒有聯網。
改為 eth1 的原因是猜測 android 會根據命令來處理網路連線。
後在網上偶然看到 ./frameworks/base/core/res/res/values/config.xml 裡的 config_ethernet_iface_regex 是乙太網的匹配,於是往下查
在 frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java 裡 mIfaceMatch 的 matches,導致只能增加 eth0 這個介面,隨做
了相應的改動。
在修改後發現
01-01 12:02:34.701 462-1996/system_process D/NetUtils: dhcp_do_request failed : eth1 (new)
01-01 12:02:34.701 462-1996/system_process E/EthernetNetworkFactory: DHCP request error:Timed out waiting for dhcpcd to start
跟程式碼發現 dhcpcd_eth1 這個服務沒有,在 init.rc 里加上後就可以了。
到這個時候,瀏覽器可以上網了,但是上網的網絡卡是我們虛擬出來的網橋eth1, linkProperties.getInterfaceName().toString()) 也可以看到 eth1 了。
2 確認了一些東西
比如 ifconfig 等命令的實際是改了核心的一些狀態,核心再通過 kobject_event 的方式傳給上層, 網路層用 netlink 等實現對核心 event 的接收,進而知道其狀態
再比如 android 系統對網路ethernet 的處理,不是按命令來的,有他自己的一套:比如檢測到了有新的網絡卡後,他自己會實現 dhcpcd , dns 等網路資訊的獲取。如果遮蔽了 EthernetNetworkFactory.java 的一些東西。用命令配置 eth0 到能 Ping 能 wget ,在瀏覽器中還是不能上網
3:產品化
我只是把功能實現,如果要做成產品,還有一些路要走:
1 沒做熱點之前,如何保證 eth0 正常功能。
2 如 eth0 ,eth1 重寫一個 類似 EthernetNetworkFactory.java 的class 來處理,比如 ppp0 這樣的介面
3 在實現功能後,我再手動開關 wlan0 ,會一直報錯,怎麼解決。
4 此功能的 命令 如何嵌入到系統以及撤銷這個功能怎麼做。