Android 4.1 Netd詳細分析(一)概述與應用實例
目錄(?)[+]
近來再看Android Netd作為Android 網路很基礎的部分,從這部分開始入門Android network.屬於偏底層的部分,現將個人的一點收穫分享給大家~個人使用的代碼來自Google Android 4.1和 開源論壇 https://www.codeaurora.org/這個論壇可以直接拉下部分公司提供的開放代碼我是用的是QCOM高通的,代碼可能會有細微差異但Netd整體構架不會變化。
個人郵箱:xiaokeweng@gmail.com
基本的環境配置和搭建就不贅述,如果你自己認為自己還是嶄新的新手,我有個人看過的關於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下的文件,我們將按照從下至上的流程分析它
~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
二.基本實例
就拿手機的soft-ap功能來舉例吧~
以使用 softap(Soft Access Point - 軟 AP)為例。軟 Ap 可以為遊戲應用提供聯機對戰的功能, 也可以基於軟 ap 實現網路共享, 即連接到軟 Ap 上的設備可以共享軟 Ap 設備的網路, 比如手機可以作為軟 Ap, 筆記本連進來就可以通過手機的 3g 上網。以htc 中的 WLAN 熱點的 app,如下圖所示。
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 plaincopy?
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 plaincopy?
4) Framework 受到回饋的信息,並通知 UI 處理結果,呈現給用戶。
5)相關的 Log 實例:(adb logcat NetdConnector:D NetworkManagementService*:S)
如果不懂logcat參考附錄(4)
D/NetworkManagementService( 1760):===================startAccessPointcommandLine=softap set wlan0 wlan0 "HTC Portable Hotspot E2D4" "wpa2-psk" *** 0 0 5 0D/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=0D/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=0D/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=0D/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 runningmulticast]}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 [upbroadcast 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=0D/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=0D/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=0D/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=0D/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=0D/NetdConnector( 1760): finish send Command (complete)D/NetworkManagementService( 1760): stopTetheringD/NetdConnector( 1760): SND ->{tether status} {null}D/NetdConnector( 1760): listenToSocket read--: (31,0)……
……
附錄(待完善……)
(1)Android啟動流程&結構框架
(2)Vold+12篇章
(3)init.rc文件的意義
(4)logcat
推薦閱讀:
※深入學習Android:虛擬機&運行時
※曾經的諾基亞人現在過的好么?來說 說你們的【故事】。
※5 月 11 日 Google 發布了 Android@Home,這會有什麼後續影響?
※書單丨十年發展,這5本書帶你開啟Android系統探索之旅
※開源整理:Android App新手指引開源控制項