Android 4.4 Kitkat 使能有线网络 Ethernet

来源:互联网 发布:音乐截取合并软件 编辑:程序博客网 时间:2024/05/16 19:04

原文地址 http://blog.csdn.net/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了. 


0 0
原创粉丝点击