Android 4.1 Netd詳細分析(一)概述與應用實例

Android 4.1 Netd詳細分析(一)概述與應用實例 分類: Android網路 Netd Android Netd network Android 2012-10-31 13:00 2563人閱讀 評論(0) 收藏 舉報

目錄(?)[+]

近來再看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?

  1. //NetworkManagementService.java
  2. @Override
  3. publicvoidstartAccessPoint(
  4. WifiConfigurationwifiConfig,StringwlanIface,StringsoftapIface){
  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(NativeDaemonConnectorExceptione){
  16. throwe.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 plaincopy?

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

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新手指引開源控制項

TAG:Android | 分析 | 細分 | 概述 |