您的位置:首页 > 理论基础 > 计算机网络

Android 4.4 Kitkat 使能有线网络 Ethernet

2016-07-16 15:47 936 查看
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 

[html]
view plain
copy
print?





<string-array translatable="false" name="radioAttributes">  
    <item>"1,1"</item>  
    <item>"7,1"</item>  
    <item>"9,1"</item>  
</string-array>  

其中 9 对应 Ethernet 的网络类型,其定义在 ConnectivityManager.java 中

[java]
view plain
copy
print?





/** 
 * The Ethernet data connection.  When active, all data traffic 
 * will use this network type's interface by default 
 * (it has a default route). 
 */  
public static final int TYPE_ETHERNET    = 9;  

init.<board>.rc

init 里面需要添加 dhcp 和 ip renew 服务

[cpp]
view plain
copy
print?





# DHCPCD  
# # eth0  
service dhcpcd_eth0 /system/bin/dhcpcd -ABKL  
    class main  
    disabled  
    oneshot  
  
# IP Renew  
# # eth0  
service iprenew_eth0 /system/bin/dhcpcd -n  
    class main  
    disabled  
    oneshot  

流程分析

ConnectivityService

ConnectivityService 的构造函数里面将会读取 radioAttributes 里面的网络配置

[java]
view plain
copy
print?





public ConnectivityService(Context context, INetworkManagementService netManager,  
        INetworkStatsService statsService, INetworkPolicyManager policyManager,  
        NetworkFactory netFactory) {  
    if (DBG) log("ConnectivityService starting up");  

[java]
view plain
copy
print?





// 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 (VDBG) log("raString=" + raString + " r=" + r);  
    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;  
}  

根据网络配置数据,将会创建 EthernetDataTracker , 并开始监听 startMonitoring

[java]
view plain
copy
print?





// Create and start trackers for hard-coded networks  
for (int targetNetworkType : mPriorityList) {  
    final NetworkConfig config = mNetConfigs[targetNetworkType];  
    final NetworkStateTracker tracker;  
    try {  
        tracker = netFactory.createTracker(targetNetworkType, config);  
        mNetTrackers[targetNetworkType] = tracker;  
    } catch (IllegalArgumentException e) {  
        Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)  
                + " tracker: " + e);  
        continue;  
    }  
  
    tracker.startMonitoring(context, mTrackerHandler);  
    if (config.isDefault()) {  
        tracker.reconnect();  
    }  
}  

EthernetDataTracker

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

[java]
view plain
copy
print?





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

[java]
view plain
copy
print?





sIfaceMatch = context.getResources().getString(  
                  com.android.internal.R.string.config_ethernet_iface_regex);  
try {  
    final String[] ifaces = mNMService.listInterfaces();  
    for (String iface : ifaces) {  
        if (iface.matches(sIfaceMatch)) {  
            mNMService.setInterfaceUp(iface);  
            InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);  
  
            if (getEthernetCarrierState(iface) == 1) {  
                mIface = iface;  
                mLinkUp = true;  
                mNetworkInfo.setIsAvailable(true);  
  
                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(iface);  
        }  
    }  
  
    reconnect();  
} catch (RemoteException e) {  
    Log.e(TAG, "Could not get list of interfaces " + e);  
}  

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

[java]
view plain
copy
print?





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

如果有多个网口呢,这个 EthernetDataTracker 显然不能满足要求,必须对其进行扩展。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: