Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [Android 源碼解析]bluez中幾個重要plugin的初始化--audio,input,network,health

[Android 源碼解析]bluez中幾個重要plugin的初始化--audio,input,network,health

編輯:關於Android編程

本來只想分析一下hciops的初始化就不再管了,後來發現別的plugin的初始化在後面還是會有涉及,心中想,既然已經分析了這麼多,咋就索性都分析了算了,反正也不差這一點代碼,其它的plugin還有audio,input,network,health。我們只看兩個函數init或者setup。所以看起來應該會比較簡單一點。       2.3.7.1 audio的init分析    audio 這個插件的分析   [cpp]   static int audio_init(void)   {       GKeyFile *config;       gboolean enable_sco;       //得到系統的dbus       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);       if (connection == NULL)           return -EIO;       //得到audio.config文件       config = load_config_file(CONFIGDIR "/audio.conf");       //根據config來進行init       if (audio_manager_init(connection, config, &enable_sco) < 0)           goto failed;   //沒有使能sco,就直接return了,我們這裡的確沒有使能sco,所以,沒什麼好說的,直接return吧       if (!enable_sco)           return 0;   ……          return -EIO;   }   1)audio.conf的內容簡介如下:   [plain]   [General]   Enable=Sink,Control   Disable=Headset,Gateway,Source   Master=false   FastConnectable=false   [A2DP]   SBCSources=1   MPEG12Sources=0      [AVRCP]   InputDeviceName=AVRCP   2)根據config來進行init   [cpp]   int audio_manager_init(DBusConnection *conn, GKeyFile *conf,                               gboolean *enable_sco)   {       char **list;       int i;       gboolean b;       GError *err = NULL;       //dbus的connection的ref+1       connection = dbus_connection_ref(conn);       //沒有config文件,直接結束       if (!conf)           goto proceed;       //config是一個全局變量       config = conf;       /*      //從上面1)中可以得到      Enable=Sink,Control      Disable=Headset,Gateway,Source  */       list = g_key_file_get_string_list(config, "General", "Enable",                           NULL, NULL);       //enable的有哪些,加粗的就是enable的       for (i = 0; list && list[i] != NULL; i++) {           if (g_str_equal(list[i], "Headset"))               enabled.headset = TRUE;           else if (g_str_equal(list[i], "Gateway"))               enabled.gateway = TRUE;           else if (g_str_equal(list[i], "Sink"))               enabled.sink = TRUE;           else if (g_str_equal(list[i], "Source"))               enabled.source = TRUE;           else if (g_str_equal(list[i], "Control"))               enabled.control = TRUE;           else if (g_str_equal(list[i], "Socket"))               enabled.socket = TRUE;           else if (g_str_equal(list[i], "Media"))               enabled.media = TRUE;       }       g_strfreev(list);       //再看disable的,加粗的就是disable的       list = g_key_file_get_string_list(config, "General", "Disable",                           NULL, NULL);       for (i = 0; list && list[i] != NULL; i++) {           if (g_str_equal(list[i], "Headset"))               enabled.headset = FALSE;           else if (g_str_equal(list[i], "Gateway"))               enabled.gateway = FALSE;           else if (g_str_equal(list[i], "Sink"))               enabled.sink = FALSE;           else if (g_str_equal(list[i], "Source"))               enabled.source = FALSE;           else if (g_str_equal(list[i], "Control"))               enabled.control = FALSE;           else if (g_str_equal(list[i], "Socket"))               enabled.socket = FALSE;           else if (g_str_equal(list[i], "Media"))               enabled.media = FALSE;       }   //除了上面這些設置,下面就還有幾個默認的   /*  //這裡是一些默認  //hsp是沒有的,hfp有的  static struct enabled_interfaces enabled = {      .hfp        = TRUE,      .headset    = TRUE,      .gateway    = FALSE,      .sink       = TRUE,      .source     = FALSE,      .control    = TRUE,      .socket     = TRUE, //主要就是這個沒有配置了      .media      = FALSE  };  */       b = g_key_file_get_boolean(config, "General", "AutoConnect", &err);       if (err) { //沒有,所以就是not found,使用默認值,是true           DBG("audio.conf: %s", err->message);           g_clear_error(&err);       } else           auto_connect = b;           b = g_key_file_get_boolean(config, "Headset", "HFP",                       &err);       if (err)           g_clear_error(&err);       else           enabled.hfp = b; //默認是true是支持的          err = NULL;       i = g_key_file_get_integer(config, "Headset", "MaxConnected",                       &err);       if (err) {           DBG("audio.conf: %s", err->message);           g_clear_error(&err);       } else           max_connected_headsets = i; //沒有設置,默認是1   proceed:       //socket是肯定要的       if (enabled.socket)           unix_init();       //media默認是false       if (enabled.media)           btd_register_adapter_driver(&media_server_driver);       //headset也是false       if (enabled.headset)           btd_register_adapter_driver(&headset_server_driver);       //gateway也是flase的       if (enabled.gateway)           btd_register_adapter_driver(&gateway_server_driver);       //這兩個是enable的,把對應的driver加入到adapter_drivers列表中,並調用driver的probe函數,同時把這個driver加入到adapter->loaded_drivers列表中。然而這些有一個前提就是adapter需要up,若是沒有也是不會做的,後面自然會有分析他們的地方,我們到時再繼續分析。       if (enabled.source || enabled.sink)           btd_register_adapter_driver(&a2dp_server_driver);       //control也是enable的       if (enabled.control)           btd_register_adapter_driver(&avrcp_server_driver);       //audio也是enable的,不過這是一個device driver       btd_register_device_driver(&audio_driver);       //這裡是false,sco是沒有enable的       *enable_sco = (enabled.gateway || enabled.headset);          return 0;   }         所以,這裡一共是3個driver注冊了。   3)unix_init分析   [cpp]   //這裡其實是新建一個本地的socket,作為server端,後期會有client可以通過這裡進行交互和通信。   int unix_init(void)   {       GIOChannel *io;       struct sockaddr_un addr = {           AF_UNIX, BT_IPC_SOCKET_NAME       };          int sk, err;       //新建一個stram的socket       sk = socket(PF_LOCAL, SOCK_STREAM, 0);       if (sk < 0) {           err = errno;           error("Can't create unix socket: %s (%d)", strerror(err), err);           return -err;       }       //和這個地址綁定在一起       if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {           error("Can't bind unix socket: %s (%d)", strerror(errno),                   errno);           close(sk);           return -1;       }       //設置為non block       set_nonblocking(sk);       //最大連接數為1       if (listen(sk, 1) < 0) {           error("Can't listen on unix socket: %s (%d)",                           strerror(errno), errno);           close(sk);           return -1;       }          unix_sock = sk;       //這邊加一個io的watch,有了數據後就會去調用accept       io = g_io_channel_unix_new(sk);       //server_cb中會accept       g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,                               server_cb, NULL);       g_io_channel_unref(io);          DBG("Unix socket created: %d", sk);          return 0;   }         2.3.7.2 input的init函數分析   input 這個插件的初始化   [cpp]  static int input_init(void)      {               GKeyFile *config;               //老規矩,不多說               connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);               if (connection == NULL)                         return -EIO;               //加載input.conf,內容見1)               config = load_config_file(CONFIGDIR "/input.conf");               //根據config進行初始化               if (input_manager_init(connection, config) < 0) {                         dbus_connection_unref(connection);                         return -EIO;               }                      if (config)                         g_key_file_free(config);                      return 0;      }         1)input.conf的內容   內容簡單的分析就如下:   [General]   別的什麼都沒有了,他其實能有的也就一個參數#IdleTimeout=30,這裡用的是默認值。   2)input_manager_init分析   [cpp]   int input_manager_init(DBusConnection *conn, GKeyFile *config)      {               GError *err = NULL;               //得到idle的timeout參數,沒有設置,就是默認值0               if (config) {                         idle_timeout = g_key_file_get_integer(config, "General",                                                              "IdleTimeout", &err);                         if (err) {                                  DBG("input.conf: %s", err->message);                                  g_error_free(err);                         }               }               //dbus的ref+1               connection = dbus_connection_ref(conn);               //初始化了input server,同樣因為adapter沒有up,所以沒有做對應的probe               btd_register_adapter_driver(&input_server_driver);               //注冊了兩個device driver               btd_register_device_driver(&input_hid_driver);               btd_register_device_driver(&input_headset_driver);                      return 0;      }         2.3.7.3 network的init函數分析   [cpp]  static int network_init(void)   {       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);       if (connection == NULL)           return -EIO;       //根據network.conf來進行各種配置       if (network_manager_init(connection) < 0) {           dbus_connection_unref(connection);           return -EIO;       }          return 0;   }      int network_manager_init(DBusConnection *conn)   {   //讀取network.conf文件,network.conf裡面也沒有內容,設置conf_security,默認為true       read_config(CONFIGDIR "/network.conf");       //新建一個bnep的socket       if (bnep_init()) {           error("Can't init bnep module");           return -1;       }          /*       * There is one socket to handle the incomming connections. NAP,       * GN and PANU servers share the same PSM. The initial BNEP message       * (setup connection request) contains the destination service       * field that defines which service the source is connecting to.       */       //初始化security       if (server_init(conn, conf_security) < 0)           return -1;       //加入到adapter_drivers列表中       /* Register network server if it doesn't exist */       btd_register_adapter_driver(&network_server_driver);       //dbus connection       if (connection_init(conn) < 0)           return -1;       //初始化了3個device driver       btd_register_device_driver(&network_panu_driver);       btd_register_device_driver(&network_gn_driver);       btd_register_device_driver(&network_nap_driver);          connection = dbus_connection_ref(conn);          return 0;   }         2.3.7.4 health的init   health總得來說用得還是蠻少的,不過android4.0也是支持了,我們來看一下吧:   [cpp]   static int hdp_init(void)   {       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);       if (connection == NULL)           return -EIO;       //就是這個函數了       if (hdp_manager_init(connection) < 0) {           dbus_connection_unref(connection);           return -EIO;       }          return 0;   }   int hdp_manager_init(DBusConnection *conn)   {       //就是注冊了一個health_manager_methods的接口,裡面有creatapplication和destroyapplication兩個函數       if (hdp_manager_start(conn))           return -1;          connection = dbus_connection_ref(conn);       //注冊一個adapter drvier和一個device driver。       btd_register_adapter_driver(&hdp_adapter_driver);       btd_register_device_driver(&hdp_device_driver);          return 0;   }         至此,所有的plugin都已經完成了。總共注冊了一下幾個adapter_driver:a2dp_server_driver,avrcp_server_driver,input_server_driver,network_server_driver,hdp_adapter_driver。另外還有幾個devcie driver:audio_driver,input_hid_driver,input_headset_driver,network_panu_driver,network_gn_driver,network_nap_driver,hdp_device_driver。在後面adapter up之後我們會加載這些driver,到時我們再來詳細分析他們各自都做了些什麼。    
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved