Example #1
0
static void source_free(struct btd_service *service)
{
	struct source *source = btd_service_get_user_data(service);

	if (source->cb_id)
		avdtp_stream_remove_cb(source->session, source->stream,
					source->cb_id);

	if (source->session)
		avdtp_unref(source->session);

	if (source->connect_id > 0) {
		btd_service_connecting_complete(source->service, -ECANCELED);
		a2dp_cancel(source->connect_id);
		source->connect_id = 0;
	}

	if (source->disconnect_id > 0) {
		btd_service_disconnecting_complete(source->service, -ECANCELED);
		a2dp_cancel(source->disconnect_id);
		source->disconnect_id = 0;
	}

	avdtp_remove_state_cb(source->avdtp_callback_id);
	btd_service_unref(source->service);

	g_free(source);
}
Example #2
0
static void a2dp_config_complete(struct avdtp *session, struct a2dp_sep *sep,
					struct avdtp_stream *stream,
					struct avdtp_error *err,
					void *user_data)
{
	struct unix_client *client = user_data;
	char buf[BT_SUGGESTED_BUFFER_SIZE];
	struct bt_set_configuration_rsp *rsp = (void *) buf;
	struct a2dp_data *a2dp = &client->d.a2dp;
	uint16_t imtu, omtu;
	GSList *caps;

	client->req_id = 0;

	if (err)
		goto failed;

	memset(buf, 0, sizeof(buf));

	if (!stream)
		goto failed;

	if (client->cb_id > 0)
		avdtp_stream_remove_cb(a2dp->session, a2dp->stream,
								client->cb_id);

	a2dp->sep = sep;
	a2dp->stream = stream;

	if (!avdtp_stream_get_transport(stream, &client->data_fd, &imtu, &omtu,
					&caps)) {
		error("Unable to get stream transport");
		goto failed;
	}

	rsp->h.type = BT_RESPONSE;
	rsp->h.name = BT_SET_CONFIGURATION;
	rsp->h.length = sizeof(*rsp);

	/* FIXME: Use imtu when fd_opt is CFG_FD_OPT_READ */
	rsp->link_mtu = omtu;

	unix_ipc_sendmsg(client, &rsp->h);

	client->cb_id = avdtp_stream_add_cb(session, stream,
						stream_state_changed, client);

	return;

failed:
	error("config failed");

	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);

	avdtp_unref(a2dp->session);

	a2dp->session = NULL;
	a2dp->stream = NULL;
	a2dp->sep = NULL;
}
Example #3
0
static void sink_free(struct audio_device *dev)
{
	struct sink *sink = dev->sink;

	if (sink->cb_id)
		avdtp_stream_remove_cb(sink->session, sink->stream,
					sink->cb_id);

	if (sink->dc_id)
		device_remove_disconnect_watch(dev->btd_dev, sink->dc_id);

	if (sink->session)
		avdtp_unref(sink->session);

	if (sink->connect)
		pending_request_free(dev, sink->connect);

	if (sink->disconnect)
		pending_request_free(dev, sink->disconnect);

	if (sink->retry_id)
		g_source_remove(sink->retry_id);

	g_free(sink);
	dev->sink = NULL;
}
Example #4
0
static void source_free(struct audio_device *dev)
{
	struct source *source = dev->source;

	if (source->cb_id)
		avdtp_stream_remove_cb(source->session, source->stream,
					source->cb_id);

	if (source->session)
		avdtp_unref(source->session);

	if (source->connect_id > 0) {
		audio_source_connected(dev->btd_dev, -ECANCELED);
		a2dp_cancel(dev, source->connect_id);
		source->connect_id = 0;
	}

	if (source->disconnect_id > 0) {
		audio_source_disconnected(dev->btd_dev, -ECANCELED);
		a2dp_cancel(dev, source->disconnect_id);
		source->disconnect_id = 0;
	}

	if (source->retry_id)
		g_source_remove(source->retry_id);

	avdtp_remove_state_cb(source->avdtp_callback_id);

	g_free(source);
	dev->source = NULL;
}
Example #5
0
File: sink.c Project: Thread974/bz
static void sink_free(struct audio_device *dev)
{
	struct sink *sink = dev->sink;

	if (sink->cb_id)
		avdtp_stream_remove_cb(sink->session, sink->stream,
					sink->cb_id);

	if (sink->session)
		avdtp_unref(sink->session);

	if (sink->connect_id > 0) {
		btd_service_connecting_complete(sink->service, -ECANCELED);
		a2dp_cancel(dev, sink->connect_id);
		sink->connect_id = 0;
	}

	if (sink->disconnect_id > 0) {
		btd_service_disconnecting_complete(sink->service, -ECANCELED);
		a2dp_cancel(dev, sink->disconnect_id);
		sink->disconnect_id = 0;
	}

	if (sink->retry_id)
		g_source_remove(sink->retry_id);

	avdtp_remove_state_cb(sink->avdtp_callback_id);
	btd_service_unref(sink->service);

	g_free(sink);
	dev->sink = NULL;
}
Example #6
0
static void start_close(struct audio_device *dev, struct unix_client *client,
			gboolean reply)
{
	struct a2dp_data *a2dp;
	struct headset_data *hs;

	if (!client->dev)
		goto failed;

	switch (client->type) {
	case TYPE_HEADSET:
		hs = &client->d.hs;

		if (client->dev && hs->locked) {
			headset_unlock(client->dev, client->lock);
			hs->locked = FALSE;
		}
		break;
        case TYPE_GATEWAY:
                break;
	case TYPE_SOURCE:
	case TYPE_SINK:
		a2dp = &client->d.a2dp;

		if (client->cb_id > 0) {
			avdtp_stream_remove_cb(a2dp->session, a2dp->stream,
								client->cb_id);
			client->cb_id = 0;
		}
		if (a2dp->sep) {
			a2dp_sep_unlock(a2dp->sep, a2dp->session);
			a2dp->sep = NULL;
		}
		if (a2dp->session) {
			avdtp_unref(a2dp->session);
			a2dp->session = NULL;
		}
		a2dp->stream = NULL;
		break;
	default:
		error("No known services for device");
		goto failed;
	}

	if (!reply)
		return;

	close_complete(dev, client);
	client->dev = NULL;

	return;

failed:
	if (reply)
		unix_ipc_error(client, BT_STOP_STREAM, EINVAL);
}
Example #7
0
static void a2dp_resume_complete(struct avdtp *session,
				struct avdtp_error *err, void *user_data)
{
	struct unix_client *client = user_data;
	char buf[BT_SUGGESTED_BUFFER_SIZE];
	struct bt_start_stream_rsp *rsp = (void *) buf;
	struct bt_new_stream_ind *ind = (void *) buf;
	struct a2dp_data *a2dp = &client->d.a2dp;

