Ejemplo n.º 1
0
static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
			GSList *caps, void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;
	int id;

	pending = sink->connect;
	pending->id = 0;

	id = a2dp_config(session, sep, stream_setup_complete, caps, sink);
	if (id == 0)
		goto failed;

	pending->id = id;
	return;

failed:
	if (pending->msg)
		error_failed(pending->conn, pending->msg, "Stream setup failed");
	pending_request_free(sink->dev, pending);
	sink->connect = NULL;
	avdtp_unref(sink->session);
	sink->session = NULL;
}
Ejemplo n.º 2
0
static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
			GSList *caps, void *user_data)
{
	struct sink *sink = user_data;
	int id;

	sink->connect_id = 0;

	id = a2dp_config(session, sep, stream_setup_complete, caps, sink);
	if (id == 0)
		goto failed;

	sink->connect_id = id;
	return;

failed:
	btd_service_connecting_complete(sink->service, -EIO);

	avdtp_unref(sink->session);
	sink->session = NULL;
}
Ejemplo n.º 3
0
static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
			GSList *caps, void *user_data)
{
	struct source *source = user_data;
	int id;

	source->connect_id = 0;

	if (caps == NULL)
		goto failed;

	id = a2dp_config(session, sep, stream_setup_complete, caps, source);
	if (id == 0)
		goto failed;

	source->connect_id = id;
	return;

failed:
	audio_source_connected(source->dev->btd_dev, -EIO);

	avdtp_unref(source->session);
	source->session = NULL;
}
Ejemplo n.º 4
0
static void start_config(struct audio_device *dev, struct unix_client *client)
{
	struct a2dp_data *a2dp;
	struct headset_data *hs;
	unsigned int id;

	switch (client->type) {
	case TYPE_SINK:
	case TYPE_SOURCE:
		a2dp = &client->d.a2dp;

		if (!a2dp->session)
			a2dp->session = avdtp_get(&dev->src, &dev->dst);

		if (!a2dp->session) {
			error("Unable to get a session");
			goto failed;
		}

		if (!a2dp->sep) {
			error("seid %d not opened", client->seid);
			goto failed;
		}

		id = a2dp_config(a2dp->session, a2dp->sep, a2dp_config_complete,
					client->caps, client);
		client->cancel = a2dp_cancel;
		break;

	case TYPE_HEADSET:
		hs = &client->d.hs;

		if (!hs->locked) {
			error("seid %d not opened", client->seid);
			goto failed;
		}

		id = headset_config_stream(dev, TRUE, headset_setup_complete,
						client);
		client->cancel = headset_cancel_stream;
		break;
	case TYPE_GATEWAY:
		if (gateway_config_stream(dev, gateway_setup_complete, client) >= 0) {
			client->cancel = gateway_cancel_stream;
			id = 1;
		} else
			id = 0;
		break;

	default:
		error("No known services for device");
		goto failed;
	}

	if (id == 0) {
		error("config failed");
		goto failed;
	}

	client->req_id = id;

	return;

failed:
	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);
}
Ejemplo n.º 5
0
static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,
				void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;
	struct avdtp_local_sep *lsep;
	struct avdtp_remote_sep *rsep;
	struct a2dp_sep *sep;
	GSList *caps = NULL;
	int id;

	pending = sink->connect;

	if (err) {
		avdtp_unref(sink->session);
		sink->session = NULL;
		if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
			DBG("connect:connect XCASE detected");
			sink->retry_id =
				g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER,
							stream_setup_retry,
							sink);
		} else
			goto failed;
		return;
	}

	DBG("Discovery complete");

	if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO,
				A2DP_CODEC_SBC, &lsep, &rsep) < 0) {
		error("No matching ACP and INT SEPs found");
		goto failed;
	}

	if (!select_capabilities(session, rsep, &caps)) {
		error("Unable to select remote SEP capabilities");
		goto failed;
	}

	sep = a2dp_get(session, rsep);
	if (!sep) {
		error("Unable to get a local source SEP");
		goto failed;
	}

	id = a2dp_config(sink->session, sep, stream_setup_complete, caps, sink);
	if (id == 0)
		goto failed;

	pending->id = id;
	return;

failed:
	if (pending->msg)
		error_failed(pending->conn, pending->msg, "Stream setup failed");
	pending_request_free(sink->dev, pending);
	sink->connect = NULL;
	avdtp_unref(sink->session);
	sink->session = NULL;
}
Ejemplo n.º 6
0
static void start_config(struct audio_device *dev, struct unix_client *client)
{
	struct a2dp_data *a2dp;
	struct headset_data *hs;
	struct avdtp_remote_sep *rsep;
	struct avdtp_service_capability *media_scms_t;
	struct avdtp_content_protection_capability scms_t_cap = {0x02, 0x00};
	unsigned int id;

	switch (client->type) {
	case TYPE_SINK:
	case TYPE_SOURCE:
		a2dp = &client->d.a2dp;

		if (!a2dp->session)
			a2dp->session = avdtp_get(&dev->src, &dev->dst);

		if (!a2dp->session) {
			error("Unable to get a session");
			goto failed;
		}

		if (!a2dp->sep) {
			error("seid %d not opened", client->seid);
			goto failed;
		}

		rsep = avdtp_get_remote_sep(a2dp->session, client->seid);
		media_scms_t = avdtp_get_remote_sep_protection(rsep);

		if (media_scms_t &&
			(memcmp(media_scms_t->data, &scms_t_cap, sizeof(scms_t_cap)) == 0)) {
			media_scms_t = avdtp_service_cap_new(AVDTP_CONTENT_PROTECTION,
						&scms_t_cap, 2);
			client->caps = g_slist_append(client->caps, media_scms_t);
		}
		id = a2dp_config(a2dp->session, a2dp->sep, a2dp_config_complete,
					client->caps, client);
		client->cancel = a2dp_cancel;
		break;

	case TYPE_HEADSET:
		hs = &client->d.hs;

		if (!hs->locked) {
			error("seid %d not opened", client->seid);
			goto failed;
		}

		id = headset_config_stream(dev, TRUE, headset_setup_complete,
						client);
		client->cancel = headset_cancel_stream;
		break;
	case TYPE_GATEWAY:
		if (gateway_config_stream(dev, gateway_setup_complete, client) >= 0) {
			client->cancel = gateway_cancel_stream;
			id = 1;
		} else
			id = 0;
		break;

	default:
		error("No known services for device");
		goto failed;
	}

	if (id == 0) {
		error("config failed");
		goto failed;
	}

	client->req_id = id;
	g_slist_free(client->caps);
	client->caps = NULL;

	return;

failed:
	if (client->caps) {
		g_slist_free(client->caps);
		client->caps = NULL;
	}
	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);
}