android系统 Ethernet 解析

在公司一款产品上需要需要添加有线网口,所以系统需要做相应的支持,找到一个支持的有线网口的系统,将其中软件部分做简单分析:

首先:功能方面,要能够设置有线网络的IP地址,子网掩码,网关,DNS等信息,这些功能由 Etnernet 这个 APP实现;

系统方面,对于已经设置好的信息,断电重启之后不能丢失,还能继续保持有效,所以需要添加一个系统服务 EthernetService


其次,EthernetService的启动入口, \frameworks\base\services\java\com\android\server\ConnectivityService.java 其构造类

public ConnectivityService(Context context, INetworkManagementService netManager,
            INetworkStatsService statsService, INetworkPolicyManager policyManager,
            NetworkFactory netFactory)

for (int targetNetworkType : mPriorityList) {
           final NetworkConfig config = mNetConfigs[targetNetworkType];
           final NetworkStateTracker tracker;
           try {
tracker = netFactory.createTracker(targetNetworkType, config);
mNetTrackers[targetNetworkType] = tracker;
if (targetNetworkType == ConnectivityManager.TYPE_ETHERNET) {
EthernetService ethernet = new EthernetService(context, (EthernetStateTracker)tracker);
ServiceManager.addService(Context.ETH_SERVICE, ethernet);

}
Slog.d(TAG, "*******targetNetworkType="+targetNetworkType);
           } catch (IllegalArgumentException e) {
               Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)
                       + " tracker: " + e);
               continue;
           }

           tracker.startMonitoring(context, mTrackerHandler); 

           
           if (config.isDefault()) {
               tracker.reconnect();
           }
       }


上面的黑体字代码是实现Ethernet 功能的核心,具体分析如下

1. tracker = netFactory.createTracker(targetNetworkType, config); 

创建 网络状态追踪器 

@Override
       public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {
           switch (config.radio) {
               case TYPE_WIFI:
                   return new WifiStateTracker(targetNetworkType, config.name);
               case TYPE_MOBILE:
                   return new MobileDataStateTracker(targetNetworkType, config.name);
               case TYPE_DUMMY:
                   return new DummyDataStateTracker(targetNetworkType, config.name);
               case TYPE_BLUETOOTH:
                   return BluetoothTetheringDataTracker.getInstance();
               case TYPE_WIMAX:
                   return makeWimaxStateTracker(mContext, mTrackerHandler);
    case TYPE_ETHERNET:
        //return EthernetDataTracker.getInstance();
return new EthernetStateTracker(targetNetworkType, config.name);
               default:
                   throw new IllegalArgumentException(
                           "Trying to create a NetworkStateTracker for an unknown radio type: "
                           + config.radio);
           }
       }
   }    

2. 创建并添加网络服务

EthernetService ethernet = new EthernetService(context, (EthernetStateTracker)tracker);
ServiceManager.addService(Context.ETH_SERVICE, ethernet);


    \frameworks\base\services\java\com\android\server\EthernetService.java


private int mEthState= EthernetManager.ETH_STATE_UNKNOWN;
//public static final int ETH_STATE_UNKNOWN = 0;

public EthernetService(Context context, EthernetStateTracker Tracker){
       mTracker = Tracker;
       mContext = context;

       isEthEnabled = getPersistedState();
       Slog.v(TAG,"Ethernet dev enabled " + isEthEnabled );
    getDeviceNameList();
    setEthState(isEthEnabled);
       //registerForBroadcasts();
       Slog.v(TAG, "Trigger the ethernet monitor");
       mTracker.StartPolling();
       mDelayedHandler = new Handler();  
       isEthernetServiceInited = true;
   }

其核心是 setEthState,即开关网络


3.  tracker.startMonitoring(context, mTrackerHandler); 

启动网络状态监控,核心是

frameworks\base\ethernet\java\android\net\ethernet\EthernetMonitor.java

   class MonitorThread extends Thread {


        public MonitorThread() {
            super("EthMonitor");
        }


        public void run() {
            int index;
            int i;


            //noinspection InfiniteLoopStatement
            for (;;) {
                if (DEBUG) Slog.i(TAG, "go poll events");
                String eventName = EthernetNative.waitForEvent();


                if (eventName == null) {
                    continue;
                }
                if (DEBUG) Slog.i(TAG, "got event " + eventName);
                /*
                 * Map event name into event enum
                 */
                String [] events = eventName.split(":");
                index = events.length;
                if (index < 2)
                    continue;
                i = 0;
                while (index != 0 && i < index-1) {


                    int event = 0;
                    if (DEBUG) Slog.i(TAG,"dev: " + events[i] + " ev " + events[i+1]);
                    int cmd =Integer.parseInt(events[i+1]);
                    if ( cmd == DEL_LINK) {
                        event = DISCONNECTED;
                        handleEvent(events[i],event);
                    }
                    else if (cmd == ADD_ADDR ) {
                        event = CONNECTED;
                        handleEvent(events[i],event);
                    } else if (cmd == NEW_LINK) {
                        event = PHYUP;
                        handleEvent(events[i],event);
                    }
                    i = i + 2;
                }
            }
        }
        /**
         * Handle all supplicant events except STATE-CHANGE
         * @param event the event type
         * @param remainder the rest of the string following the
         * event name and &quot;&#8195;&#8212;&#8195;&quot;
         */
        void handleEvent(String ifname,int event) {
            switch (event) {
                case DISCONNECTED:
                    mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.DISCONNECTED);
                    break;
                case CONNECTED:
                    mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.CONNECTED);
                    break;
                case PHYUP:
                    mTracker.notifyPhyConnected(ifname);
                    break;
                default:
                    mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.FAILED);
            }
        }


监控程序启动一个线程,调用native方法  String eventName = EthernetNative.waitForEvent();

通过 handleEvent(events[i],event);  将不同的网络状态消息传到 mTracker ,mTracker对消息作出响应


4. 实现真正的网络设置,

tracker.reconnect();  其核心是 EthernetStateTracker ->resetInterface,在调用本地方法,

system/core/libnetutils/ifc_utils.c

(libcutils---ifc_utils.c)int ifc_reset_connections(const char *ifname, const int reset_mask)


这个文件还包含一些网络接口,详见 另一篇博客

http://blog.youkuaiyun.com/liufuliang163/article/details/72729901


上面提到的相关代码:

http://download.youkuaiyun.com/detail/liufuliang163/9853456


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值