Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android源碼分析]hciops的初始化

Android源碼分析]hciops的初始化

編輯:關於Android編程

凡是真正分析過bluez代碼或者debug過相關bug的童鞋,一定對hciops非常熟悉吧,是的,它是各個event的處理中心,承接著controller到上層host的各個方面的交互,本文就來詳細分析一下它的初始化過程。   2.3.5.2 add_plugin分析   add_plugin只是單純地把plugin加入到系統裡面,或者就是plugin的初始化,來看看吧   [cpp]  static gboolean add_plugin(void *handle, struct bluetooth_plugin_desc *desc)   {       struct bluetooth_plugin *plugin;       //檢查是否有init函數,沒有直接返回       if (desc->init == NULL)           return FALSE;       //檢查一下version是不是匹配,那邊初始化的時候就是用的VERSION,所以,沒有問題       if (g_str_equal(desc->version, VERSION) == FALSE) {           error("Version mismatch for %s", desc->name);           return FALSE;       }          DBG("Loading %s plugin", desc->name);       //初始化bluetooth_plugin結構體       plugin = g_try_new0(struct bluetooth_plugin, 1);       if (plugin == NULL)           return FALSE;          plugin->handle = handle;       plugin->active = FALSE;       plugin->desc = desc;       //按照priority來加入到plugins list中       plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);          return TRUE;   }   2.3.5.3  hciops的init函數分析   初略一看,hciops的init函數還是蠻簡單的,就是一句話:   [cpp]  static int hciops_init(void)   {       DBG("");       //這個我們比較熟悉,就是把hci_ops注冊進來呗       //這裡我們詳細分析一下,究竟做了些什麼       return btd_register_adapter_ops(&hci_ops, FALSE);   }   [cpp]  int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority)   {       //其實就是判斷setup函數是否存在,具體的帶用會在後面的adapter_ops_setup中       if (ops->setup == NULL)           return -EINVAL;       //根據priority,決定吧ops加入到ops_candidates的頭還是尾中,這個還是蠻簡單的吧       if (priority)           ops_candidates = g_slist_prepend(ops_candidates, ops);       else           ops_candidates = g_slist_append(ops_candidates, ops);          return 0;   }   2.3.6 adapter_ops_setup的分析   其實這個函數很簡單,就是setuphciops,我們來分析一下   [cpp]  int adapter_ops_setup(void)   {       GSList *l;       int ret;       //ops_candidates是在hciops的init函數中加入的       if (!ops_candidates)           return -EINVAL;       //這裡也沒有別的,就只有hciops,調用他的setup即可       for (l = ops_candidates; l != NULL; l = g_slist_next(l)) {           struct btd_adapter_ops *ops = l->data;           //Setup見下面的分析           ret = ops->setup();           if (ret < 0)               continue;           //同時需要把這個ops和adapter_ops相關聯           adapter_ops = ops;           break;       }          return ret;   }   hciops的setup函數也是在對應的ops中定義的,我們去看一下:   [cpp]  static int hciops_setup(void)   {       struct sockaddr_hci addr;       struct hci_filter flt;       GIOChannel *ctl_io, *child_io;       int sock, err;          DBG("");       //先判斷一下有沒有pipe過       if (child_pipe[0] != -1)           return -EALREADY;       //創建一個管道,child_pipe[0]為讀入端,child_pipe[1]為寫入端       if (pipe(child_pipe) < 0) {           err = -errno;           error("pipe(): %s (%d)", strerror(-err), -err);           return err;       }          //一個io channel進行監聽,若是有數據,就會去讀了       child_io = g_io_channel_unix_new(child_pipe[0]);       g_io_channel_set_close_on_unref(child_io, TRUE);       child_io_id = g_io_add_watch(child_io,                   G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,                   child_exit, NULL);       g_io_channel_unref(child_io);       //創建並且bind hci socket       /* Create and bind HCI socket */       sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);       if (sock < 0) {           err = -errno;           error("Can't open HCI socket: %s (%d)", strerror(-err),                                   -err);           return err;       }          /* Set filter */       //這裡只關注bluez stack的internal的event,這個就是DEV_REG,DEV_UP之類的event的處理了       hci_filter_clear(&flt);       hci_filter_set_ptype(HCI_EVENT_PKT, &flt);       hci_filter_set_event(EVT_STACK_INTERNAL, &flt);       if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {           err = -errno;           error("Can't set filter: %s (%d)", strerror(-err), -err);           return err;       }          memset(&addr, 0, sizeof(addr));       addr.hci_family = AF_BLUETOOTH;       addr.hci_dev = HCI_DEV_NONE;       //bind       if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {           err = -errno;           error("Can't bind HCI socket: %s (%d)", strerror(-err), -err);           return err;       }       //再建一個io channel來監聽它       ctl_io = g_io_channel_unix_new(sock);       g_io_channel_set_close_on_unref(ctl_io, TRUE);       //回調函數是io stack event,等用到的時候再具體分析好了,詳細分析見2.3       ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL);       g_io_channel_unref(ctl_io);       //這裡設置了一個空閒任務,就是空閒的時候,我們會執行init_known_adapters函數,從這裡可以看出這個函數的優先級必然不高,但是他仍然會執行,所以,我們可以去看一下       g_idle_add(init_known_adapters, GINT_TO_POINTER(sock));       return 0;   }   空閒的時候執行函數:init_known_adapters的分析   [cpp]   static gboolean init_known_adapters(gpointer user_data)   {       struct hci_dev_list_req *dl;       struct hci_dev_req *dr;       int i, err, ctl = GPOINTER_TO_INT(user_data);       size_t req_size;          DBG("");          req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t);       //申請devcie list空間       dl = g_try_malloc0(req_size);       if (!dl) {           error("Can't allocate devlist buffer");           return FALSE;       }       //最多16個設備       dl->dev_num = HCI_MAX_DEV;       dr = dl->dev_req;       //通過ioctl得到device 的列表       if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) {           err = -errno;           error("Can't get device list: %s (%d)", strerror(-err), -err);           g_free(dl);           return FALSE;       }          for (i = 0; i < dl->dev_num; i++, dr++) {           struct dev_info *dev;           gboolean already_up;       //這裡檢查是否up,bluetootd初始化的時候應該已經up了           already_up = hci_test_bit(HCI_UP, &dr->dev_opt);       //初始化device,這個在2.3.1中進行詳細分析           dev = init_device(dr->dev_id, already_up);           if (dev == NULL)               continue;              if (!dev->already_up)               continue;              init_conn_list(dr->dev_id);              dev->pending = 0;       //設置pending version位           hci_set_bit(PENDING_VERSION, &dev->pending);       //發送read local version的cmd           hci_send_cmd(dev->sk, OGF_INFO_PARAM,                       OCF_READ_LOCAL_VERSION, 0, NULL);       //同時發送HCI_DEV_UP的event,這個在2.3.2中分析           device_event(HCI_DEV_UP, dr->dev_id);       }          g_free(dl);          return FALSE;   }    
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved