netd

近来再看Android  Netd作为Android 网络很基础的部分,从这部分开始入门Android network.属于偏底层的部分,现将个人的一点收获分享给大家~个人使用的代码来自Google Android 4.1和 开源论坛  https://www.codeaurora.org/ 这个论坛可以直接拉下部分公司提供的开放代码我是用的是QCOM高通的,代码可能会有细微差异但Netd整体构架不会变化。

个人邮箱:[email protected]

       基本的环境配置和搭建就不赘述,如果你自己认为自己还是崭新的新手,我有个人看过的关于Android底层开发,系统级别需要了解的知识的博客列表~LINK(待完善):

 

一.概述

       所谓 Netd 就是Network Daemon 的缩写,表示Network守护进程,类似的命名还有很多,例如 Vold(Volumn Deamon)---磁盘管理,Rild(Radio Interface Layer Deamon)--- 电话的基本数据功能……类似的还有好多,遍及Android各类服务,各个层次~

Netd负责跟一些涉及物理端口的网络操作相关的功能实现,例如带宽控制(Bandwidth),网络地址转换(NAT),个人局域网(pan),PPP链接,soft-ap,共享上网(Tether)等等……都是按照模块(.cpp+.h)组织在netd文件目录下的~ 


Android Netd 相关的基本框架的四大部分

(1)Linux Kernel 用于检测 network 相关的所有 event 事件。

(2)Netd 作为 Kernel 与 Framework 之间通信的桥梁。

(3)Framework 层操作 Netd,向 Netd 发送操作命令。

(4)UI 与 Framework 交互,用于用户进行网络的操控。

 

涉及主要源码位置:

Netd:

/System/netd

/system/core/libsysutils/src

/system/core/include/sysutils

Framework:

 /frameworks/base/services/java/com/android/server


先统领一下~整体的框架图~ 很不规范,会意即可,之后还会详细介绍:

netd_第1张图片


















 如下式Netd下的文件,我们将按照从下至上的流程分析它

~leo/myAndroid/System/netd/

0:[+] Android.mk *
0:[+] BandwidthController.cpp *
0:[+] BandwidthController.h *
0:[+] CleanSpec.mk *
0:[+] CommandListener.cpp *
0:[+] CommandListener.h *
0:[+] DnsProxyListener.cpp *
0:[+] DnsProxyListener.h *
0:[+] IdletimerController.cpp *
0:[+] IdletimerController.h *
0:[+] List.h *
0:[+] MDnsSdListener.cpp *
0:[+] MDnsSdListener.h *
0:[+] NatController.cpp *
0:[+] NatController.h *
0:[+] NetdCommand.cpp *
0:[+] NetdCommand.h *
0:[+] NetdConstants.cpp *
0:[+] NetdConstants.h *
0:[+] NetlinkHandler.cpp *
0:[+] NetlinkHandler.h *
0:[+] NetlinkManager.cpp *
0:[+] NetlinkManager.h *
0:[+] PanController.cpp *
0:[+] PanController.h *
0:[+] PppController.cpp *
0:[+] PppController.h *
0:[+] ResolverController.cpp *
0:[+] ResolverController.h *
0:[+] ResponseCode.h *
0:[+] RouteController.cpp *
0:[+] RouteController.h *
0:[+] SecondaryTableController.cpp *
0:[+] SecondaryTableController.h *
0:[+] SoftapController.cpp *
0:[+] SoftapController.h *
0:[+] TetherController.cpp *
0:[+] TetherController.h *
0:[+] ThrottleController.cpp *
0:[+] ThrottleController.h *
0:[+] logwrapper.c *
0:[+] main.cpp *
0:[+] ndc.c *
0:[+] oem_iptables_hook.cpp *
0:[+] oem_iptables_hook.h *

      

从init.rc文件中可以看到,是在启动就开始运行的一个系统级的守护进程。而且同 Vold 基本并列~ 对于init.rc文件的意义请参考附录2

netd_第2张图片

 

二.基本实例

就拿手机的soft-ap功能来举例吧~

以使用 softap(Soft Access Point - 软 AP)为例。软 Ap 可以为游戏应用提供联机对战的功能, 也可以基于软 ap 实现网络共享, 即连接到软 Ap 上的设备可以共享软 Ap 设备的网络, 比如手机可以作为软 Ap, 笔记本连进来就可以通过手机的 3g 上网。以htc 中的 WLAN 热点的 app,如下图所示。

netd_第3张图片

 

1)设置并开启 softap(便携式 WLAN 热点)

在 Setting 选项中进行设置,该设置功能的开启将涉及相关的UI 路径下相关的文件,packages /apps/Settings/src/com/android/settings/wifi 路径下,程序中的 WifiApEnabler. OnPreferenceChange 里, 设置 soft ap 在 wifiApDialog.onClick 里。知道就行,因为你不一定有……☺


2)调用相应的处理函数,通过 socket 向 netd 下发命令。

对于 app 层的函数调用关系不做详细介绍,最终会调用到 Framework 层的 NetworkManagementService.startAccessPoint 函数。


[java] view plain copy
  1. //NetworkManagementService.java     
  2.  @Override  
  3.     public void startAccessPoint(  
  4.             WifiConfiguration wifiConfig, String wlanIface, String softapIface) {  
  5.         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);  
  6.         try {  
  7.             wifiFirmwareReload(wlanIface, "AP");  
  8.             if (wifiConfig == null) {  
  9.                 mConnector.execute("softap""set", wlanIface, softapIface);  
  10.             } else {  
  11.                 mConnector.execute("softap""set", wlanIface, softapIface, wifiConfig.SSID,  
  12.                         getSecurityType(wifiConfig), wifiConfig.preSharedKey);  
  13.             }  
  14.             mConnector.execute("softap""startap");  
  15.         } catch (NativeDaemonConnectorException e) {  
  16.             throw e.rethrowAsParcelableException();  
  17.         }  
  18.     }  

