/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <pthread.h>

#include <netinet/in.h>

#include <bluetooth/bluetooth.h>

#include "ipc.h"
#include "sbc.h"
#include "rtp.h"

#include "gsta2dpsink.h"

enum {
        NOT_CONFIGURED,
        CONFIGURING_INIT,
        CONFIGURING_SENT_CONF,
        CONFIGURING_RCVD_DEV_CONF,
        CONFIGURED
};

GST_DEBUG_CATEGORY_STATIC(a2dp_sink_debug);
#define GST_CAT_DEFAULT a2dp_sink_debug

#define BUFFER_SIZE 2048

#define GST_A2DP_SINK_MUTEX_LOCK(s) G_STMT_START {	\
		g_mutex_lock (s->sink_lock);		\
	} G_STMT_END

#define GST_A2DP_SINK_MUTEX_UNLOCK(s) G_STMT_START {	\
		g_mutex_unlock (s->sink_lock);		\
	} G_STMT_END

#define GST_A2DP_SINK_WAIT_CON_END(s) G_STMT_START {			\
		s->waiting_con_conf = TRUE;				\
		g_cond_wait (s->con_conf_end, s->sink_lock);		\
		s->waiting_con_conf = FALSE;				\
	} G_STMT_END

#define GST_A2DP_SINK_CONFIGURATION_FAIL(s) G_STMT_START {		\
		s->con_state = NOT_CONFIGURED;				\
		g_cond_signal (s->con_conf_end);			\
	} G_STMT_END

#define GST_A2DP_SINK_CONFIGURATION_SUCCESS(s) G_STMT_START {		\
		s->con_state = CONFIGURED;				\
		g_cond_signal (s->con_conf_end);			\
	} G_STMT_END

struct bluetooth_data {
	struct ipc_data_cfg cfg;	/* Bluetooth device config */
	sbc_t sbc;			/* Codec data */
	int codesize;			/* SBC codesize */
	int samples;			/* Number of encoded samples */
	gchar buffer[BUFFER_SIZE];	/* Codec transfer buffer */
	gsize count;			/* Codec transfer buffer counter */

	int nsamples;			/* Cumulative number of codec samples */
	uint16_t seq_num;		/* Cumulative packet sequence */
	int frame_count;		/* Current frames in buffer*/
};

#define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0)
#define IS_MPEG(n) (strcmp((n), "audio/mpeg") == 0)

enum {
	PROP_0,
	PROP_DEVICE,
};

GST_BOILERPLATE(GstA2dpSink, gst_a2dp_sink, GstBaseSink, GST_TYPE_BASE_SINK);

static const GstElementDetails a2dp_sink_details =
	GST_ELEMENT_DETAILS("Bluetooth A2DP sink",
				"Sink/Audio",
				"Plays audio to an A2DP device",
				"Marcel Holtmann <marcel@holtmann.org>");

static GstStaticPadTemplate a2dp_sink_factory =
	GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
		GST_STATIC_CAPS("audio/x-sbc, "
				"rate = (int) { 16000, 32000, 44100, 48000 }, "
				"channels = (int) [ 1, 2 ], "
				"mode = (string) { mono, dual, stereo, joint }, "
				"blocks = (int) { 4, 8, 12, 16 }, "
				"subbands = (int) { 4, 8 }, "
				"allocation = (string) { snr, loudness }; "
				"audio/mpeg, "
				"mpegversion = (int) 1, "
				"layer = (int) [ 1, 3 ], "
				"rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
				"channels = (int) [ 1, 2 ]"));

static void gst_a2dp_sink_base_init(gpointer g_class)
{
	GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);

	gst_element_class_add_pad_template(element_class,
		gst_static_pad_template_get(&a2dp_sink_factory));

	gst_element_class_set_details(element_class, &a2dp_sink_details);
}

static gboolean gst_a2dp_sink_stop(GstBaseSink *basesink)
{
	GstA2dpSink *self = GST_A2DP_SINK(basesink);

	GST_INFO_OBJECT(self, "stop");

	self->con_state = NOT_CONFIGURED;

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

	if (self->server) {
		g_io_channel_close(self->server);
		g_io_channel_unref(self->server);
		self->stream = NULL;
	}

	if (self->data) {
		if (self->data->cfg.codec == CFG_CODEC_SBC)
			sbc_finish(&self->data->sbc);
		g_free(self->data);
		self->data = NULL;
	}

	return TRUE;
}

static void gst_a2dp_sink_finalize(GObject *object)
{
	GstA2dpSink *self = GST_A2DP_SINK(object);

	if (self->data)
		gst_a2dp_sink_stop(GST_BASE_SINK(self));

	if (self->device)
		g_free(self->device);

	/* unlock any thread waiting for this signal */
	GST_A2DP_SINK_MUTEX_LOCK(self);
	GST_A2DP_SINK_CONFIGURATION_FAIL(self);
	GST_A2DP_SINK_MUTEX_UNLOCK(self);

	g_cond_free(self->con_conf_end);
	g_mutex_free(self->sink_lock);

	G_OBJECT_CLASS(parent_class)->finalize(object);
}

static void gst_a2dp_sink_set_property(GObject *object, guint prop_id,
					const GValue *value, GParamSpec *pspec)
{
	GstA2dpSink *sink = GST_A2DP_SINK(object);

	switch (prop_id) {
	case PROP_DEVICE:
		if (sink->device)
			g_free(sink->device);
		sink->device = g_value_dup_string(value);
		break;

	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static void gst_a2dp_sink_get_property(GObject *object, guint prop_id,
					GValue *value, GParamSpec *pspec)
{
	GstA2dpSink *sink = GST_A2DP_SINK(object);

	switch (prop_id) {
	case PROP_DEVICE:
		g_value_set_string(value, sink->device);
		break;

	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static gint gst_a2dp_sink_bluetooth_recvmsg_fd(GstA2dpSink *sink)
{
	char cmsg_b[CMSG_SPACE(sizeof(int))], m;
	int err, ret, stream_fd;
	struct iovec iov = { &m, sizeof(m) };
	struct msghdr msgh;
	struct cmsghdr *cmsg;

	memset(&msgh, 0, sizeof(msgh));
	msgh.msg_iov = &iov;
	msgh.msg_iovlen = 1;
	msgh.msg_control = &cmsg_b;
	msgh.msg_controllen = CMSG_LEN(sizeof(int));

	ret = recvmsg(g_io_channel_unix_get_fd(sink->server), &msgh, 0);
	if (ret < 0) {
		err = errno;
		GST_ERROR_OBJECT(sink, "Unable to receive fd: %s (%d)",
				strerror(err), err);
		return -err;
	}

	/* Receive auxiliary data in msgh */
	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
			cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
		if (cmsg->cmsg_level == SOL_SOCKET
				&& cmsg->cmsg_type == SCM_RIGHTS) {
			stream_fd = (*(int *) CMSG_DATA(cmsg));
			sink->stream = g_io_channel_unix_new(stream_fd);

			GST_DEBUG_OBJECT(sink, "stream_fd=%d", stream_fd);
			return 0;
		}
	}

	return -EINVAL;
}

static int gst_a2dp_sink_bluetooth_a2dp_init(GstA2dpSink *self,
			struct ipc_codec_sbc *sbc)
{
	struct bluetooth_data *data = self->data;
	struct ipc_data_cfg *cfg = &data->cfg;

	if (cfg == NULL) {
		GST_ERROR_OBJECT(self, "Error getting codec parameters");
		return -1;
	}

	if (cfg->codec != CFG_CODEC_SBC)
		return -1;

	/* FIXME: init using flags? */
	sbc_init(&data->sbc, 0);
	data->sbc.rate = cfg->rate;
	data->sbc.channels = cfg->mode == CFG_MODE_MONO ? 1 : 2;
	if (cfg->mode == CFG_MODE_MONO || cfg->mode == CFG_MODE_JOINT_STEREO)
		data->sbc.joint = 1;
	data->sbc.allocation = sbc->allocation;
	data->sbc.subbands = sbc->subbands;
	data->sbc.blocks = sbc->blocks;
	data->sbc.bitpool = sbc->bitpool;
	data->codesize = data->sbc.subbands * data->sbc.blocks *
						data->sbc.channels * 2;
	data->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);

	GST_DEBUG_OBJECT(self, "Codec parameters: "
				"\tallocation=%u\n\tsubbands=%u\n "
				"\tblocks=%u\n\tbitpool=%u\n",
				data->sbc.allocation, data->sbc.subbands,
				data->sbc.blocks, data->sbc.bitpool);

	return 0;
}

static gboolean gst_a2dp_sink_init_pkt_conf(GstA2dpSink *sink,
					GstCaps *caps,
					struct ipc_packet *pkt)
{

	struct ipc_data_cfg *cfg = (void *) pkt->data;
	struct ipc_codec_sbc *sbc = (void *) cfg->data;
	const GValue *value = NULL;
	const char *pref, *name;
	GstStructure *structure = gst_caps_get_structure(caps,0);

	name = gst_structure_get_name(structure);
	/* FIXME only sbc supported here, should suport mp3 */
	if (!(IS_SBC(name))) {
		GST_ERROR_OBJECT(sink, "Unsupported format %s", name);
		return FALSE;
	}

	if (sink->device)
		strncpy(pkt->device, sink->device, 18);

	pkt->role = PKT_ROLE_HIFI;

	value = gst_structure_get_value(structure, "rate");
	cfg->rate = g_value_get_int(value);

	value = gst_structure_get_value(structure, "mode");
	pref = g_value_get_string(value);
	if (strcmp(pref, "auto") == 0)
		cfg->mode = CFG_MODE_AUTO;
	else if (strcmp(pref, "mono") == 0)
		cfg->mode = CFG_MODE_MONO;
	else if (strcmp(pref, "dual") == 0)
		cfg->mode = CFG_MODE_DUAL_CHANNEL;
	else if (strcmp(pref, "stereo") == 0)
		cfg->mode = CFG_MODE_STEREO;
	else if (strcmp(pref, "joint") == 0)
		cfg->mode = CFG_MODE_JOINT_STEREO;
	else {
		GST_ERROR_OBJECT(sink, "Invalid mode %s", pref);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "allocation");
	pref = g_value_get_string(value);
	if (strcmp(pref, "auto") == 0)
		sbc->allocation = CFG_ALLOCATION_AUTO;
	else if (strcmp(pref, "loudness") == 0)
		sbc->allocation = CFG_ALLOCATION_LOUDNESS;
	else if (strcmp(pref, "snr") == 0)
		sbc->allocation = CFG_ALLOCATION_SNR;
	else {
		GST_ERROR_OBJECT(sink, "Invalid allocation: %s", pref);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "subbands");
	sbc->subbands = g_value_get_int(value);

	value = gst_structure_get_value(structure, "blocks");
	sbc->blocks = g_value_get_int(value);
	sbc->bitpool = 32;

	pkt->length = sizeof(*cfg) + sizeof(*sbc);
	pkt->type = PKT_TYPE_CFG_REQ;
	pkt->error = PKT_ERROR_NONE;

	return TRUE;
}

static gboolean gst_a2dp_sink_conf_resp(GstA2dpSink *sink)
{
	gchar buf[IPC_MTU];
	GIOError io_error;
	gsize ret;
	gint total;
	struct ipc_packet *pkt = (void *) buf;
	struct ipc_data_cfg *cfg = (void *) pkt->data;
	struct ipc_codec_sbc *sbc = (void *) cfg->data;

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

	io_error = g_io_channel_read(sink->server, (gchar *) buf,
			sizeof(*pkt) + sizeof(*cfg), &ret);
	if (io_error != G_IO_ERROR_NONE && ret > 0) {
		GST_ERROR_OBJECT(sink, "Error ocurred while receiving "
					"configurarion packet answer");
		return FALSE;
	}

	total = ret;
	if (pkt->type != PKT_TYPE_CFG_RSP) {
		GST_ERROR_OBJECT(sink, "Unexpected packet type %d "
					"received", pkt->type);
		return FALSE;
	}

	if (pkt->error != PKT_ERROR_NONE) {
		GST_ERROR_OBJECT(sink, "Error %d while configuring "
					"device", pkt->error);
		return FALSE;
	}

	if (cfg->codec != CFG_CODEC_SBC) {
		GST_ERROR_OBJECT(sink, "Unsupported format");
		return FALSE;
	}

	io_error = g_io_channel_read(sink->server, (gchar *) sbc,
					sizeof(*sbc), &ret);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(sink, "Error while reading data from socket "
				"%s (%d)", strerror(errno), errno);
		return FALSE;
	} else if (ret == 0) {
		GST_ERROR_OBJECT(sink, "Read 0 bytes from socket");
		return FALSE;
	}

	total += ret;
	GST_DEBUG_OBJECT(sink, "OK - %d bytes received", total);

	if (pkt->length != (total - sizeof(struct ipc_packet))) {
		GST_ERROR_OBJECT(sink, "Error while configuring device: "
			"packet size doesn't match");
		return FALSE;
	}

	memcpy(&sink->data->cfg, cfg, sizeof(*cfg));

	GST_DEBUG_OBJECT(sink, "Device configuration:\n\tchannel=%p\n\t"
			"fd_opt=%u\n\tpkt_len=%u\n\tsample_size=%u\n\trate=%u",
			sink->stream, sink->data->cfg.fd_opt,
			sink->data->cfg.pkt_len, sink->data->cfg.sample_size,
			sink->data->cfg.rate);

	if (sink->data->cfg.codec == CFG_CODEC_SBC) {
		ret = gst_a2dp_sink_bluetooth_a2dp_init(sink, sbc);
		if (ret < 0)
			return FALSE;
	}

	return TRUE;
}

static gboolean gst_a2dp_sink_conf_recv_stream_fd(GstA2dpSink *self)
{
	struct bluetooth_data *data = self->data;
	gint ret;
	GIOError err;
	GError *gerr = NULL;
	GIOStatus status;
	GIOFlags flags;
	gsize read;

	ret = gst_a2dp_sink_bluetooth_recvmsg_fd(self);
	if (ret < 0)
		return FALSE;

	if (!self->stream) {
		GST_ERROR_OBJECT(self, "Error while configuring device: "
				"could not acquire audio socket");
		return FALSE;
	}

	/* set stream socket to nonblock */
	GST_LOG_OBJECT(self, "setting stream socket to nonblock");
	flags = g_io_channel_get_flags(self->stream);
	flags |= G_IO_FLAG_NONBLOCK;
	status = g_io_channel_set_flags(self->stream, flags, &gerr);
	if (status != G_IO_STATUS_NORMAL) {
		if (gerr)
			GST_WARNING_OBJECT(self, "Error while "
				"setting server socket to nonblock: "
				"%s", gerr->message);
		else
			GST_WARNING_OBJECT(self, "Error while "
				"setting server "
				"socket to nonblock");
	}

	/* It is possible there is some outstanding
	data in the pipe - we have to empty it */
	GST_LOG_OBJECT(self, "emptying stream pipe");
	while (1) {
		err = g_io_channel_read(self->stream, data->buffer,
					(gsize) data->cfg.pkt_len,
					&read);
		if (err != G_IO_ERROR_NONE || read <= 0)
			break;
	}

	/* set stream socket to block */
	GST_LOG_OBJECT(self, "setting stream socket to block");
	flags = g_io_channel_get_flags(self->stream);
	flags &= ~G_IO_FLAG_NONBLOCK;
	status = g_io_channel_set_flags(self->stream, flags, &gerr);
	if (status != G_IO_STATUS_NORMAL) {
		if (gerr)
			GST_WARNING_OBJECT(self, "Error while "
				"setting server socket to block:"
				"%s", gerr->message);
		else
			GST_WARNING_OBJECT(self, "Error while "
				"setting server "
				"socket to block");
	}

	memset(data->buffer, 0, sizeof(data->buffer));

	return TRUE;
}

static void gst_a2dp_sink_conf_recv_data(GstA2dpSink *sink)
{
	/*
	 * We hold the lock, since we can send a signal.
	 * It is a good practice, according to the glib api.
	 */
	GST_A2DP_SINK_MUTEX_LOCK(sink);

	switch (sink->con_state) {
	case CONFIGURING_SENT_CONF:
		if (gst_a2dp_sink_conf_resp(sink))
			sink->con_state = CONFIGURING_RCVD_DEV_CONF;
		else
			GST_A2DP_SINK_CONFIGURATION_FAIL(sink);
		break;
	case CONFIGURING_RCVD_DEV_CONF:
		if (gst_a2dp_sink_conf_recv_stream_fd(sink))
			GST_A2DP_SINK_CONFIGURATION_SUCCESS(sink);
		else
			GST_A2DP_SINK_CONFIGURATION_FAIL(sink);
		break;
	}

	GST_A2DP_SINK_MUTEX_UNLOCK(sink);
}


static gboolean server_callback(GIOChannel *chan,
					GIOCondition cond, gpointer data)
{
	GstA2dpSink *sink;

	if (cond & G_IO_HUP || cond & G_IO_NVAL)
		return FALSE;
	else if (cond & G_IO_ERR) {
		sink = GST_A2DP_SINK(data);
		GST_WARNING_OBJECT(sink, "Untreated callback G_IO_ERR");
	} else if (cond & G_IO_IN) {
		sink = GST_A2DP_SINK(data);
		if (sink->con_state != NOT_CONFIGURED &&
			sink->con_state != CONFIGURED)
			gst_a2dp_sink_conf_recv_data(sink);
		else
			GST_WARNING_OBJECT(sink, "Unexpected data received");
	} else {
		sink = GST_A2DP_SINK(data);
		GST_WARNING_OBJECT(sink, "Unexpected callback call");
	}

	return TRUE;
}

static gboolean gst_a2dp_sink_start(GstBaseSink *basesink)
{
	GstA2dpSink *self = GST_A2DP_SINK(basesink);
	struct sockaddr_un addr = { AF_UNIX, IPC_SOCKET_NAME };
	gint sk;
	gint err;

	GST_INFO_OBJECT(self, "start");

	self->watch_id = 0;

	sk = socket(PF_LOCAL, SOCK_STREAM, 0);
	if (sk < 0) {
		err = errno;
		GST_ERROR_OBJECT(self, "Cannot open socket: %s (%d)",
			strerror(err), err);
		return FALSE;
	}

	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		err = errno;
		GST_ERROR_OBJECT(self, "Connection fail %s (%d)",
			strerror(err), err);
		close(sk);
		return FALSE;
	}

	self->server = g_io_channel_unix_new(sk);

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

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

	self->stream = NULL;
	self->con_state = NOT_CONFIGURED;

	self->waiting_con_conf = FALSE;

	return TRUE;
}

