歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Ubuntu Bluetooth 配對過程

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.             <span style="color:#000000;">device_event(HCI_DEV_UP, dr->dev_id);</span>  
  34.         }  
  35.     }  
  36.   
  37.     g_free(dl);  
  38.     return 0;  
  39. }  
Copyright © Linux教程網 All Rights Reserved