NetworkManagementService 顾名思义是 Android 系统的网络管理服务, 负责比较特殊的网络的设置(比如网络共享(Tether)和网络地址转换(Nat)和 ip 转发(ip forwording))和向上层通知网络相关的事件。mConnector 是一个 NativeDaemonConnector, 这里用来和系统的 netd 守护进程通过 socket 进行通信。

3) netd 接受命令并进行处理,并将处理结果反馈给 Framework 层。


NetworkManagementService 的好多功能都是通过 Netd 实现的。 Netd 的代码在/system/netd 里。Netd 中 softap 控制的功能在/system/netd/SoftapController.{h,cpp}里, 具体的执行是通过调用网卡驱动的 ap 功能, 适具体网卡驱动提供的 soft-ap 接口不同而不同。NetworkManagementService 通过 NativeDaemonConnector 向下通过 socket 向下 softap 相关的字符串命令,NativeDaemonConnector 中维护着与 Netd 中 CommandListener 相关联的内部socket 线程。两者可以通过它相互通信。

[cpp] view plain copy
  1. //CommandListener.cpp  
  2. int CommandListener::SoftapCmd::runCommand(SocketClient *cli,  
  3.                                         int argc, char **argv) {  
  4.     int rc = 0, flag = 0;  
  5.     char *retbuf = NULL;  
  6.   
  7.     if (argc < 2) {  
  8.         cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument"false);  
  9.         return 0;  
  10.     }  
  11.   
  12.     if (!strcmp(argv[1], "start")) {  
  13.         rc = sSoftapCtrl->startDriver(argv[2]);  
  14.     } else if (!strcmp(argv[1], "stop")) {  
  15.         rc = sSoftapCtrl->stopDriver(argv[2]);  
  16.     } else if (!strcmp(argv[1], "startap")) {  
  17.         rc = sSoftapCtrl->startSoftap();  
  18.     } else if (!strcmp(argv[1], "stopap")) {  
  19.         rc = sSoftapCtrl->stopSoftap();  
  20.     } else if (!strcmp(argv[1], "fwreload")) {  
  21.         rc = sSoftapCtrl->fwReloadSoftap(argc, argv);  
  22.     } else if (!strcmp(argv[1], "clients")) {  
  23.         rc = sSoftapCtrl->clientsSoftap(&retbuf);  
  24.         if (!rc) {  
  25.             cli->sendMsg(ResponseCode::CommandOkay, retbuf, false);  
  26.             free(retbuf);  
  27.             return 0;  
  28.         }  
  29.     } else if (!strcmp(argv[1], "status")) {  
  30.       
  31. ……  
  32. ……  

4) Framework 受到回馈的信息,并通知 UI 处理结果,呈现给用户。

netd_第4张图片

5)相关的 Log 实例:(adb logcat NetdConnector:D NetworkManagementService*:S)

    如果不懂logcat参考附录(4)

D/NetworkManagementService( 1760): ===================startAccessPoint
commandLine=softap set wlan0 wlan0 "HTC Portable Hotspot E2D4" "wpa2-psk" *** 0 0 5 0

D/NetdConnector( 1760): SND -> {softap set wlan0 wlan0 "HTC Portable Hotspot E2D4""wpa2-psk" "3FF8F7531FBB9" 0 0 5 0} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap startap} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 down}
D/NetdConnector( 1760): listenToSocket read--: (24,0)
D/NetdConnector( 1760): RCV <- {600 Iface added m.wlan0}
D/NetdConnector( 1760): listenToSocket read--: (33,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate m.wlan0 down}
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate m.wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap setMaxConns 5} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): SND -> {interface getcfg wlan0} {null}
D/NetdConnector( 1760): listenToSocket read--: (65,0)
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): RCV <- {213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast running multicast]}
D/NetdConnector( 1760): RSP <- {213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast runningmulticast]}

D/NetworkManagementService( 1760): rsp <213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast running multicast]>
D/NetworkManagementService( 1760): flags <[up broadcast running multicast]>
D/NetdConnector( 1760): SND -> {interface setcfg wlan0 192.168.1.1 24 [up]} {null}
D/NetdConnector( 1760): listenToSocket read--: (32,0)
D/NetdConnector( 1760): RCV <- {200 Interface configuration set}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): RSP <- {200 Interface configuration set}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
E/NetworkManagementService( 1760): DEBUG softap setmaclist: softap setmaclist 0 "" ""
D/NetdConnector( 1760): SND -> {softap setmaclist 0 "" ""} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {tether interface add wlan0} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Tether operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Tether operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap getassoclist} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (7,0)
D/NetdConnector( 1760): RCV <- {222 0|}
D/NetdConnector( 1760): RSP <- {222 0|}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
E/NetworkManagementService( 1760): DEBUG softap getassoclist: 0|
D/NetdConnector( 1760): SND -> {ipfwd enable} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (30,0)
D/NetdConnector( 1760): RCV <- {200 ipfwd operation succeeded}
D/NetdConnector( 1760): RSP <- {200 ipfwd operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetworkManagementService( 1760): stopTethering
D/NetdConnector( 1760): SND -> {tether status} {null}
D/NetdConnector( 1760): listenToSocket read--: (31,0)
……

……


附录(待完善……)

(1)Android启动流程&结构框架

(2)Vold+12篇章

(3)init.rc文件的意义

(4)logcat


你可能感兴趣的:(netd)