static gboolean gst_a2dp_sink_send_conf_pkt(GstA2dpSink *sink, GstCaps *caps)
{
	gchar buf[IPC_MTU];
	struct ipc_packet *pkt = (void *) buf;
	gboolean ret;
	gsize bytes_sent;
	GIOError io_error;

	g_assert(sink->con_state == NOT_CONFIGURED);

	memset (pkt, 0, sizeof(buf));
	ret = gst_a2dp_sink_init_pkt_conf(sink, caps, pkt);
	if (!ret) {
		GST_ERROR_OBJECT(sink, "Couldn't initialize parse caps "
				"to packet configuration");
		return FALSE;
	}

	sink->con_state = CONFIGURING_INIT;

	io_error = g_io_channel_write(sink->server, (gchar *) pkt,
			sizeof(*pkt) + pkt->length, &bytes_sent);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(sink, "Error ocurred while sending "
					"configurarion packet");
		sink->con_state = NOT_CONFIGURED;
		return FALSE;
	}

	GST_DEBUG_OBJECT(sink, "%d bytes sent", bytes_sent);
	sink->con_state = CONFIGURING_SENT_CONF;

	return TRUE;
}

static gboolean gst_a2dp_sink_start_dev_conf(GstA2dpSink *sink, GstCaps *caps)
{
	gboolean ret;

	g_assert(sink->con_state == NOT_CONFIGURED);

	GST_DEBUG_OBJECT(sink, "starting device configuration");

	ret = gst_a2dp_sink_send_conf_pkt(sink, caps);

	return ret;
}

static GstFlowReturn gst_a2dp_sink_preroll(GstBaseSink *basesink,
					GstBuffer *buffer)
{
	GstA2dpSink *sink = GST_A2DP_SINK(basesink);

	GST_A2DP_SINK_MUTEX_LOCK(sink);

	if (sink->con_state == NOT_CONFIGURED)
		gst_a2dp_sink_start_dev_conf(sink, GST_BUFFER_CAPS(buffer));

	/* wait for the connection process to finish */
	if (sink->con_state != CONFIGURED)
		GST_A2DP_SINK_WAIT_CON_END(sink);

	GST_A2DP_SINK_MUTEX_UNLOCK(sink);

	if (sink->con_state != CONFIGURED)
		return GST_FLOW_ERROR;

	return GST_FLOW_OK;
}

static int gst_a2dp_sink_avdtp_write(GstA2dpSink *self)
{
	gsize ret;
	struct bluetooth_data *data = self->data;
	struct rtp_header *header;
	struct rtp_payload *payload;
	GIOError err;

	header = (void *) data->buffer;
	payload = (void *) (data->buffer + sizeof(*header));

	memset(data->buffer, 0, sizeof(*header) + sizeof(*payload));

	payload->frame_count = data->frame_count;
	header->v = 2;
	header->pt = 1;
	header->sequence_number = htons(data->seq_num);
	header->timestamp = htonl(data->nsamples);
	header->ssrc = htonl(1);

	err = g_io_channel_write(self->stream, data->buffer, data->count, &ret);
	if (err != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while sending data");
		ret = -1;
	}

	/* Reset buffer of data to send */
	data->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
	data->frame_count = 0;
	data->samples = 0;
	data->seq_num++;

	return ret;
}

static GstFlowReturn gst_a2dp_sink_render(GstBaseSink *basesink,
					GstBuffer *buffer)
{
	GstA2dpSink *self = GST_A2DP_SINK(basesink);
	struct bluetooth_data *data = self->data;
	gint encoded;
	gint ret;

	encoded = GST_BUFFER_SIZE(buffer);

	if (data->count + encoded >= data->cfg.pkt_len) {
		ret = gst_a2dp_sink_avdtp_write(self);
		if (ret < 0)
			return GST_FLOW_ERROR;
	}

	memcpy(data->buffer + data->count, GST_BUFFER_DATA(buffer), encoded);
	data->count += encoded;
	data->frame_count++;

	return GST_FLOW_OK;
}

static gboolean gst_a2dp_sink_set_caps(GstBaseSink *basesink, GstCaps *caps)
{
	GstA2dpSink *self = GST_A2DP_SINK(basesink);

	GST_A2DP_SINK_MUTEX_LOCK(self);
	if (self->con_state == NOT_CONFIGURED)
		gst_a2dp_sink_start_dev_conf(self, caps);
	GST_A2DP_SINK_MUTEX_UNLOCK(self);

	return TRUE;
}

static gboolean gst_a2dp_sink_unlock(GstBaseSink *basesink)
{
	GstA2dpSink *self = GST_A2DP_SINK(basesink);

	if (self->stream != NULL)
		g_io_channel_flush (self->stream, NULL);

	return TRUE;
}

