Netd:
/System/netd/*
lib:
/system/core/libsysutils/src
Framework:
/frameworks/base/services/java/com/android/server/NetworkManagementService.java
/frameworks/base/services/java/com/android/server/NativeDaemonConnector.java
理解一个模块最好方法就是实际应用。netd最为一个deamon,为开发者提供了一个用于管理的接口。就是ndc (nativedeamonconnector),通过adb可以直接使用CommandListener中定义的各类命令。相似的framework层的NativeDeamonConnector是为上层提供的接口。下面是4.2中ndc可用的命令集合:
interface | list |
readrxcounter| readtxcounter | |
getthrottle<iface><”rx|tx”> | |
setthrottle<iface><rx_kbps|tx_kbps> | |
driver<iface><cmd><args> | |
route<add|remove> <iface> <”default|secondary”><dst> <prefix> <gateway> | |
list_ttys | |
ipfwd | status |
enable|disable | |
tether | status |
start-reverse|stop-reverse | |
stop< | |
start<addr_1 addr_2 addr_3 addr_4 [addr_2n]> | |
interface<add|remove|list> | |
dnslist | |
dnsset <addr_1> < addr_2> | |
nat | <enable|disable><iface><extface><addrcnt><nated-ipaddr/prelength> |
pppd | attach<tty> <addr_local> <add_remote> <dns_1><dns_2> |
detach<tty> | |
softap | startap|stopap |
fwreload<iface> <AP|P2P> | |
clients | |
status | |
set<iface> <SSID> <wpa-psk|wpa2-psk|open> [<key><channel> <preamble><max SCB>] | |
resolver | setdefaultif<iface> |
setifdns<iface><dns_1><dns_2> | |
flushdefaultif | |
flushif<iface> | |
bandwith | enable|disable |
removequota|rq | |
getquota|gq | |
getiquota|giq<iface> | |
setquota|sq<bytes> <iface> | |
removequota|rqs<iface> | |
removeiiquota|riq<iface> | |
setiquota|sq<interface><bytes> | |
addnaughtyapps|ana<appUid> | |
removenaughtyapps|rna<appUid> | |
setgolbalalert|sga<bytes> | |
debugsettetherglobalalert|dstga<iface0><iface1> | |
setsharedalert|ssa<bytes> | |
removesharedalert|rsa | |
setinterfacealert|sia<iface><bytes> | |
removeinterfacealert|ria<iface> | |
gettetherstats|gts<iface0><iface1> | |
idletimer | enable|disable |
add|remove<iface><timeout><classLabel> | |
firewall | enable|disable|is_enabled |
set_interface_rule<rmnet0><allow|deny> | |
set_egress_source_rule<ip_addr><allow|deny> | |
set_egress_dest_rule<ip_addr><port><allow|deny> | |
set_uid_rule<uid><allow|deny> | |
clatd | stop|status|start<iface> |
从init.rc文件中可以看到,是系统级的守护进程,手动kill后还会从新启动。
三.基本实例
就拿手机的soft-ap功能来举例吧,以使用 softap(Soft Access Point)为例。softap可以为wlan接入设备共享手机使用的移动网络,笔记本接入softap,可以通过手机的 3g 上网。以htc 中的 WLAN 热点的 app,如下图所示。在 Setting 选项中进行设置,该设置功能的开启将涉及相关的UI 路径下相关的文件,packages /apps/Settings/src/com/android/settings/wifi 路径下,程序中的 WifiApEnabler. OnPreferenceChange 里, 设置 soft ap 在 wifiApDialog.onClick 里。
应用层通过ConnectivityManager接口,最终走到 Framework 层的 NetworkManagementService.startAccessPoint 函数。
//NetworkManagementService.java @Override public void startAccessPoint( WifiConfiguration wifiConfig, String wlanIface, String softapIface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { wifiFirmwareReload(wlanIface, "AP"); if (wifiConfig == null) { mConnector.execute("softap", "set", wlanIface, softapIface); } else { mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID, getSecurityType(wifiConfig), wifiConfig.preSharedKey); } mConnector.execute("softap", "startap"); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } }
NetworkManagementService 通过NativeDaemonConnector, 这里用来和系统的 netd 守护进程通过 socket 进行通信,发送命令。
Netd 中 softap 控制的功能在/system/netd/SoftapController.{h,cpp}里, 具体的执行是通过调用网卡驱动的 ap 功能。NetworkManagementService 通过 NativeDaemonConnector 向下通过 socket 向下 softap 相关的字符串命令,NativeDaemonConnector 中维护着与 Netd 中 CommandListener 相关联的内部socket 线程。两者可以通过它相互通信。
//CommandListener.cpp int CommandListener::SoftapCmd::runCommand(SocketClient *cli, int argc, char **argv) { int rc = 0, flag = 0; char *retbuf = NULL; if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); return 0; } if (!strcmp(argv[1], "start")) { rc = sSoftapCtrl->startDriver(argv[2]); } else if (!strcmp(argv[1], "stop")) { rc = sSoftapCtrl->stopDriver(argv[2]); } else if (!strcmp(argv[1], "startap")) { rc = sSoftapCtrl->startSoftap(); } else if (!strcmp(argv[1], "stopap")) { rc = sSoftapCtrl->stopSoftap(); } else if (!strcmp(argv[1], "fwreload")) { rc = sSoftapCtrl->fwReloadSoftap(argc, argv); } else if (!strcmp(argv[1], "clients")) { rc = sSoftapCtrl->clientsSoftap(&retbuf); if (!rc) { cli->sendMsg(ResponseCode::CommandOkay, retbuf, false); free(retbuf); return 0; } } else if (!strcmp(argv[1], "status")) { …… ……
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)
…………