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 此功能的 命令 如何嵌入到系统以及撤销这个功能怎么做。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(android,thernet,wifi,ap,同一网段,网桥)