您的位置:首页 > 移动开发 > Android开发

Android 4.1 Netd详细分析(三)代码分析1

2012-11-02 11:26 225 查看
个人邮箱:xiaokeweng@gmail.com
[b] 接下来开始从代码分析,按照从下至上的顺序来分析,从native层向framework层过渡,Android的各个层之间严格按照软件工程原理的低耦合要求.[/b]

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <fcntl.h>
#include <dirent.h>

#define LOG_TAG "Netd"

#include "cutils/log.h"

#include "CommandListener.h"
#include "NetlinkManager.h"
#include "DnsProxyListener.h"
#include "MDnsSdListener.h"

static void coldboot(const char *path);
static void sigchld_handler(int sig);
static void blockSigpipe();

int main() {

/********************************************************
*以下两个为函数主要使用的类
*CommandListener :监听 framework 层的命令,并调用本类中注册的处理函数,并将处理结果返回
*NetLinkManager  :管理 kernel 层相关的 event,将收到收到的信息提交给 framework 层
********************************************************/

CommandListener *cl;
NetlinkManager *nm;

/********************************************************
* 这两个可以各自理解为单独的工作模块,相对上面的类更加简单。
* DnsProxyListener :DNS 解析,通过系统库函数 getaddrinfo,并将解析结果反馈给 framework 层
* MDnsSdListener   :Muliticast-DNS Server Descript 利用局域网其他对象解析
********************************************************/
  
  DnsProxyListener *dpl;
MDnsSdListener *mdnsl;

ALOGI("Netd 1.0 starting");

//  signal(SIGCHLD, sigchld_handler);
blockSigpipe();			//禁用Sigpipe

if (!(nm = NetlinkManager::Instance())) {	//实例化nm
ALOGE("Unable to create NetlinkManager");
exit(1);
};

/*******************************************************
* nm->setBroadcaster((SocketListener *) cl)
* setBroadcaster函数将NetlinkManager的成员变量mBroadcaster设置成cl,这两个变量都是
* ScoketListener的指针类型,命令执行广播函数,就会调用这个SocketListener的指针来调用
* SocketListener类的广播函数* 因为:继承关系:
* CommandListener(子类)-->FrameworkListener()-->SocketListener(父类)*******************************************************/

cl = new CommandListener();			//实例化cl
nm->setBroadcaster((SocketListener *) cl);	//关联nm和cl这样nm就可以通过方法
//广播消息来回复给framework
/**************************************************
* 使用了 Netlink socket 是用于实现用户进程与内核进程通信的 IPC,
* 下面的 start()就是开启监听内核的线程。
*************************************************/

if (nm->start()) {
ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));
exit(1); }

/**************************************************
* 关于DnsProxyListener/MdnsSdListener会在后面单独详细
* 各自的原理同CommandListener+NetlinkManager两个组成的系统
**************************************************/

// Set local DNS mode, to prevent bionic from proxying(自动代理)
// back to this service, recursively.(递归)
// DnsProxyListener -> FrameworkListrner -> SocketListener

setenv("ANDROID_DNS_MODE", "local", 1); 		//设置为本地模式,是一个全局变量
//DNS
dpl = new DnsProxyListener();
if (dpl->startListener()) {
ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
exit(1);
}
//multicast_DNS_server_descript_listener										//多播DNS守护进程
//内网没有DNS服务器时,出现此组播
mdnsl = new MDnsSdListener();
if (mdnsl->startListener()) {
ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));
exit(1);
}

/************************************************
* cl 开启线程,监听 framework 层下发的命令,并调用相关函数处理
*********************************************** */

if (cl->startListener()) {
ALOGE("Unable to start CommandListener (%s)", strerror(errno));
exit(1);
}

// 成为守护进程
while(1) {
sleep(1000);
}

ALOGI("Netd exiting");
exit(0);
}

///*********打杂函数**************//
// 实际还真没看到打杂的意义/作用是什么……
static void do_coldboot(DIR *d, int lvl)
{
struct dirent *de;
int dfd, fd;

dfd = dirfd(d);

fd = openat(dfd, "uevent", O_WRONLY);
if(fd >= 0) {
write(fd, "add\n", 4);
close(fd);
}

while((de = readdir(d))) {
DIR *d2;

if (de->d_name[0] == '.')
continue;

if (de->d_type != DT_DIR && lvl > 0)
continue;

fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
if(fd < 0)
continue;

d2 = fdopendir(fd);
if(d2 == 0)
close(fd);
else {
do_coldboot(d2, lvl + 1);
closedir(d2);
}
}
}

static void coldboot(const char *path)
{
DIR *d = opendir(path);
if(d) {
do_coldboot(d, 0);
closedir(d);
}
}

static void sigchld_handler(int sig) {
pid_t pid = wait(NULL);
ALOGD("Child process %d exited", pid);
}

static void blockSigpipe()
{
sigset_t mask;

sigemptyset(&mask);
sigaddset(&mask, SIGPIPE);
if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
ALOGW("WARNING: SIGPIPE not blocked\n");
}




至此,按照 main 函数的流程进行分析。

首先如上图,系统的部分主干关系图,系统可以按照功能和相关性分为三大部分,DnsProxyLis-

tener,MDnsSdListener,和 CommandListener + NetlinkManager 三大部分,每个部分都能够利用内

部 socket 和独立线程,接收到 Framework 层的命令,系统调用操作 Kernel 层,并回复 Framework 反

馈,可是说 Netd 充当了 Framework 与 kernel 的桥梁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: