热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UbuntuBluetooth配对过程

bluetoothd运行时(main函数启动时),加载plugin(调用plugin_init函数):gbooleanplugin_init(GKeyFile*config){GSList*list;&nb

bluetoothd运行时(main函数启动时),加载plugin(调用plugin_init函数):

  1. gboolean plugin_init(GKeyFile *config)  
  2. {  
  3.     GSList *list;  
  4.     GDir *dir;  
  5.     const gchar *file;  
  6.     gchar **disabled;  
  7.     unsigned int i;  
  8.   
  9.     /* Make a call to BtIO API so its symbols got resolved before the 
  10.      * plugins are loaded. */  
  11.     bt_io_error_quark();  
  12.   
  13.     if (config)  
  14.         disabled = g_key_file_get_string_list(config, "General",  
  15.                             "DisablePlugins",  
  16.                             NULL, NULL);  
  17.     else  
  18.         disabled = NULL;  
  19.   
  20.     info("Loading builtin plugins");  
  21.   
  22.     //add default plugins, those plugins always need for bluetoothd runing   
  23.     //those plugins will add to the global link named plugins   
  24.     for (i = 0; __bluetooth_builtin[i]; i++) {  
  25.         if (is_disabled(__bluetooth_builtin[i]->name, disabled))  
  26.             continue;  
  27.   
  28.         add_plugin(NULL,  __bluetooth_builtin[i]);  
  29.     }  
  30.   
  31.     if (strlen(PLUGINDIR) == 0) {  
  32.         g_strfreev(disabled);  
  33.         goto start;  
  34.     }  
  35.   
  36.     info("Loading plugins %s\n", PLUGINDIR);  
  37.   
  38.     dir = g_dir_open(PLUGINDIR, 0, NULL);  
  39.     if (!dir) {  
  40.         g_strfreev(disabled);  
  41.         goto start;  
  42.     }  
  43.   
  44.     //add user plugins, those plugins stored in PLUGINDIR path, and the    
  45.     //PLUGINDIR = /usr/local/lib/bluetooth/plugins. The bluetoothd will   
  46.     //find all those plugins which name *.so, and open them, get the method   
  47.     //named bluetooth_plugin_desc, it will also add those plugins to the   
  48.     //plugins links.   
  49.     while ((file = g_dir_read_name(dir)) != NULL) {  
  50.         struct bluetooth_plugin_desc *desc;  
  51.         void *handle;  
  52.         gchar *filename;  
  53.   
  54.         if (g_str_has_prefix(file, "lib") == TRUE ||  
  55.                 g_str_has_suffix(file, ".so") == FALSE)  
  56.             continue;  
  57.   
  58.         if (is_disabled(file, disabled))  
  59.             continue;  
  60.   
  61.         filename = g_build_filename(PLUGINDIR, file, NULL);  
  62.   
  63.         handle = dlopen(filename, RTLD_NOW);  
  64.         if (handle == NULL) {  
  65.             error("Can't load plugin %s: %s", filename,  
  66.                                 dlerror());  
  67.             g_free(filename);  
  68.             continue;  
  69.         }  
  70.   
  71.         g_free(filename);  
  72.   
  73.         desc = dlsym(handle, "bluetooth_plugin_desc");  
  74.         if (desc == NULL) {  
  75.             error("Can't load plugin description: %s", dlerror());  
  76.             dlclose(handle);  
  77.             continue;  
  78.         }  
  79.   
  80.         if (add_plugin(handle, desc) == FALSE)  
  81.             dlclose(handle);  
  82.     }  
  83.   
  84.     g_dir_close(dir);  
  85.   
  86.     g_strfreev(disabled);  
  87.   
  88. start:  
  89.     //init all of the plugins by calling the plugins init function   
  90.     for (list = plugins; list; list = list->next) {  
  91.         struct bluetooth_plugin *plugin = list->data;  
  92.   
  93.         if (plugin->desc->init() < 0) {  
  94.             error("Failed to init %s plugin", plugin->desc->name);  
  95.             continue;  
  96.         }  
  97.         info("plugins active\n");  
  98.         plugin->active = TRUE;  
  99.     }  
  100.   
  101.     return TRUE;  
  102. }  
函数中__bluetooth_builtin结构体为存储加载的plugin的入口地址,这些地址是通过连接宏##连接的,其中包含hciops模块的加载。此函数将结构体中的地址加载成plugins链表,然后循环调用每个模块的初始化init函数。对应于hciops模块,调用初始化函数为hciops_init。__bluetooth_builtin结构体和连接宏定义如下:
  1. static struct bluetooth_plugin_desc *__bluetooth_builtin[] = {  
  2.   &__bluetooth_builtin_audio,  
  3.   &__bluetooth_builtin_input,  
  4.   &__bluetooth_builtin_serial,  
  5.   &__bluetooth_builtin_network,  
  6.   &__bluetooth_builtin_service,  
  7.   &__bluetooth_builtin_hciops,  
  8.   &__bluetooth_builtin_hal,  
  9.   &__bluetooth_builtin_storage,  
  10.   NULL  
  11. };  
 
  1. #define BLUETOOTH_PLUGIN_DEFINE(name, version, priority, init, exit) \   
  2.         struct bluetooth_plugin_desc __bluetooth_builtin_ ## name = { \  
  3.             #name, version, priority, init, exit \   
  4.         };  
