[android源码分析]bluetoothd service的启动的总体流程分析

本文详细解析了Android蓝牙服务bluetoothd的启动流程,包括权限设置、命令行参数解析、后台运行设置、日志初始化、配置文件加载及解析等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

servicebluetoothd /system/bin/bluetoothd -n

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

[plain] view plain copy
  1. #
  2. #bluetoothd
  3. #
  4. include$(CLEAR_VARS)
  5. LOCAL_SHARED_LIBRARIES:=\
  6. libbluetoothd
  7. LOCAL_MODULE:=bluetoothd

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

  1. intmain(intargc,char*argv[])
  2. {
  3. GOptionContext*context;
  4. GError*err=NULL;
  5. structsigactionsa;
  6. uint16_tmtu=0;
  7. GKeyFile*config;
  8. //这个函数就是用来设置uid和capability的,他主要是使得该应用在访问kernel的时候能够有权限
  9. //从注册可以看到,说目前的androidinitrc并不支持权限的赋予,所以只能出此下策,毫无疑问,我们需要走到这个ifdef中
  10. //当然我们也可以从理论上去check一下,在Android.mk中是有这个宏的define的
  11. #ifdefANDROID_SET_AID_AND_CAP
  12. /*UnfortunatelyAndroid'sinit.rcdoesnotyetsupportapplying
  13. *capabilities.Sowemustdoitin-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. #ifdefHAVE_CAPNG
  24. /*Dropcapabilities*/
  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. if(g_option_context_parse(context,&argc,&argv,&err)==FALSE){
  38. if(err!=NULL){
  39. g_printerr("%s\n",err->message);
  40. g_error_free(err);
  41. }else
  42. g_printerr("Anunknownerroroccurred\n");
  43. exit(1);
  44. }
  45. g_option_context_free(context);
  46. //下面就是根据上面解析得到的值来看是否需要做一些对应的操作
  47. //从initrc中,我们可以看到只有一个-n的参数,但是,我们看是G_OPTION_FLAG_REVERS,猜猜看吧,是的,就是反转的意思,所以option_detach还是false,其它的就都可以忽略了
  48. if(option_version==TRUE){
  49. printf("%s\n",VERSION);
  50. exit(0);
  51. }
  52. if(option_udev==TRUE){
  53. interr;
  54. option_detach=TRUE;
  55. err=connect_dbus();
  56. if(err<0){
  57. if(err==-EALREADY)
  58. exit(0);
  59. exit(1);
  60. }
  61. }
  62. //后台运行,这里也就不去
  63. if(option_detach==TRUE&&option_udev==FALSE){
  64. if(daemon(0,0)){
  65. perror("Can'tstartdaemon");
  66. exit(1);
  67. }
  68. }
  69. //重新设置权限
  70. umask(0077);
  71. //btlog的初始化,这里就不关心了,android中若想打印log需要重新修改
  72. __btd_log_init(option_debug,option_detach);
  73. //设置一个signal的处理函数,不一一看了,关系不大
  74. memset(&sa,0,sizeof(sa));
  75. sa.sa_flags=SA_NOCLDSTOP;
  76. sa.sa_handler=sig_term;
  77. sigaction(SIGTERM,&sa,NULL);
  78. sigaction(SIGINT,&sa,NULL);
  79. sa.sa_handler=sig_debug;
  80. sigaction(SIGUSR2,&sa,NULL);
  81. sa.sa_handler=SIG_IGN;
  82. sigaction(SIGPIPE,&sa,NULL);
  83. //加载配置文件
  84. config=load_config(CONFIGDIR"/main.conf");
  85. //解析配置文件,这里就是根据main.conf中的配置进行相应的设置
  86. //详细分析见2.2.3
  87. parse_config(config);
  88. //这里就是初始化dbus
  89. agent_init();
  90. if(option_udev==FALSE){
  91. //连接dbus
  92. if(connect_dbus()<0){
  93. error("UnabletogetonD-Bus");
  94. exit(1);
  95. }
  96. }else{
  97. if(daemon(0,0)){
  98. perror("Can'tstartdaemon");
  99. exit(1);
  100. }
  101. }
  102. //启动sdpserver,详细分析见2.2.4
  103. start_sdp_server(mtu,main_opts.deviceid,SDP_SERVER_COMPAT);
  104. //在main.conf中attrib_server=false,所以这里就不进入了
  105. if(main_opts.attrib_server){
  106. if(attrib_server_init()<0)
  107. error("Can'tinitializeattributeserver");
  108. }
  109. /*LoadingpluginshastobedoneafterD-Bushasbeensetupsince
  110. *thepluginsmightwannaexposesomepathsonthebus.Howeverthe
  111. *bestorderofhowtoinitvarioussubsystemsoftheBluetooth
  112. *daemonneedstobere-worked.*/
  113. //从注释来看,plugins的加载最好是在D-Bus已经建立完成的基础上。
  114. //他们也认为这个地方做好再重写一下,我们就先将就着看看吧
  115. //这里的option_plugin和option_noplugin都是null,因为我们的bluetoothd中并没有他们的参数
  116. //包含了hciops,audio,input,network,health
  117. //具体参见2.2.5中
  118. plugin_init(config,option_plugin,option_noplugin);
  119. //创建主循环
  120. event_loop=g_main_loop_new(NULL,FALSE);
  121. //adapter的ops的建立,详细分析见2.2.6
  122. if(adapter_ops_setup()<0){
  123. error("adapter_ops_setupfailed");
  124. exit(1);
  125. }
  126. //会根据remember_powered参数来决定是否需要做什么,我们这里是是false,所以,没有做什么,直接ruturn。
  127. rfkill_init();
  128. DBG("Enteringmainloop");
  129. //进入主循环,就卡在这边了。
  130. //对主循环的影响都在上面的那些signal的处理函数中,我们可以理解,没有什么异常就会卡在这边了,知道蓝牙关闭才会退出了
  131. g_main_loop_run(event_loop);
  132. //之后的内容就不再详细分析了
  133. ……
  134. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值