初入android驱动开发之网络设备以太网(二)

因为这次用到以太网模块无需自己移植供应商的驱动,只需要在内核中配置选项中加入CONFIG_USB_USBNET=y 即可。

      主要修改的是系统层的代码,这里主要是讲ethernet的流程。

     android4.3 本身是支持以太网的,不过需要修改一些代码。

1. frameworks/base/services/java/com/android/server/ConnectivityService.java

        mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_networkTransitionTimeout);

        mNetTrackers = new NetworkStateTracker[
                ConnectivityManager.MAX_NETWORK_TYPE+1];
        mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];

        mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
        mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];

        // Load device network attributes from resources
        String[] raStrings = context.getResources().getStringArray(
                com.android.internal.R.array.radioAttributes);
        for (String raString : raStrings) {
            RadioAttributes r = new RadioAttributes(raString);
            if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
                loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
                continue;
            }
            if (mRadioAttributes[r.mType] != null) {
                loge("Error in radioAttributes - ignoring attempt to redefine type " +
                        r.mType);
                continue;
            }
            mRadioAttributes[r.mType] = r;
        }

        // TODO: What is the "correct" way to do determine if this is a wifi only device?
        boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
        log("wifiOnly=" + wifiOnly);
        String[] naStrings = context.getResources().getStringArray(
                com.android.internal.R.array.networkAttributes);
        for (String naString : naStrings) {
            try {
                NetworkConfig n = new NetworkConfig(naString);
                if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
                    loge("yl Error in networkAttributes - ignoring attempt to define type " +
                            n.type);
                    continue;
                }
                if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
                    loge("yl networkAttributes - ignoring mobile as this dev is wifiOnly " +
                            n.type);
                    continue;
                }
                if (mNetConfigs[n.type] != null) {
                    loge("yl Error in networkAttributes - ignoring attempt to redefine type " +
                            n.type);
                    continue;
                }
                if (mRadioAttributes[n.radio] == null) {
                    loge("yl Error in networkAttributes - ignoring attempt to use undefined " +
                            "radio " + n.radio + " in network type " + n.type);
                    continue;
                }
                mNetConfigs[n.type] = n;
                mNetworksDefined++;
            } catch(Exception e) {
                // ignore it - leave the entry null
            }
        }
上面代码可以看出,ConnectivityService,会读取radioAttributes的网络配置,所以这里会把所有的网络类型读出来,并调用startMonitoring,然而默认的代码并没有添加ethernet的配置。所以需要添加下面的代码:

2.frameworks/base/core/res/res/values/config.xml

<span style="font-size:14px;">--- a/frameworks/base/core/res/res/values/config.xml
+++ b/frameworks/base/core/res/res/values/config.xml
@@ -152,6 +152,7 @@
         <item>"mobile_ims,11,0,2,60000,true"</item>
         <item>"mobile_cbs,12,0,2,60000,true"</item>
         <item>"wifi_p2p,13,1,0,-1,true"</item>
+        <item>"ethernet,9,9,0,-1,true"</item> 
     </string-array>
 
     <!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
@@ -170,6 +171,7 @@
     <string-array translatable="false" name="radioAttributes">
         <item>"1,1"</item>
         <item>"0,1"</item>
+        <item>"9,1"</item>
     </string-array>
 
     <!-- Set of NetworkInfo.getType() that reflect data usage. --></span>
3. frameworks/base/core/java/android/net/EthernetDataTracker.java

