歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Ubuntu Bluetooth 配對過程

Ubuntu Bluetooth 配對過程

日期:2017/3/1 10:20:26   编辑:Linux編程

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. /* Make a call to BtIO API so its symbols got resolved before the
  9. * plugins are loaded. */
  10. bt_io_error_quark();
  11. if (config)
  12. disabled = g_key_file_get_string_list(config, "General",
  13. "DisablePlugins",
  14. NULL, NULL);
  15. else
  16. disabled = NULL;
  17. info("Loading builtin plugins");
  18. //add default plugins, those plugins always need for bluetoothd runing
  19. //those plugins will add to the global link named plugins
  20. for (i = 0; __bluetooth_builtin[i]; i++) {
  21. if (is_disabled(__bluetooth_builtin[i]->name, disabled))
  22. continue;
  23. add_plugin(NULL, __bluetooth_builtin[i]);
  24. }
  25. if (strlen(PLUGINDIR) == 0) {
  26. g_strfreev(disabled);
  27. goto start;
  28. }
  29. info("Loading plugins %s\n", PLUGINDIR);
  30. dir = g_dir_open(PLUGINDIR, 0, NULL);
  31. if (!dir) {
  32. g_strfreev(disabled);
  33. goto start;
  34. }
  35. //add user plugins, those plugins stored in PLUGINDIR path, and the
  36. //PLUGINDIR = /usr/local/lib/bluetooth/plugins. The bluetoothd will
  37. //find all those plugins which name *.so, and open them, get the method
  38. //named bluetooth_plugin_desc, it will also add those plugins to the
  39. //plugins links.
  40. while ((file = g_dir_read_name(dir)) != NULL) {
  41. struct bluetooth_plugin_desc *desc;
  42. void *handle;
  43. gchar *filename;
  44. if (g_str_has_prefix(file, "lib") == TRUE ||
  45. g_str_has_suffix(file, ".so") == FALSE)
  46. continue;
  47. if (is_disabled(file, disabled))
  48. continue;
  49. filename = g_build_filename(PLUGINDIR, file, NULL);
  50. handle = dlopen(filename, RTLD_NOW);
  51. if (handle == NULL) {
  52. error("Can't load plugin %s: %s", filename,
  53. dlerror());
  54. g_free(filename);
  55. continue;
  56. }
  57. g_free(filename);
  58. desc = dlsym(handle, "bluetooth_plugin_desc");
  59. if (desc == NULL) {
  60. error("Can't load plugin description: %s", dlerror());
  61. dlclose(handle);
  62. continue;
  63. }
  64. if (add_plugin(handle, desc) == FALSE)
  65. dlclose(handle);
  66. }
  67. g_dir_close(dir);
  68. g_strfreev(disabled);
  69. start:
  70. //init all of the plugins by calling the plugins init function
  71. for (list = plugins; list; list = list->next) {
  72. struct bluetooth_plugin *plugin = list->data;
  73. if (plugin->desc->init() < 0) {
  74. error("Failed to init %s plugin", plugin->desc->name);
  75. continue;
  76. }
  77. info("plugins active\n");
  78. plugin->active = TRUE;
  79. }
  80. return TRUE;
  81. }
函數中__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. if (btd_adapter_ops->setup == NULL)
  7. return -EINVAL;
  8. adapter_ops = btd_adapter_ops;
  9. return 0;
  10. }
這個初始化函數將靜態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. return adapter_ops->setup();
  6. }
這個函數即調用裡 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. info("hciops_setup\n");
  8. if (child_pipe[0] != -1)
  9. return -EALREADY;
  10. if (pipe(child_pipe) < 0) {
  11. err = errno;
  12. error("pipe(): %s (%d)", strerror(err), err);
  13. return -err;
  14. }
  15. child_io = g_io_channel_unix_new(child_pipe[0]);
  16. g_io_channel_set_close_on_unref(child_io, TRUE);
  17. child_io_id = g_io_add_watch(child_io,
  18. G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
  19. child_exit, NULL);
  20. g_io_channel_unref(child_io);
  21. /* Create and bind HCI socket */
  22. sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
  23. if (sock < 0) {
  24. err = errno;
  25. error("Can't open HCI socket: %s (%d)", strerror(err),
  26. err);
  27. return -err;
  28. }
  29. /* Set filter */
  30. hci_filter_clear(&flt);
  31. hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
  32. hci_filter_set_event(EVT_STACK_INTERNAL, &flt);
  33. if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt,
  34. sizeof(flt)) < 0) {
  35. err = errno;
  36. error("Can't set filter: %s (%d)", strerror(err), err);
  37. return -err;
  38. }
  39. memset(&addr, 0, sizeof(addr));
  40. addr.hci_family = AF_BLUETOOTH;
  41. addr.hci_dev = HCI_DEV_NONE;
  42. if (bind(sock, (struct sockaddr *) &addr,
  43. sizeof(addr)) < 0) {
  44. err = errno;
  45. error("Can't bind HCI socket: %s (%d)",
  46. strerror(err), err);
  47. return -err;
  48. }
  49. ctl_io = g_io_channel_unix_new(sock);
  50. g_io_channel_set_close_on_unref(ctl_io, TRUE);
  51. ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL);
  52. g_io_channel_unref(ctl_io);
  53. /* Initialize already connected devices */
  54. return init_known_adapters(sock);
  55. }
在函數的最後,調用裡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. info("init_known_adapters\n");
  7. dl = g_try_malloc0(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t));
  8. if (!dl) {
  9. err = errno;
  10. error("Can't allocate devlist buffer: %s (%d)",
  11. strerror(err), err);
  12. return -err;
  13. }
  14. dl->dev_num = HCI_MAX_DEV;
  15. dr = dl->dev_req;
  16. if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {
  17. err = errno;
  18. error("Can't get device list: %s (%d)",
  19. strerror(err), err);
  20. g_free(dl);
  21. return -err;
  22. }
  23. for (i = 0; i < dl->dev_num; i++, dr++) {
  24. device_event(HCI_DEV_REG, dr->dev_id);
  25. if (hci_test_bit(HCI_UP, &dr->dev_opt)){
  26. info("here start the hci device\n");
  27. <span style="color:#000000;">device_event(HCI_DEV_UP, dr->dev_id);</span>
  28. }
  29. }
  30. g_free(dl);
  31. return 0;
  32. }
Copyright © Linux教程網 All Rights Reserved