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

Android 4.4 Kitkat 使能有线网络 Ethernet

2016-03-28 14:57 501 查看
转自: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 显然不能满足要求,必须对其进行扩展。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: