Android 4.4 Kitkat 使能有线网络 Ethernet

本文介绍了Android系统中Ethernet有线网络的支持配置方法及其实现流程。覆盖了Linux配置、Android配置、ConnectivityService和EthernetDataTracker的工作原理,并提供内核部分的驱动编译指导。

原文地址 http://blog.youkuaiyun.com/jingxia2008/article/details/26591005 ——这个有线网卡和wifi 是不同的,在这里不需要HAL。

背景

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 ? 在CODE上查看代码片 派生到我的代码片
  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 中
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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 服务
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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 里面的网络配置
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public ConnectivityService(Context context, INetworkManagementService netManager,  
  2.         INetworkStatsService statsService, INetworkPolicyManager policyManager,  
  3.         NetworkFactory netFactory) {  
  4.     if (DBG) log("ConnectivityService starting up");  

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <!-- Regex of wired ethernet ifaces -->  
  2. <string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>  

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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  网路已经连接,这个时候上层应用便可以开始执行网络操作。

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);  
  2. Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
  3. msg.sendToTarget();  

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

-----------下面是内核部分,以ax8872 为参考例子。

一、下载驱动

网卡采用USB 2.0转以太网控制芯片AX88772B, Android 2.3 和4.0下的通用网卡驱动不支持这款芯片, 需要从网上下载最新的Linux 下AX88772B驱动

驱动下载地址:http://www.asix.com.tw/cs/download.php?sub=driverdetail&PItemID=105

 

二、将下载的驱动源码编译进kernel image.

下载的驱动解包后有6个文件, readme文件是release note , 里面有revision history和 make 方法, 可以简单看一下.

Makefile文件告诉我们生成的最终文件是asix.o, 其它4个文件asix.c, asix.h,axusbnet.c,axusbnet.h就是我们需要的源码文件了.

 

进入你的kernel 目录, 你会发现/drivers/net/usb里已经有asix.c 文件, 你可以用下载的asix.c 直接替换这个文件, 也可以将原始的asix.c 改名成asix_ori.c.

将asix.c, asix.h,axusbnet.c,axusbnet.h全部放入/drivers/net/usb 目录, 不需要做任何修改,直接在终端执行make -j2.

如果不能生asix.o, 你需要检查你的config 文件里下面几个flag 是否有设置

#
# USB Network Adapters
#
CONFIG_USB_PEGASUS=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_DM9601=y
CONFIG_USB_NET_NET1080=y
CONFIG_USB_NET_CDC_SUBSET=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_NET_ZAURUS=y

 

三、配置dhcp 和dns

烧入新生成的kernel image, 这时你的设备还不能通过浏览器访问internet, 需要配置dhcp 和dns.

打开adb, 输入下面两条命令

netcfg eth0 dhcp
setprop net.dns1 8.8.8.8

 

最后用busybox ifconfig 检查一下设置是否生效.

如果在eth0 里能看到系统分配的IP 地址, 说明一切设置OK了. 


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值