<span style="font-size:18px;"> </span><span style="font-size:14px;"> // already exists
        sIfaceMatch = context.getResources().getString(
            com.android.internal.R.string.config_ethernet_iface_regex);
        try {
			Log.e(TAG, "yl>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + "sIfaceMatch" + sIfaceMatch);
            final String[] ifaces = mNMService.listInterfaces();
            for (String iface : ifaces) {
					Log.e(TAG, "yl>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + "iface" + iface);
                if (iface.matches(sIfaceMatch)) {
                    mIface = iface;
                    mNMService.setInterfaceUp(iface);
                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
                    mLinkUp = config.hasFlag("up");
                    if (config != null && mHwAddr == null) {
                        mHwAddr = config.getHardwareAddress();
                        if (mHwAddr != null) {
                            mNetworkInfo.setExtraInfo(mHwAddr);
                        }
                    }

                    // if a DHCP client had previously been started for this interface, then stop it
                    NetworkUtils.stopDhcp(mIface);

                    reconnect();
                    break;
                }
            }</span>
startMonitoring,会找到第一个eth开头的 ( <string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>) 的有线网络设备。假设这里的网络设备为eth0,这里会把该设备up,并且rundhcp,如若成功,则通知上层,网络连接成功

4. frameworks\base\core\java\android\net\NetworkUtils.java

    public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults);

frameworks\base\core\jni\android_net_NetUtils.cpp

android_net_utils_runDhcp

android_net_utils_runDhcpCommon

        ::dhcp_do_request_renew

   
::dhcp_do_request
    system\core\libnetutils\Dhcp_utils.c (动态分配ip)

dhcp_do_request

system\core\libnetutils\Ifc_utils.c (静态分配ip,静态设置ip之前,需要动态dhcp成功后,才进行设置)


5.配置启动:init 里面需要添加 dhcp 和 ip renew 服务

+service dhcpcd_eth0 /system/bin/dhcpcd -ABKL
+    class main
+    disabled
+    oneshot
+
+service iprenew_eth0 /system/bin/dhcpcd -n
+    class main
+    disabled
+    oneshot
+


6. 配置的一个例子:

   void configureInterface(EthernetDevInfo info) {
        if (info.getConnectMode().equals(EthernetDevInfo.ETHERNET_CONN_MODE_DHCP)) {

            try {
                mNMService.setInterfaceDown(info.getIfName());
                mNMService.clearInterfaceAddresses(info.getIfName());
                mNMService.setInterfaceUp(info.getIfName());
            } catch (RemoteException re){
                Log.e(TAG,"DHCP configuration failed: " + re);
            } catch (IllegalStateException e) {
                Log.e(TAG,"DHCP configuration fialed: " + e);
            }
        } else {
            InterfaceConfiguration ifcg = null;
            Log.d(TAG, "Static IP =" + info.getIpAddress());
            try {
                ifcg = mNMService.getInterfaceConfig(info.getIfName());
                ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
                        info.getIpAddress()), 24));
                ifcg.setInterfaceUp();
				InetAddress gatewayAddress = NetworkUtils.intToInetAddress(lookupHost(info.getRouteAddr()));
            	RouteInfo defaultRoute = new RouteInfo(gatewayAddress);
				mNMService.addRoute(info.getIfName(),defaultRoute);
                mNMService.setInterfaceConfig(info.getIfName(), ifcg);
				
                Log.d(TAG,"Static IP configuration succeeded");
            } catch (RemoteException re){
                Log.e(TAG,"Static IP configuration failed: " + re);
            } catch (IllegalStateException e) {
                Log.e(TAG,"Static IP configuration fialed: " + e);
            }catch (IllegalArgumentException e) {
                Log.e(TAG,"Wrong Static IP: " + e);
                Toast.makeText(mContext, "Illegal address inputed. You can not access the Internet.",Toast.LENGTH_SHORT).show();
            }
            Log.d(TAG, "set ip manually " + info.toString());
            SystemProperties.set("net.dns1", info.getDnsAddr());
            SystemProperties.set("net." + info.getIfName() + ".dns1",info.getDnsAddr());
            SystemProperties.set("net." + info.getIfName() + ".dns2", "0.0.0.0");
            updateDevInfo(info);
        }
    }

7. 上面主要是关于ethernet的流程,具体的开发还有许多细节需要处理:

如,设置里面加入ethernet的配置选项,网线插拔检测,网络的优先级等一些处理,这些可参考android4.0的移植。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值