`
836811384
  • 浏览: 547287 次
文章分类
社区版块
存档分类
最新评论

[Android 源码解析]bluez中几个重要plugin的初始化--audio,input,network,health

 
阅读更多

本来只想分析一下hciops的初始化就不再管了,后来发现别的plugin的初始化在后面还是会有涉及,心中想,既然已经分析了这么多,咋就索性都分析了算了,反正也不差这一点代码,其它的plugin还有audioinputnetworkhealth。我们只看两个函数init或者setup。所以看起来应该会比较简单一点。

2.3.7.1 audioinit分析

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;
}

1audio.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;
}


所以,这里一共是3driver注册了。

3unix_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 inputinit函数分析

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;

}


1input.conf的内容

内容简单的分析就如下:

[General]

别的什么都没有了,他其实能有的也就一个参数#IdleTimeout=30,这里用的是默认值。

2input_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 networkinit函数分析

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 healthinit

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_drivera2dp_server_driveravrcp_server_driverinput_server_drivernetwork_server_driverhdp_adapter_driver。另外还有几个devcie driveraudio_driverinput_hid_driverinput_headset_drivernetwork_panu_drivernetwork_gn_drivernetwork_nap_driverhdp_device_driver。在后面adapter up之后我们会加载这些driver,到时我们再来详细分析他们各自都做了些什么。

若您觉得该文章对您有帮助,请在下面用鼠标轻轻按一下“顶”,哈哈~~·

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics