2013年10月23日09:20:30
閱讀數:4571
本篇文章將會從總體流程上解釋一下每一個函數的意義,具體的每一個函數的解釋將是一個很長的過程,後面的文章中我將會針對每一個有意義的函數來具體分析。
在具體分析bluetoothdservice的啟動之前,我們先來看一下bluetoothd service究竟是什麼,他同樣定義在init.rc中:
servicebluetoothd /system/bin/bluetoothd -n
所以,很清楚,他就是執行bluetoothd這個應用。那麼bluetoothd是由哪個文件編譯出來的呢,搜索一下就會在bluez下面的src中的Android.mk發現其踪跡:
- #
- # bluetoothd
- #
- include $(CLEAR_VARS)
- LOCAL_SHARED_LIBRARIES := \
- libbluetoothd
- LOCAL_MODULE:=bluetoothd
所以,很清楚了,我們就在src目錄下面看一下了,作為一個應用程序,第一個映入我們眼簾的肯定就是main了,正好下面有一個main.c,然後裡面還有一個main函數,哈哈,你懂的:
- int main( int argc, char *argv[])
- {
- GOptionContext *context;
- GError *err = NULL;
- struct sigaction sa;
- uint16_t mtu = 0;
- GKeyFile *config;
- //這個函數就是用來設置uid和capability的,他主要是使得該應用在訪問kernel的時候能夠有權限
- //從註冊可以看到,說目前的android init rc並不支持權限的賦予,所以只能出此下策,毫無疑問,我們需要走到這個ifdef中
- //當然我們也可以從理論上去check一下,在Android.mk中是有這個宏的define的
- #ifdef ANDROID_SET_AID_AND_CAP
- /* Unfortunately Android's init.rc does not yet support applying
- * capabilities. So we must do it in-process. */
- void *android_set_aid_and_cap( void );
- //這個就是設置uid為AID_BLUETOOTH,
- //設置capbility為CAP_NET_RAW| CAP_NET_ADMIN| CAP_NET_BIND_SERVICE
- android_set_aid_and_cap();
- #endif
- //默認的初始化,詳細分析見2.2.1
- init_defaults();
- //既然我們上面已經想法設法得到權限了,這裡就必然不會再把權限釋放了。
- //這個ifdef是不會進去了
- #ifdef HAVE_CAPNG
- /* Drop capabilities */
- capng_clear(CAPNG_SELECT_BOTH);
- capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
- CAP_NET_BIND_SERVICE, CAP_NET_ADMIN,
- CAP_NET_RAW, CAP_IPC_LOCK, -1);
- capng_apply(CAPNG_SELECT_BOTH);
- #endif
- //這裡是解析命令項
- //使用的是glib命令行解析庫
- context = g_option_context_new(NULL);
- //就是根據options定義的內容,自動解析到對應的變量中了
- //詳細見2.2.2
- g_option_context_add_main_entries(context, options, NULL);
- if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {
- if (err != NULL) {
- g_printerr( "%s\n" , err->message);
- g_error_free(err);
- } else
- g_printerr( "An unknown error occurred\n" );
- exit(1);
- }
- g_option_context_free(context);
- //下面就是根據上面解析得到的值來看是否需要做一些對應的操作
- //從init rc中,我們可以看到只有一個-n的參數,但是,我們看是G_OPTION_FLAG_REVERS,猜猜看吧,是的,就是反轉的意思,所以option_detach還是false,其它的就都可以忽略了
- if (option_version == TRUE) {
- printf( "%s\n" , VERSION);
- exit(0);
- }
- if (option_udev == TRUE) {
- int err;
- option_detach = TRUE;
- err = connect_dbus();
- if (err < 0) {
- if (err == -EALREADY)
- exit(0);
- exit(1);
- }
- }
- //後台運行,這裡也就不去
- if (option_detach == TRUE && option_udev == FALSE) {
- if (daemon(0, 0)) {
- perror( "Can't start daemon" );
- exit(1);
- }
- }
- //重新設置權限
- umask(0077);
- //bt log的初始化,這裡就不關心了,android中若想打印log需要重新修改
- __btd_log_init(option_debug, option_detach);
- //設置一個signal的處理函數,不一一看了,關係不大
- memset(&sa, 0, sizeof (sa));
- sa.sa_flags = SA_NOCLDSTOP;
- sa.sa_handler = sig_term;
- sigaction(SIGTERM, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sa.sa_handler = sig_debug;
- sigaction(SIGUSR2, &sa, NULL);
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
- //加載配置文件
- config = load_config(CONFIGDIR "/main.conf" );
- //解析配置文件,這裡就是根據main.conf中的配置進行相應的設置
- //詳細分析見2.2.3
- parse_config(config);
- //這裡就是初始化dbus
- agent_init();
- if (option_udev == FALSE) {
- //連接dbus
- if (connect_dbus() < 0) {
- error( "Unable to get on D-Bus" );
- exit(1);
- }
- } else {
- if (daemon(0, 0)) {
- perror( "Can't start daemon" );
- exit(1);
- }
- }
- //啟動sdp server,詳細分析見2.2.4
- start_sdp_server(mtu, main_opts.deviceid, SDP_SERVER_COMPAT);
- //在main.conf中attrib_server=false,所以這裡就不進入了
- if (main_opts.attrib_server) {
- if (attrib_server_init() < 0)
- error( "Can't initialize attribute server" );
- }
- /* Loading plugins has to be done after D-Bus has been setup since
- * the plugins might wanna expose some paths on the bus. However the
- * best order of how to init various subsystems of the Bluetooth
- * daemon needs to be re-worked. */
- //從註釋來看,plugins的加載最好是在D-Bus已經建立完成的基礎上。
- //他們也認為這個地方做好再重寫一下,我們就先將就著看看吧
- //這裡的option_plugin和option_noplugin都是null,因為我們的bluetoothd中並沒有他們的參數
- //包含了hciops,audio,input,network,health
- //具體參見2.2.5中
- plugin_init(config, option_plugin, option_noplugin);
- //創建主循環
- event_loop = g_main_loop_new(NULL, FALSE);
- //adapter的ops的建立,詳細分析見2.2.6
- if (adapter_ops_setup() < 0) {
- error( "adapter_ops_setup failed" );
- exit(1);
- }
- //會根據remember_powered參數來決定是否需要做什麼,我們這裡是是false,所以,沒有做什麼,直接ruturn。
- rfkill_init();
- DBG( "Entering main loop" );
- //進入主循環,就卡在這邊了。
- //對主循環的影響都在上面的那些signal的處理函數中,我們可以理解,沒有什麼異常就會卡在這邊了,知道藍牙關閉才會退出了
- g_main_loop_run(event_loop);
- //之後的內容就不再詳細分析了
- ……
- }
沒有留言:
張貼留言