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

📄 a2dp.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);	a2dp_sep->stream = stream;	if (!setup)		return;	dev = a2dp_get_dev(session);	/* Notify sink.c of the new stream */	sink_new_stream(dev, session, setup->stream);	ret = avdtp_open(session, stream);	if (ret < 0) {		error("Error on avdtp_open %s (%d)", strerror(-ret),				-ret);		setup->stream = NULL;		finalize_config_errno(setup, ret);	}}static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,				uint8_t *err, void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Get_Configuration_Ind");	else		debug("Source %p: Get_Configuration_Ind");	return TRUE;}static void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Set_Configuration_Cfm", sep);	else		debug("Source %p: Set_Configuration_Cfm", sep);}static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,				struct avdtp_stream *stream, uint8_t *err,				void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Open_Ind", sep);	else		debug("Source %p: Open_Ind", sep);	return TRUE;}static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Open_Cfm", sep);	else		debug("Source %p: Open_Cfm", sep);	setup = find_setup_by_session(session);	if (!setup)		return;	if (setup->canceled) {		if (!err)			avdtp_close(session, stream);		setup_unref(setup);		return;	}	if (setup->reconfigure)		setup->reconfigure = FALSE;	if (err) {		setup->stream = NULL;		setup->err = err;		finalize_config(setup);	}	else		finalize_config_errno(setup, 0);}static gboolean suspend_timeout(struct a2dp_sep *sep){	if (avdtp_suspend(sep->session, sep->stream) == 0)		sep->suspending = TRUE;	sep->suspend_timer = 0;	avdtp_unref(sep->session);	sep->session = NULL;	return FALSE;}static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,				struct avdtp_stream *stream, uint8_t *err,				void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Start_Ind", sep);	else		debug("Source %p: Start_Ind", sep);	if (!a2dp_sep->locked) {		a2dp_sep->session = avdtp_ref(session);		a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT,						(GSourceFunc) suspend_timeout,						a2dp_sep);	}	return TRUE;}static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Start_Cfm", sep);	else		debug("Source %p: Start_Cfm", sep);	setup = find_setup_by_session(session);	if (!setup)		return;	if (setup->canceled) {		if (!err)			avdtp_close(session, stream);		setup_unref(setup);		return;	}	if (err) {		setup->stream = NULL;		setup->err = err;		finalize_resume(setup);	}	else		finalize_resume_errno(setup, 0);}static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,				struct avdtp_stream *stream, uint8_t *err,				void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Suspend_Ind", sep);	else		debug("Source %p: Suspend_Ind", sep);	if (a2dp_sep->suspend_timer) {		g_source_remove(a2dp_sep->suspend_timer);		a2dp_sep->suspend_timer = 0;		avdtp_unref(a2dp_sep->session);		a2dp_sep->session = NULL;	}	return TRUE;}static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	gboolean start;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Suspend_Cfm", sep);	else		debug("Source %p: Suspend_Cfm", sep);	a2dp_sep->suspending = FALSE;	setup = find_setup_by_session(session);	if (!setup)		return;	start = setup->start;	setup->start = FALSE;	if (err) {		setup->stream = NULL;		setup->err = err;		finalize_suspend(setup);	}	else		finalize_suspend_errno(setup, 0);	if (!start)		return;	if (err) {		setup->err = err;		finalize_suspend(setup);	} else if (avdtp_start(session, a2dp_sep->stream) < 0) {		struct avdtp_error start_err;		error("avdtp_start failed");		avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO);		setup->err = err;		finalize_suspend(setup);	}}static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,				struct avdtp_stream *stream, uint8_t *err,				void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Close_Ind", sep);	else		debug("Source %p: Close_Ind", sep);	return TRUE;}static gboolean a2dp_reconfigure(gpointer data){	struct a2dp_setup *setup = data;	struct avdtp_local_sep *lsep;	struct avdtp_remote_sep *rsep;	struct avdtp_service_capability *cap;	struct avdtp_media_codec_capability *codec_cap = NULL;	GSList *l;	int posix_err;	for (l = setup->client_caps; l != NULL; l = l->next) {		cap = l->data;		if (cap->category != AVDTP_MEDIA_CODEC)			continue;		codec_cap = (void *) cap->data;		break;	}	posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK,					codec_cap->media_type,					codec_cap->media_codec_type,					&lsep, &rsep);	if (posix_err < 0) {		error("No matching ACP and INT SEPs found");		finalize_config_errno(setup, posix_err);	}	posix_err = avdtp_set_configuration(setup->session, rsep, lsep,						setup->client_caps,						&setup->stream);	if (posix_err < 0) {		error("avdtp_set_configuration: %s",			strerror(-posix_err));		finalize_config_errno(setup, posix_err);	}	return FALSE;}static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Close_Cfm", sep);	else		debug("Source %p: Close_Cfm", sep);	setup = find_setup_by_session(session);	if (!setup)		return;	if (setup->canceled) {		setup_unref(setup);		return;	}	if (err) {		setup->stream = NULL;		setup->err = err;		finalize_config(setup);		return;	}	if (setup->reconfigure)		g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);}static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,				struct avdtp_stream *stream, uint8_t *err,				void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Abort_Ind", sep);	else		debug("Source %p: Abort_Ind", sep);	a2dp_sep->stream = NULL;	return TRUE;}static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: Abort_Cfm", sep);	else		debug("Source %p: Abort_Cfm", sep);	setup = find_setup_by_session(session);	if (!setup)		return;	setup_unref(setup);}static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,				uint8_t *err, void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: ReConfigure_Ind", sep);	else		debug("Source %p: ReConfigure_Ind", sep);	return TRUE;}static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,			struct avdtp_stream *stream, struct avdtp_error *err,			void *user_data){	struct a2dp_sep *a2dp_sep = user_data;	struct a2dp_setup *setup;	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)		debug("Sink %p: ReConfigure_Cfm", sep);	else		debug("Source %p: ReConfigure_Cfm", sep);	setup = find_setup_by_session(session);	if (!setup)		return;	if (setup->canceled) {		if (!err)			avdtp_close(session, stream);		setup_unref(setup);		return;	}	if (err) {		setup->stream = NULL;		setup->err = err;		finalize_config(setup);	}	else		finalize_config_errno(setup, 0);}static struct avdtp_sep_cfm cfm = {	.set_configuration	= setconf_cfm,	.get_configuration	= getconf_cfm,	.open			= open_cfm,	.start			= start_cfm,	.suspend		= suspend_cfm,	.close			= close_cfm,	.abort			= abort_cfm,	.reconfigure		= reconf_cfm};static struct avdtp_sep_ind sbc_ind = {	.get_capability		= sbc_getcap_ind,	.set_configuration	= sbc_setconf_ind,	.get_configuration	= getconf_ind,	.open			= open_ind,	.start			= start_ind,	.suspend		= suspend_ind,	.close			= close_ind,	.abort			= abort_ind,	.reconfigure		= reconf_ind};static struct avdtp_sep_ind mpeg_ind = {	.get_capability		= mpeg_getcap_ind,	.set_configuration	= mpeg_setconf_ind,	.get_configuration	= getconf_ind,	.open			= open_ind,	.start			= start_ind,	.suspend		= suspend_ind,	.close			= close_ind,	.abort			= abort_ind,	.reconfigure		= reconf_ind};static sdp_record_t *a2dp_source_record(){	sdp_list_t *svclass_id, *pfseq, *apseq, *root;	uuid_t root_uuid, l2cap, avdtp, a2src;	sdp_profile_desc_t profile[1];	sdp_list_t *aproto, *proto[2];	sdp_record_t *record;	sdp_data_t *psm, *version, *features;	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F;	record = sdp_record_alloc();	if (!record)		return NULL;	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);	root = sdp_list_append(0, &root_uuid);	sdp_set_browse_groups(record, root);	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);	svclass_id = sdp_list_append(0, &a2src);	sdp_set_service_classes(record, svclass_id);	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);	profile[0].version = 0x0100;	pfseq = sdp_list_append(0, &profile[0]);	sdp_set_profile_descs(record, pfseq);	sdp_uuid16_create(&l2cap, L2CAP_UUID);	proto[0] = sdp_list_append(0, &l2cap);	psm = sdp_data_alloc(SDP_UINT16, &lp);	proto[0] = sdp_list_append(proto[0], psm);	apseq = sdp_list_append(0, proto[0]);	sdp_uuid16_create(&avdtp, AVDTP_UUID);	proto[1] = sdp_list_append(0, &avdtp);	version = sdp_data_alloc(SDP_UINT16, &ver);	proto[1] = sdp_list_append(proto[1], version);	apseq = sdp_list_append(apseq, proto[1]);	aproto = sdp_list_append(0, apseq);	sdp_set_access_protos(record, aproto);	features = sdp_data_alloc(SDP_UINT16, &feat);	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);	sdp_set_info_attr(record, "Audio Source", 0, 0);	free(psm);	free(version);	sdp_list_free(proto[0], 0);	sdp_list_free(proto[1], 0);	sdp_list_free(apseq, 0);	sdp_list_free(pfseq, 0);	sdp_list_free(aproto, 0);	sdp_list_free(root, 0);	sdp_list_free(svclass_id, 0);	return record;}static sdp_record_t *a2dp_sink_record(){	return NULL;}

⌨️ 快捷键说明

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