⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manager.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!adapter->hfp_ag_server)		goto failed;	record = hfp_ag_record(chan, features);	if (!record) {		error("Unable to allocate new service record");		goto failed;	}	if (add_record_to_server(&adapter->src, record) < 0) {		error("Unable to register HF AG service record");		sdp_record_free(record);		goto failed;	}	adapter->hfp_ag_record_id = record->handle;	return 0;failed:	if (adapter->hsp_ag_server) {		g_io_channel_unref(adapter->hsp_ag_server);		adapter->hsp_ag_server = NULL;	}	if (adapter->hfp_ag_server) {		g_io_channel_unref(adapter->hfp_ag_server);		adapter->hfp_ag_server = NULL;	}	return -1;}static int gateway_server_init(struct audio_adapter *adapter){	uint8_t chan = DEFAULT_HSP_HS_CHANNEL;	sdp_record_t *record;	gboolean master = TRUE;	GError *err = NULL;	uint32_t flags;	if (config) {		gboolean tmp;		tmp = g_key_file_get_boolean(config, "General", "Master",						&err);		if (err) {			debug("audio.conf: %s", err->message);			g_clear_error(&err);		} else			master = tmp;	}	flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;	if (master)		flags |= RFCOMM_LM_MASTER;	adapter->hsp_hs_server = bt_rfcomm_listen(&adapter->src, chan, flags,				hs_io_cb, adapter);	if (!adapter->hsp_hs_server)		return -1;	record = hsp_hs_record(chan);	if (!record) {		error("Unable to allocate new service record");		return -1;	}	if (add_record_to_server(&adapter->src, record) < 0) {		error("Unable to register HSP HS service record");		sdp_record_free(record);		g_io_channel_unref(adapter->hsp_hs_server);		adapter->hsp_hs_server = NULL;		return -1;	}	adapter->hsp_hs_record_id = record->handle;	return 0;}static int audio_probe(struct btd_device *device, GSList *uuids){	struct btd_adapter *adapter = device_get_adapter(device);	bdaddr_t src, dst;	struct audio_device *audio_dev;	adapter_get_address(adapter, &src);	device_get_address(device, &dst);	audio_dev = manager_get_device(&src, &dst);	if (!audio_dev) {		debug("audio_probe: unable to get a device object");		return -1;	}	g_slist_foreach(uuids, (GFunc) handle_uuid, audio_dev);	return 0;}static void audio_remove(struct btd_device *device){	struct audio_device *dev;	bdaddr_t bdaddr;	device_get_address(device, &bdaddr);	dev = manager_find_device(&bdaddr, NULL, FALSE);	if (!dev)		return;	devices = g_slist_remove(devices, dev);	device_unregister(dev);}static struct audio_adapter *create_audio_adapter(const char *path, bdaddr_t *src){	struct audio_adapter *adp;	adp = g_new0(struct audio_adapter, 1);	adp->path = g_strdup(path);	bacpy(&adp->src, src);	return adp;}static struct audio_adapter *get_audio_adapter(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	bdaddr_t src;	adapter_get_address(adapter, &src);	adp = find_adapter(adapters, path);	if (!adp) {		adp = create_audio_adapter(path, &src);		if (!adp)			return NULL;		adapters = g_slist_append(adapters, adp);	}	return adp;}static int headset_server_probe(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = get_audio_adapter(adapter);	if (!adp)		return -EINVAL;	return headset_server_init(adp);}static void headset_server_remove(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = find_adapter(adapters, path);	if (!adp)		return;	if (adp->hsp_ag_record_id) {		remove_record_from_server(adp->hsp_ag_record_id);		adp->hsp_ag_record_id = 0;	}	if (adp->hsp_ag_server) {		g_io_channel_unref(adp->hsp_ag_server);		adp->hsp_ag_server = NULL;	}	if (adp->hfp_ag_record_id) {		remove_record_from_server(adp->hfp_ag_record_id);		adp->hfp_ag_record_id = 0;	}	if (adp->hfp_ag_server) {		g_io_channel_unref(adp->hfp_ag_server);		adp->hfp_ag_server = NULL;	}}static int gateway_server_probe(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = get_audio_adapter(adapter);	if (!adp)		return -EINVAL;	return gateway_server_init(adp);}static void gateway_server_remove(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = find_adapter(adapters, path);	if (!adp)		return;	if (adp->hsp_hs_record_id) {		remove_record_from_server(adp->hsp_hs_record_id);		adp->hsp_hs_record_id = 0;	}	if (adp->hsp_hs_server) {		g_io_channel_unref(adp->hsp_hs_server);		adp->hsp_hs_server = NULL;	}}static int a2dp_server_probe(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = get_audio_adapter(adapter);	if (!adp)		return -EINVAL;	return a2dp_register(connection, &adp->src, config);}static void a2dp_server_remove(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = find_adapter(adapters, path);	if (!adp)		return;	return a2dp_unregister(&adp->src);}static int avrcp_server_probe(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = get_audio_adapter(adapter);	if (!adp)		return -EINVAL;	return avrcp_register(connection, &adp->src, config);}static void avrcp_server_remove(struct btd_adapter *adapter){	struct audio_adapter *adp;	const gchar *path = adapter_get_path(adapter);	DBG("path %s", path);	adp = find_adapter(adapters, path);	if (!adp)		return;	return avrcp_unregister(&adp->src);}static struct btd_device_driver audio_driver = {	.name	= "audio",	.uuids	= BTD_UUIDS(HSP_HS_UUID, HFP_HS_UUID, HSP_AG_UUID, HFP_AG_UUID,			ADVANCED_AUDIO_UUID, A2DP_SOURCE_UUID, A2DP_SINK_UUID,			AVRCP_TARGET_UUID, AVRCP_REMOTE_UUID),	.probe	= audio_probe,	.remove	= audio_remove,};static struct btd_adapter_driver headset_server_driver = {	.name	= "audio-headset",	.probe	= headset_server_probe,	.remove	= headset_server_remove,};static struct btd_adapter_driver gateway_server_driver = {	.name	= "audio-gateway",	.probe	= gateway_server_probe,	.remove	= gateway_server_remove,};static struct btd_adapter_driver a2dp_server_driver = {	.name	= "audio-a2dp",	.probe	= a2dp_server_probe,	.remove	= a2dp_server_remove,};static struct btd_adapter_driver avrcp_server_driver = {	.name	= "audio-control",	.probe	= avrcp_server_probe,	.remove	= avrcp_server_remove,};int audio_manager_init(DBusConnection *conn, GKeyFile *conf){	char **list;	int i;	gboolean b;	GError *err;	connection = dbus_connection_ref(conn);	if (!conf)		goto proceed;	config = conf;	list = g_key_file_get_string_list(config, "General", "Enable",						NULL, NULL);	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;	}	g_strfreev(list);	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;	}	g_strfreev(list);	err = NULL;	b = g_key_file_get_boolean(config, "Headset", "HFP",					&err);	if (err) {		debug("audio.conf: %s", err->message);		g_clear_error(&err);	} else		enabled.hfp = b;	err = NULL;	i = g_key_file_get_integer(config, "Headset", "MaxConnected",					&err);	if (err) {		debug("audio.conf: %s", err->message);		g_clear_error(&err);	} else		max_connected_headsets = i;proceed:	if (enabled.headset) {		telephony_init();		btd_register_adapter_driver(&headset_server_driver);	}	if (enabled.gateway)		btd_register_adapter_driver(&gateway_server_driver);	if (enabled.source || enabled.sink)		btd_register_adapter_driver(&a2dp_server_driver);	if (enabled.control)		btd_register_adapter_driver(&avrcp_server_driver);	btd_register_device_driver(&audio_driver);	return 0;}void audio_manager_exit(void){	dbus_connection_unref(connection);	if (config)		g_key_file_free(config);	if (enabled.headset) {		btd_unregister_adapter_driver(&headset_server_driver);		telephony_exit();	}	if (enabled.gateway)		btd_unregister_adapter_driver(&gateway_server_driver);	if (enabled.source || enabled.sink)		btd_unregister_adapter_driver(&a2dp_server_driver);	if (enabled.control)		btd_unregister_adapter_driver(&avrcp_server_driver);	btd_unregister_device_driver(&audio_driver);	connection = NULL;}struct audio_device *manager_get_connected_device(void){	GSList *l;	for (l = devices; l != NULL; l = g_slist_next(l)) {		struct audio_device *device = l->data;		if ((device->sink || device->source) &&				avdtp_is_connected(&device->src, &device->dst))			return device;		if (device->headset && headset_is_active(device))			return device;	}	return NULL;}struct audio_device *manager_find_device(const bdaddr_t *bda, const char *interface,					gboolean connected){	GSList *l;	for (l = devices; l != NULL; l = l->next) {		struct audio_device *dev = l->data;		if (bacmp(bda, BDADDR_ANY) && bacmp(&dev->dst, bda))			continue;		if (interface && !strcmp(AUDIO_HEADSET_INTERFACE, interface)				&& !dev->headset)			continue;		if (interface && !strcmp(AUDIO_SINK_INTERFACE, interface)				&& !dev->sink)			continue;		if (interface && !strcmp(AUDIO_SOURCE_INTERFACE, interface)				&& !dev->source)			continue;		if (interface && !strcmp(AUDIO_CONTROL_INTERFACE, interface)				&& !dev->control)			continue;		if (connected && !device_is_connected(dev, interface))			continue;		return dev;	}	return NULL;}struct audio_device *manager_get_device(const bdaddr_t *src,					const bdaddr_t *dst){	struct audio_device *dev;	struct btd_adapter *adapter;	struct btd_device *device;	char addr[18];	const char *path;	dev = manager_find_device(dst, NULL, FALSE);	if (dev)		return dev;	ba2str(src, addr);	adapter = manager_find_adapter(src);	if (!adapter) {		error("Unable to get a btd_adapter object for %s",				addr);		return NULL;	}	ba2str(dst, addr);	device = adapter_get_device(connection, adapter, addr);	if (!device) {		error("Unable to get btd_device object for %s", addr);		return NULL;	}	path = device_get_path(device);	dev = device_register(connection, path, src, dst);	if (!dev)		return NULL;	dev->btd_dev = device;	devices = g_slist_append(devices, dev);	return dev;}gboolean manager_allow_headset_connection(bdaddr_t *src){	GSList *l;	int connected = 0;	for (l = devices; l != NULL; l = l->next) {		struct audio_device *dev = l->data;		struct headset *hs = dev->headset;		if (bacmp(&dev->src, src))			continue;		if (!hs)			continue;		if (headset_get_state(dev) > HEADSET_STATE_DISCONNECTED)			connected++;		if (connected >= max_connected_headsets)			return FALSE;	}	return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -