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

📄 manager.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	} else {		char hs_address[18];		headset_set_authorized(device);		ba2str(&device->dst, hs_address);		debug("Accepted headset connection from %s for %s",						hs_address, device->path);		headset_set_state(device, HEADSET_STATE_CONNECTED);	}}static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,			const bdaddr_t *dst, gpointer data){	const char *uuid;	struct audio_device *device;	gboolean hfp_active;	if (err < 0) {		error("accept: %s (%d)", strerror(-err), -err);		return;	}	if (chan == hsp_ag_server) {		hfp_active = FALSE;		uuid = HSP_AG_UUID;	} else {		hfp_active = TRUE;		uuid = HFP_AG_UUID;	}	device = manager_find_device(dst, NULL, FALSE);	if (!device)		goto drop;	if (headset_get_state(device) > HEADSET_STATE_DISCONNECTED) {		debug("Refusing new connection since one already exists");		goto drop;	}	set_hfp_active(device, hfp_active);	if (headset_connect_rfcomm(device, chan) < 0) {		error("Allocating new GIOChannel failed!");		goto drop;	}	err = service_req_auth(&device->src, &device->dst, uuid, auth_cb,				device);	if (err < 0) {		debug("Authorization denied: %s", strerror(-err));		headset_close_rfcomm(device);		return;	}	headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS);	return;drop:	g_io_channel_close(chan);	g_io_channel_unref(chan);	return;}static void hs_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,		const bdaddr_t *dst, void *data){	/*Stub*/	return;}static int headset_server_init(DBusConnection *conn, GKeyFile *config){	uint8_t chan = DEFAULT_HS_AG_CHANNEL;	sdp_record_t *record;	gboolean hfp = TRUE, master = TRUE;	GError *err = NULL;	uint32_t features, flags;	if (!enabled.headset)		return 0;	if (config) {		gboolean tmp;		tmp = g_key_file_get_boolean(config, "General", "Master",						&err);		if (err) {			debug("audio.conf: %s", err->message);			g_error_free(err);			err = NULL;		} else			master = tmp;		tmp = g_key_file_get_boolean(config, "Headset", "HFP",						&err);		if (err) {			debug("audio.conf: %s", err->message);			g_error_free(err);			err = NULL;		} else			hfp = tmp;	}	flags = RFCOMM_LM_SECURE;	if (master)		flags |= RFCOMM_LM_MASTER;	hsp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,				NULL);	if (!hsp_ag_server)		return -1;	record = hsp_ag_record(chan);	if (!record) {		error("Unable to allocate new service record");		return -1;	}	if (add_record_to_server(BDADDR_ANY, record) < 0) {		error("Unable to register HS AG service record");		sdp_record_free(record);		g_io_channel_unref(hsp_ag_server);		hsp_ag_server = NULL;		return -1;	}	hsp_ag_record_id = record->handle;	features = headset_config_init(config);	if (!hfp)		return 0;	chan = DEFAULT_HF_AG_CHANNEL;	hfp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,				NULL);	if (!hfp_ag_server)		return -1;	record = hfp_ag_record(chan, features);	if (!record) {		error("Unable to allocate new service record");		return -1;	}	if (add_record_to_server(BDADDR_ANY, record) < 0) {		error("Unable to register HF AG service record");		sdp_record_free(record);		g_io_channel_unref(hfp_ag_server);		hfp_ag_server = NULL;		return -1;	}	hfp_ag_record_id = record->handle;	return 0;}static int gateway_server_init(DBusConnection *conn, GKeyFile *config){	uint8_t chan = DEFAULT_HSP_HS_CHANNEL;	sdp_record_t *record;	gboolean master = TRUE;	GError *err = NULL;	uint32_t flags;	if (!enabled.gateway)		return 0;	if (config) {		gboolean tmp;		tmp = g_key_file_get_boolean(config, "General", "Master",						&err);		if (err) {			debug("audio.conf: %s", err->message);			g_error_free(err);			err = NULL;		} else			master = tmp;	}	flags = RFCOMM_LM_SECURE;	if (master)		flags |= RFCOMM_LM_MASTER;	hsp_hs_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, hs_io_cb,				NULL);	if (!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(BDADDR_ANY, record) < 0) {		error("Unable to register HSP HS service record");		sdp_record_free(record);		g_io_channel_unref(hsp_hs_server);		hsp_hs_server = NULL;		return -1;	}	hsp_hs_record_id = record->handle;	return 0;}static void server_exit(void){	if (hsp_ag_record_id) {		remove_record_from_server(hsp_ag_record_id);		hsp_ag_record_id = 0;	}	if (hsp_ag_server) {		g_io_channel_unref(hsp_ag_server);		hsp_ag_server = NULL;	}	if (hsp_hs_record_id) {		remove_record_from_server(hsp_hs_record_id);		hsp_hs_record_id = 0;	}	if (hsp_hs_server) {		g_io_channel_unref(hsp_hs_server);		hsp_hs_server = NULL;	}	if (hfp_ag_record_id) {		remove_record_from_server(hfp_ag_record_id);		hfp_ag_record_id = 0;	}	if (hfp_ag_server) {		g_io_channel_unref(hfp_ag_server);		hfp_ag_server = NULL;	}}static int audio_probe(struct btd_device_driver *driver,			struct btd_device *device, GSList *records){	struct adapter *adapter = device_get_adapter(device);	const gchar *path = device_get_path(device);	const char *source, *destination;	bdaddr_t src, dst;	struct audio_device *dev;	source = adapter_get_address(adapter);	destination = device_get_address(device);	str2ba(source, &src);	str2ba(destination, &dst);	dev = manager_find_device(&dst, NULL, FALSE);	if (!dev) {		dev = device_register(connection, path, &src, &dst);		if (!dev)			return -EINVAL;		devices = g_slist_append(devices, dev);	}	g_slist_foreach(records, (GFunc) handle_record, dev);	return 0;}static void audio_remove(struct btd_device_driver *driver,			struct btd_device *device){	struct audio_device *dev;	const char *destination = device_get_address(device);	bdaddr_t dst;	str2ba(destination, &dst);	dev = manager_find_device(&dst, NULL, FALSE);	if (!dev)		return;	devices = g_slist_remove(devices, dev);	device_unregister(dev);}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,};int audio_manager_init(DBusConnection *conn, GKeyFile *config){	char **list;	int i;	connection = dbus_connection_ref(conn);	if (!config)		goto proceed;	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);proceed:	if (enabled.headset) {		if (headset_server_init(conn, config) < 0)			goto failed;	}	if (enabled.gateway) {		if (gateway_server_init(conn, config) < 0)			goto failed;	}	if (enabled.source || enabled.sink) {		if (a2dp_init(conn, config) < 0)			goto failed;	}	if (enabled.control && avrcp_init(conn, config) < 0)		goto failed;	btd_register_device_driver(&audio_driver);	return 0;failed:	audio_manager_exit();	return -1;}void audio_manager_exit(void){	server_exit();	dbus_connection_unref(connection);	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;	if (!bacmp(bda, BDADDR_ANY) && !interface && !connected)		return devices->data;	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;}

⌨️ 快捷键说明

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