• Android 4.4 Kitkat 使能有线网络 Ethernet



    http://blog.csdn.net/jingxia2008/article/details/26591005


    背景

    Android kitkat 默认已经支持 Ethernet 有线网络,只要稍微配置,便可以直接使用,测试结果,网络浏览器和下载都没有没有问题,而且系统可以做到与 wifi 共存,互相不影响功能,这里简单介绍如何使能 Ethernet,并简要分析其代码和流程。

    Linux 配置部分


    Linux 需要能够支持有线网络,生成 eth 网络设备节点。

    Android 配置

    overlay


    主要是 overlay 里面添加 Ethernet 网络类型支持:  frameworks/base/core/res/res/values/config.xml 
    1. <string-array translatable="false" name="radioAttributes">  
    2.     <item>"1,1"</item>  
    3.     <item>"7,1"</item>  
    4.     <item>"9,1"</item>  
    5. </string-array>  

    其中 9 对应 Ethernet 的网络类型,其定义在 ConnectivityManager.java 中
    1. /** 
    2.  * The Ethernet data connection.  When active, all data traffic 
    3.  * will use this network type's interface by default 
    4.  * (it has a default route). 
    5.  */  
    6. public static final int TYPE_ETHERNET    = 9;  

    init.<board>.rc


    init 里面需要添加 dhcp 和 ip renew 服务
    1. # DHCPCD  
    2. # # eth0  
    3. service dhcpcd_eth0 /system/bin/dhcpcd -ABKL  
    4.     class main  
    5.     disabled  
    6.     oneshot  
    7.   
    8. # IP Renew  
    9. # # eth0  
    10. service iprenew_eth0 /system/bin/dhcpcd -n  
    11.     class main  
    12.     disabled  
    13.     oneshot  

    流程分析


    ConnectivityService

    ConnectivityService 的构造函数里面将会读取 radioAttributes 里面的网络配置
    1. public ConnectivityService(Context context, INetworkManagementService netManager,  
    2.         INetworkStatsService statsService, INetworkPolicyManager policyManager,  
    3.         NetworkFactory netFactory) {  
    4.     if (DBG) log("ConnectivityService starting up");  

    1. // Load device network attributes from resources  
    2. String[] raStrings = context.getResources().getStringArray(  
    3.         com.android.internal.R.array.radioAttributes);  
    4. for (String raString : raStrings) {  
    5.     RadioAttributes r = new RadioAttributes(raString);  
    6.     if (VDBG) log("raString=" + raString + " r=" + r);  
    7.     if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {  
    8.         loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);  
    9.         continue;  
    10.     }  
    11.     if (mRadioAttributes[r.mType] != null) {  
    12.         loge("Error in radioAttributes - ignoring attempt to redefine type " +  
    13.                 r.mType);  
    14.         continue;  
    15.     }  
    16.     mRadioAttributes[r.mType] = r;  
    17. }  

    根据网络配置数据,将会创建 EthernetDataTracker , 并开始监听 startMonitoring
    1. // Create and start trackers for hard-coded networks  
    2. for (int targetNetworkType : mPriorityList) {  
    3.     final NetworkConfig config = mNetConfigs[targetNetworkType];  
    4.     final NetworkStateTracker tracker;  
    5.     try {  
    6.         tracker = netFactory.createTracker(targetNetworkType, config);  
    7.         mNetTrackers[targetNetworkType] = tracker;  
    8.     } catch (IllegalArgumentException e) {  
    9.         Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)  
    10.                 + " tracker: " + e);  
    11.         continue;  
    12.     }  
    13.   
    14.     tracker.startMonitoring(context, mTrackerHandler);  
    15.     if (config.isDefault()) {  
    16.         tracker.reconnect();  
    17.     }  
    18. }  


    EthernetDataTracker

    EthernetDataTracker 将会寻找第一个以 eth 开头的有线网络设备,打开并开始做 dhcp

    1. <!-- Regex of wired ethernet ifaces -->  
    2. <string translatable="false" name="config_ethernet_iface_regex">eth\d</string>  

    1. sIfaceMatch = context.getResources().getString(  
    2.                   com.android.internal.R.string.config_ethernet_iface_regex);  
    3. try {  
    4.     final String[] ifaces = mNMService.listInterfaces();  
    5.     for (String iface : ifaces) {  
    6.         if (iface.matches(sIfaceMatch)) {  
    7.             mNMService.setInterfaceUp(iface);  
    8.             InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);  
    9.   
    10.             if (getEthernetCarrierState(iface) == 1) {  
    11.                 mIface = iface;  
    12.                 mLinkUp = true;  
    13.                 mNetworkInfo.setIsAvailable(true);  
    14.   
    15.                 if (config != null && mHwAddr == null) {  
    16.                     mHwAddr = config.getHardwareAddress();  
    17.   
    18.                     if (mHwAddr != null) {  
    19.                         mNetworkInfo.setExtraInfo(mHwAddr);  
    20.                     }  
    21.                 }  
    22.             }  
    23.   
    24.             // if a DHCP client had previously been started for this interface, then stop it  
    25.             NetworkUtils.stopDhcp(iface);  
    26.         }  
    27.     }  
    28.   
    29.     reconnect();  
    30. catch (RemoteException e) {  
    31.     Log.e(TAG, "Could not get list of interfaces " + e);  
    32. }  

    DHCP 成功后,通知NetworkManagementService  网路已经连接,这个时候上层应用便可以开始执行网络操作。

    1. mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);  
    2. Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
    3. msg.sendToTarget();  

    如果有多个网口呢,这个 EthernetDataTracker 显然不能满足要求,必须对其进行扩展。

  • 相关阅读:
    ASP.NET---创建自定义Web控件小结
    ASP.NET---使用Asp.NET开发三层架构的应用程序
    poj 1847 最短路简单题,dijkstra
    HDU 1102 最小生成树裸题,kruskal,prim
    poj 2239 二分图最大匹配,基础题(待补)
    HDU 1520 树形dp裸题
    HDU 2089 简单数位dp
    poj 3254 状压dp入门题
    HDU 1710 二叉树遍历,输入前、中序求后序
    Poj 3250 单调栈
  • 原文地址:https://www.cnblogs.com/ztguang/p/12646044.html
Copyright © 2020-2023  润新知