static void bluetooth_exit(struct bluetooth_data *data)
{
	struct bluetooth_a2dp *a2dp = &data->a2dp;

	if (data->server.fd >= 0)
		bt_audio_service_close(data->server.fd);

	if (data->stream.fd >= 0)
		close(data->stream.fd);

	if (data->hw_thread) {
		pthread_cancel(data->hw_thread);
		pthread_join(data->hw_thread, 0);
	}

	if (a2dp->sbc_initialized)
		sbc_finish(&a2dp->sbc);

	if (data->pipefd[0] > 0)
		close(data->pipefd[0]);

	if (data->pipefd[1] > 0)
		close(data->pipefd[1]);

	free(data);
}
示例#2
0
static void bluetooth_close(struct bluetooth_data *data)
{
	DBG("bluetooth_close");
	if (data->server.fd >= 0) {
		bt_audio_service_close(data->server.fd);
		data->server.fd = -1;
	}

	if (data->stream.fd >= 0) {
		close(data->stream.fd);
		data->stream.fd = -1;
	}

	data->state = A2DP_STATE_NONE;
}
示例#3
0
static gboolean gst_avdtp_sink_start(GstBaseSink *basesink)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
	gint sk;
	gint err;

	GST_INFO_OBJECT(self, "start");

	self->watch_id = 0;

	sk = bt_audio_service_open();
	if (sk <= 0) {
		err = errno;
		GST_ERROR_OBJECT(self, "Cannot open connection to bt "
			"audio service: %s %d", strerror(err), err);
		goto failed;
	}

	self->server = g_io_channel_unix_new(sk);
	self->watch_id = g_io_add_watch(self->server, G_IO_HUP | G_IO_ERR |
					G_IO_NVAL, server_callback, self);

	self->data = g_new0(struct bluetooth_data, 1);

	self->stream = NULL;
	self->stream_caps = NULL;
	self->mp3_using_crc = -1;
	self->channel_mode = -1;

	if (!gst_avdtp_sink_get_capabilities(self)) {
		GST_ERROR_OBJECT(self, "failed to get capabilities "
				"from device");
		goto failed;
	}

	return TRUE;

failed:
	bt_audio_service_close(sk);
	return FALSE;
}
示例#4
0
static gboolean gst_avdtp_sink_stop(GstBaseSink *basesink)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);

	GST_INFO_OBJECT(self, "stop");

	if (self->watch_id != 0) {
		g_source_remove(self->watch_id);
		self->watch_id = 0;
	}

	if (self->server) {
		bt_audio_service_close(g_io_channel_unix_get_fd(self->server));
		g_io_channel_unref(self->server);
		self->server = NULL;
	}

	if (self->stream) {
		g_io_channel_shutdown(self->stream, TRUE, NULL);
		g_io_channel_unref(self->stream);
		self->stream = NULL;
	}

	if (self->data) {
		g_free(self->data);
		self->data = NULL;
	}

	if (self->stream_caps) {
		gst_caps_unref(self->stream_caps);
		self->stream_caps = NULL;
	}

	if (self->dev_caps) {
		gst_caps_unref(self->dev_caps);
		self->dev_caps = NULL;
	}

	return TRUE;
}
示例#5
0
static void bluetooth_close(struct bluetooth_data *data)
{
	DBG("bluetooth_close");
	if (data->server.fd >= 0) {
		// sending BT_CLOSE to cleanup unix socket.
		char buf[BT_SUGGESTED_BUFFER_SIZE];
		struct bt_close_req *close_req = (void*) buf;
		struct bt_close_rsp *close_rsp = (void*) buf;
		int err;
		memset(close_req, 0, BT_SUGGESTED_BUFFER_SIZE);
		close_req->h.type = BT_REQUEST;
		close_req->h.name = BT_CLOSE;

		close_req->h.length = sizeof(*close_req);

		err = audioservice_send(data, &close_req->h);
		if (err < 0) {
			ERR("audioservice_send failed for BT_CLOSE_REQ\n");
		} else {
			close_rsp->h.length = 0;
			err = audioservice_expect(data, &close_rsp->h, BT_CLOSE);
			if (err < 0) {
				ERR("audioservice_expect failed for BT_CLOSE_RSP\n");
			}
		}
		bt_audio_service_close(data->server.fd);
		data->server.fd = -1;
	}

	if (data->stream.fd >= 0) {
		close(data->stream.fd);
		data->stream.fd = -1;
	}

	data->state = A2DP_STATE_NONE;
}