static void gst_a2dp_sink_class_init(GstA2dpSinkClass *klass)
{
	GObjectClass *object_class = G_OBJECT_CLASS(klass);
	GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS(klass);

	parent_class = g_type_class_peek_parent(klass);

	object_class->finalize = GST_DEBUG_FUNCPTR(gst_a2dp_sink_finalize);
	object_class->set_property = GST_DEBUG_FUNCPTR(
					gst_a2dp_sink_set_property);
	object_class->get_property = GST_DEBUG_FUNCPTR(
					gst_a2dp_sink_get_property);

	basesink_class->start = GST_DEBUG_FUNCPTR(gst_a2dp_sink_start);
	basesink_class->stop = GST_DEBUG_FUNCPTR(gst_a2dp_sink_stop);
	basesink_class->render = GST_DEBUG_FUNCPTR(gst_a2dp_sink_render);
	basesink_class->preroll = GST_DEBUG_FUNCPTR(gst_a2dp_sink_preroll);
	basesink_class->set_caps = GST_DEBUG_FUNCPTR(gst_a2dp_sink_set_caps);
	basesink_class->unlock = GST_DEBUG_FUNCPTR(gst_a2dp_sink_unlock);

	g_object_class_install_property(object_class, PROP_DEVICE,
					g_param_spec_string("device", "Device",
					"Bluetooth remote device address",
					NULL, G_PARAM_READWRITE));

	GST_DEBUG_CATEGORY_INIT(a2dp_sink_debug, "a2dpsink", 0,
				"A2DP sink element");
}

static void gst_a2dp_sink_init(GstA2dpSink *self, GstA2dpSinkClass *klass)
{
	self->device = NULL;
	self->data = NULL;

	self->stream = NULL;
	self->con_state = NOT_CONFIGURED;

	self->con_conf_end = g_cond_new();
	self->waiting_con_conf = FALSE;
	self->sink_lock = g_mutex_new();
}
