本来只想分析一下hciops的初始化就不再管了,后来发现别的plugin的初始化在后面还是会有涉及,心中想,既然已经分析了这么多,咋就索性都分析了算了,反正也不差这一点代码,其它的plugin还有audio,input,network,health。我们只看两个函数init或者setup。所以看起来应该会比较简单一点。
2.3.7.1 audio的init分析
audio 这个插件的分析
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的内容简介如下:
[General] Enable=Sink,Control Disable=Headset,Gateway,Source Master=false FastConnectable=false [A2DP] SBCSources=1 MPEG12Sources=0 [AVRCP] InputDeviceName=AVRCP
2)根据config来进行init
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分析
//这里其实是新建一个本地的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 这个插件的初始化
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分析
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函数分析
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也是支持了,我们来看一下吧:
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,到时我们再来详细分析他们各自都做了些什么。
若您觉得该文章对您有帮助,请在下面用鼠标轻轻按一下“顶”,哈哈~~·