hciops模块初始化:
  1. static int hciops_init(void)  
  2. {  
  3.     info("hciops_init\n");  
  4.     return btd_register_adapter_ops(&hci_ops);  
  5. }  

 
  1. int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops)  
  2. {  
  3.     /* Already registered */  
  4.     if (adapter_ops)  
  5.         return -EALREADY;  
  6.   
  7.     if (btd_adapter_ops->setup == NULL)  
  8.         return -EINVAL;  
  9.   
  10.     adapter_ops = btd_adapter_ops;  
  11.   
  12.     return 0;  
  13. }  
这个初始化函数将静态hci_ops结构体变量赋值给了全局变量adapter_ops。hci_ops结构定义:
  1. static struct btd_adapter_ops hci_ops = {  
  2.     .setup = hciops_setup,  
  3.     .cleanup = hciops_cleanup,  
  4.     .start = hciops_start,  
  5.     .stop = hciops_stop,  
  6.     .set_powered = hciops_powered,  
  7.     .set_connectable = hciops_connectable,  
  8.     .set_discoverable = hciops_discoverable,  
  9.     .set_limited_discoverable = hciops_set_limited_discoverable,  
  10.     .start_discovery = hciops_start_discovery,  
  11.     .stop_discovery = hciops_stop_discovery,  
  12.     .resolve_name = hciops_resolve_name,  
  13.     .cancel_resolve_name = hciops_cancel_resolve_name,  
  14.     .set_name = hciops_set_name,  
  15.     .read_name = hciops_read_name,  
  16.     .set_class = hciops_set_class,  
  17. };  
在plugin_init加载完plugins后,调用了adapter_ops_setup函数来启动HCI适配层:

[cpp] view plaincopyprint?
  1. int adapter_ops_setup(void)  
  2. {  
  3.     if (!adapter_ops)  
  4.         return -EINVAL;  
  5.   
  6.     return adapter_ops->setup();  
  7. }  
这个函数即调用里 hci_ops静态全局变量的setup函数,看hci_ops全局变量的定义,.setup指向hciops_setup函数:
  1. static int hciops_setup(void)  
  2. {  
  3.     struct sockaddr_hci addr;  
  4.     struct hci_filter flt;  
  5.     GIOChannel *ctl_io, *child_io;  
  6.     int sock, err;  
  7.   
  8.     info("hciops_setup\n");  
  9.   
  10.     if (child_pipe[0] != -1)  
  11.         return -EALREADY;  
  12.   
  13.     if (pipe(child_pipe) < 0) {  
  14.         err = errno;  
  15.         error("pipe(): %s (%d)", strerror(err), err);  
  16.         return -err;  
  17.     }  
  18.   
  19.     child_io = g_io_channel_unix_new(child_pipe[0]);  
  20.     g_io_channel_set_close_on_unref(child_io, TRUE);  
  21.     child_io_id = g_io_add_watch(child_io,  
  22.                 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,  
  23.                 child_exit, NULL);  
  24.     g_io_channel_unref(child_io);  
  25.   
  26.     /* Create and bind HCI socket */  
  27.     sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);  
  28.     if (sock < 0) {  
  29.         err = errno;  
  30.         error("Can't open HCI socket: %s (%d)", strerror(err),  
  31.                                 err);  
  32.         return -err;  
  33.     }  
  34.   
  35.     /* Set filter */  
  36.     hci_filter_clear(&flt);  
  37.     hci_filter_set_ptype(HCI_EVENT_PKT, &flt);  
  38.     hci_filter_set_event(EVT_STACK_INTERNAL, &flt);  
  39.     if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt,  
  40.                             sizeof(flt)) < 0) {  
  41.         err = errno;  
  42.         error("Can't set filter: %s (%d)", strerror(err), err);  
  43.         return -err;  
  44.     }  
  45.   
  46.     memset(&addr, 0, sizeof(addr));  
  47.     addr.hci_family = AF_BLUETOOTH;  
  48.     addr.hci_dev = HCI_DEV_NONE;  
  49.     if (bind(sock, (struct sockaddr *) &addr,  
  50.                             sizeof(addr)) < 0) {  
  51.         err = errno;  
  52.         error("Can't bind HCI socket: %s (%d)",  
  53.                             strerror(err), err);  
  54.         return -err;  
  55.     }  
  56.   
  57.     ctl_io = g_io_channel_unix_new(sock);  
  58.     g_io_channel_set_close_on_unref(ctl_io, TRUE);  
  59.   
  60.     ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL);  
  61.   
  62.     g_io_channel_unref(ctl_io);  
  63.   
  64.     /* Initialize already connected devices */  
  65.     return init_known_adapters(sock);  
  66. }  
在函数的最后,调用里init_known_adapters启动里已知的hci设备,初始化HCI适配器:
  1. static int init_known_adapters(int ctl)  
  2. {  
  3.     struct hci_dev_list_req *dl;  
  4.     struct hci_dev_req *dr;  
  5.     int i, err;  
  6.   
  7.     info("init_known_adapters\n");  
  8.   
  9.     dl = g_try_malloc0(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t));  
  10.     if (!dl) {  
  11.         err = errno;  
  12.         error("Can't allocate devlist buffer: %s (%d)",  
  13.                             strerror(err), err);  
  14.         return -err;  
  15.     }  
  16.   
  17.     dl->dev_num = HCI_MAX_DEV;  
  18.     dr = dl->dev_req;  
  19.   
  20.     if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {  
  21.         err = errno;  
  22.         error("Can't get device list: %s (%d)",  
  23.                             strerror(err), err);  
  24.         g_free(dl);  
  25.         return -err;  
  26.     }  
  27.   
  28.     for (i = 0; i < dl->dev_num; i++, dr++) {  
  29.         device_event(HCI_DEV_REG, dr->dev_id);  
  30.   
  31.         if (hci_test_bit(HCI_UP, &dr->dev_opt)){  
  32.             info("here start the hci device\n");  
  33.             "color:#000000;">device_event(HCI_DEV_UP, dr->dev_id);  
  34.         }  
  35.     }  
  36.   
  37.     g_free(dl);  
  38.     return 0;  
  39. }  

推荐阅读
  • vue使用
    关键词: ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
author-avatar
诺亚方舟菲芘袁子陽
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有