	if (err)
		goto failed;

	memset(buf, 0, sizeof(buf));
	rsp->h.type = BT_RESPONSE;
	rsp->h.name = BT_START_STREAM;
	rsp->h.length = sizeof(*rsp);

	unix_ipc_sendmsg(client, &rsp->h);

	memset(buf, 0, sizeof(buf));
	ind->h.type = BT_RESPONSE;
	ind->h.name = BT_NEW_STREAM;
	rsp->h.length = sizeof(*ind);

	unix_ipc_sendmsg(client, &ind->h);

	if (unix_sendmsg_fd(client->sock, client->data_fd) < 0) {
		error("unix_sendmsg_fd: %s(%d)", strerror(errno), errno);
		goto failed;
	}

	return;

failed:
	error("resume failed");

	unix_ipc_error(client, BT_START_STREAM, EIO);

	if (client->cb_id > 0) {
		avdtp_stream_remove_cb(a2dp->session, a2dp->stream,
					client->cb_id);
		client->cb_id = 0;
	}

	if (a2dp->sep) {
		a2dp_sep_unlock(a2dp->sep, a2dp->session);
		a2dp->sep = NULL;
	}

	avdtp_unref(a2dp->session);
	a2dp->session = NULL;
	a2dp->stream = NULL;
}
Example #8
0
void sink_free(struct audio_device *dev)
{
	struct sink *sink = dev->sink;

	if (sink->cb_id)
		avdtp_stream_remove_cb(sink->session, sink->stream,
					sink->cb_id);

	if (sink->session)
		avdtp_unref(sink->session);

	if (sink->connect)
		pending_request_free(sink->connect);

	if (sink->disconnect)
		pending_request_free(sink->disconnect);

	g_free(sink);
	dev->sink = NULL;
}