本篇文章将会从总体流程上解释一下每一个函数的意义,具体的每一个函数的解释将是一个很长的过程,后面的文章中我将会针对每一个有意义的函数来具体分析。

bluetoothdservice的启动之前,我们先来看一下bluetoothd service究竟是什么,他同样定义在init.rc中:

servicebluetoothd /system/bin/bluetoothd -n

         所以,很清楚,他就是执行bluetoothd这个应用。那么bluetoothd是由哪个文件编译出来的呢,搜索一下就会在bluez下面的src中的Android.mk发现其踪迹:



1. #  
2. # bluetoothd  
3. #  
4.   
5. include $(CLEAR_VARS)  
6.   
7. LOCAL_SHARED_LIBRARIES := \  
8.     libbluetoothd  
9.   
10. LOCAL_MODULE:=bluetoothd

src目录下面看一下了,作为一个应用程序,第一个映入我们眼帘的肯定就是main了,正好下面有一个main.c,然后里面还有一个main函数,哈哈,你懂的:



1. int main(int argc, char *argv[])  
2. {  
3.     GOptionContext *context;  
4.     GError *err = NULL;  
5. struct sigaction sa;  
6.     uint16_t mtu = 0;  
7.     GKeyFile *config;  
8. //这个函数就是用来设置uid和capability的,他主要是使得该应用在访问kernel的时候能够有权限  
9. //从注册可以看到,说目前的android init rc并不支持权限的赋予,所以只能出此下策,毫无疑问,我们需要走到这个ifdef中  
10. //当然我们也可以从理论上去check一下,在Android.mk中是有这个宏的define的  
11. #ifdef ANDROID_SET_AID_AND_CAP  
12. /* Unfortunately Android's init.rc does not yet support applying
13.      * capabilities. So we must do it in-process. */  
14. void *android_set_aid_and_cap(void);  
15. //这个就是设置uid为AID_BLUETOOTH,  
16. //设置capbility为CAP_NET_RAW| CAP_NET_ADMIN| CAP_NET_BIND_SERVICE  
17.     android_set_aid_and_cap();  
18. #endif  
19. //默认的初始化,详细分析见2.2.1  
20.     init_defaults();  
21. //既然我们上面已经想法设法得到权限了,这里就必然不会再把权限释放了。  
22. //这个ifdef是不会进去了  
23. #ifdef HAVE_CAPNG  
24. /* Drop capabilities */  
25.     capng_clear(CAPNG_SELECT_BOTH);  
26.     capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,  
27.                     CAP_NET_BIND_SERVICE, CAP_NET_ADMIN,  
28.                         CAP_NET_RAW, CAP_IPC_LOCK, -1);  
29.     capng_apply(CAPNG_SELECT_BOTH);  
30. #endif  
31. //这里是解析命令项  
32. //使用的是glib命令行解析库  
33.     context = g_option_context_new(NULL);  
34. //就是根据options定义的内容,自动解析到对应的变量中了  
35. //详细见2.2.2  
36.     g_option_context_add_main_entries(context, options, NULL);  
37.   
38. if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {  
39. if (err != NULL) {  
40. "%s\n", err->message);  
41.             g_error_free(err);  
42. else  
43. "An unknown error occurred\n");  
44.         exit(1);  
45.     }  
46.   
47.     g_option_context_free(context);  
48. //下面就是根据上面解析得到的值来看是否需要做一些对应的操作  
49. //从init rc中,我们可以看到只有一个-n的参数,但是,我们看是G_OPTION_FLAG_REVERS,猜猜看吧,是的,就是反转的意思,所以option_detach还是false,其它的就都可以忽略了  
50. if (option_version == TRUE) {  
51. "%s\n", VERSION);  
52.         exit(0);  
53.     }  
54.   
55. if (option_udev == TRUE) {  
56. int err;  
57.   
58.         option_detach = TRUE;  
59.         err = connect_dbus();  
60. if (err < 0) {  
61. if (err == -EALREADY)  
62.                 exit(0);  
63.             exit(1);  
64.         }  
65.     }  
66. //后台运行,这里也就不去  
67. if (option_detach == TRUE && option_udev == FALSE) {  
68. if (daemon(0, 0)) {  
69. "Can't start daemon");  
70.             exit(1);  
71.         }  
72.     }  
73. //重新设置权限  
74.     umask(0077);  
75. //bt log的初始化,这里就不关心了,android中若想打印log需要重新修改  
76.     __btd_log_init(option_debug, option_detach);  
77. //设置一个signal的处理函数,不一一看了,关系不大  
78. sizeof(sa));  
79.     sa.sa_flags = SA_NOCLDSTOP;  
80.     sa.sa_handler = sig_term;  
81.     sigaction(SIGTERM, &sa, NULL);  
82.     sigaction(SIGINT,  &sa, NULL);  
83.   
84.     sa.sa_handler = sig_debug;  
85.     sigaction(SIGUSR2, &sa, NULL);  
86.   
87.     sa.sa_handler = SIG_IGN;  
88.     sigaction(SIGPIPE, &sa, NULL);  
89. //加载配置文件  
90. "/main.conf");  
91. //解析配置文件,这里就是根据main.conf中的配置进行相应的设置  
92. //详细分析见2.2.3  
93.     parse_config(config);  
94. //这里就是初始化dbus  
95.     agent_init();  
96.   
97. if (option_udev == FALSE) {  
98. //连接dbus  
99. if (connect_dbus() < 0) {  
100. "Unable to get on D-Bus");  
101.             exit(1);  
102.         }  
103. else {  
104. if (daemon(0, 0)) {  
105. "Can't start daemon");  
106.             exit(1);  
107.         }  
108.     }  
109. //启动sdp server,详细分析见2.2.4  
110.     start_sdp_server(mtu, main_opts.deviceid, SDP_SERVER_COMPAT);  
111. //在main.conf中attrib_server=false,所以这里就不进入了  
112. if (main_opts.attrib_server) {  
113. if (attrib_server_init() < 0)  
114. "Can't initialize attribute server");  
115.     }  
116. /* Loading plugins has to be done after D-Bus has been setup since
117.      * the plugins might wanna expose some paths on the bus. However the
118.      * best order of how to init various subsystems of the Bluetooth
119.      * daemon needs to be re-worked. */  
120. //从注释来看,plugins的加载最好是在D-Bus已经建立完成的基础上。  
121. //他们也认为这个地方做好再重写一下,我们就先将就着看看吧  
122. //这里的option_plugin和option_noplugin都是null,因为我们的bluetoothd中并没有他们的参数  
123. //包含了hciops,audio,input,network,health  
124. //具体参见2.2.5中  
125.     plugin_init(config, option_plugin, option_noplugin);  
126. //创建主循环  
127.     event_loop = g_main_loop_new(NULL, FALSE);  
128. //adapter的ops的建立,详细分析见2.2.6  
129. if (adapter_ops_setup() < 0) {  
130. "adapter_ops_setup failed");  
131.         exit(1);  
132.     }  
133. //会根据remember_powered参数来决定是否需要做什么,我们这里是是false,所以,没有做什么,直接ruturn。  
134.     rfkill_init();  
135.   
136. "Entering main loop");  
137. //进入主循环,就卡在这边了。  
138. //对主循环的影响都在上面的那些signal的处理函数中,我们可以理解,没有什么异常就会卡在这边了,知道蓝牙关闭才会退出了  
139.     g_main_loop_run(event_loop);  
140. //之后的内容就不再详细分析了  
141.     ……  
142. }