/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2008  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 <gst/rtp/gstrtpbuffer.h>

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

#include "gstavdtpsink.h"

GST_DEBUG_CATEGORY_STATIC(avdtp_sink_debug);
#define GST_CAT_DEFAULT avdtp_sink_debug

#define BUFFER_SIZE 2048
#define TEMPLATE_MAX_BITPOOL 64
#define CRC_PROTECTED 1
#define CRC_UNPROTECTED 0

#define DEFAULT_AUTOCONNECT TRUE

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

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


struct bluetooth_data {
	struct bt_getcapabilities_rsp caps; /* Bluetooth device caps */
	guint link_mtu;

	gchar buffer[BUFFER_SIZE];	/* Codec transfer buffer */
};

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

enum {
	PROP_0,
	PROP_DEVICE,
	PROP_AUTOCONNECT
};

GST_BOILERPLATE(GstAvdtpSink, gst_avdtp_sink, GstBaseSink,
			GST_TYPE_BASE_SINK);

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

static GstStaticPadTemplate avdtp_sink_factory =
	GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
		GST_STATIC_CAPS("application/x-rtp, "
				"media = (string) \"audio\","
				"payload = (int) "
					GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
				"clock-rate = (int) { 16000, 32000, "
					"44100, 48000 }, "
				"encoding-name = (string) \"SBC\"; "
				"application/x-rtp, "
				"media = (string) \"audio\", "
				"payload = (int) "
				GST_RTP_PAYLOAD_MPA_STRING ", "
				"clock-rate = (int) 90000; "
				"application/x-rtp, "
				"media = (string) \"audio\", "
				"payload = (int) "
				GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
				"clock-rate = (int) 90000, "
				"encoding-name = (string) \"MPA\""
				));

static GIOError gst_avdtp_sink_audioservice_send(GstAvdtpSink *self,
					const bt_audio_msg_header_t *msg);
static GIOError gst_avdtp_sink_audioservice_expect(
				GstAvdtpSink *self,
				bt_audio_msg_header_t *outmsg,
				int expected_type);


static void gst_avdtp_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(&avdtp_sink_factory));

	gst_element_class_set_details(element_class, &avdtp_sink_details);
}

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_flush(self->stream, NULL);
		g_io_channel_close(self->stream);
		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;
}

static void gst_avdtp_sink_finalize(GObject *object)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(object);

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

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

	g_mutex_free(self->sink_lock);

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

static void gst_avdtp_sink_set_property(GObject *object, guint prop_id,
					const GValue *value, GParamSpec *pspec)
{
	GstAvdtpSink *sink = GST_AVDTP_SINK(object);

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

	case PROP_AUTOCONNECT:
		sink->autoconnect = g_value_get_boolean(value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static void gst_avdtp_sink_get_property(GObject *object, guint prop_id,
					GValue *value, GParamSpec *pspec)
{
	GstAvdtpSink *sink = GST_AVDTP_SINK(object);

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

	case PROP_AUTOCONNECT:
		g_value_set_boolean(value, sink->autoconnect);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static gint gst_avdtp_sink_bluetooth_recvmsg_fd(GstAvdtpSink *sink)
{
	int err, ret;

	ret = bt_audio_service_get_data_fd(
			g_io_channel_unix_get_fd(sink->server));

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

	sink->stream = g_io_channel_unix_new(ret);
	GST_DEBUG_OBJECT(sink, "stream_fd=%d", ret);

	return 0;
}

static gboolean gst_avdtp_sink_init_sbc_pkt_conf(GstAvdtpSink *sink,
					GstCaps *caps,
					sbc_capabilities_t *pkt)
{
	sbc_capabilities_t *cfg = &sink->data->caps.sbc_capabilities;
	const GValue *value = NULL;
	const char *pref, *name;
	gint rate, subbands, blocks;
	GstStructure *structure = gst_caps_get_structure(caps, 0);

	name = gst_structure_get_name(structure);

	if (!(IS_SBC(name))) {
		GST_ERROR_OBJECT(sink, "Unexpected format %s, "
				"was expecting sbc", name);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "rate");
	rate = g_value_get_int(value);
	if (rate == 44100)
		cfg->frequency = BT_SBC_SAMPLING_FREQ_44100;
	else if (rate == 48000)
		cfg->frequency = BT_SBC_SAMPLING_FREQ_48000;
	else if (rate == 32000)
		cfg->frequency = BT_SBC_SAMPLING_FREQ_32000;
	else if (rate == 16000)
		cfg->frequency = BT_SBC_SAMPLING_FREQ_16000;
	else {
		GST_ERROR_OBJECT(sink, "Invalid rate while setting caps");
		return FALSE;
	}

	value = gst_structure_get_value(structure, "mode");
	pref = g_value_get_string(value);
	if (strcmp(pref, "mono") == 0)
		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
	else if (strcmp(pref, "dual") == 0)
		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
	else if (strcmp(pref, "stereo") == 0)
		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
	else if (strcmp(pref, "joint") == 0)
		cfg->channel_mode = BT_A2DP_CHANNEL_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, "loudness") == 0)
		cfg->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
	else if (strcmp(pref, "snr") == 0)
		cfg->allocation_method = BT_A2DP_ALLOCATION_SNR;
	else {
		GST_ERROR_OBJECT(sink, "Invalid allocation: %s", pref);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "subbands");
	subbands = g_value_get_int(value);
	if (subbands == 8)
		cfg->subbands = BT_A2DP_SUBBANDS_8;
	else if (subbands == 4)
		cfg->subbands = BT_A2DP_SUBBANDS_4;
	else {
		GST_ERROR_OBJECT(sink, "Invalid subbands %d", subbands);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "blocks");
	blocks = g_value_get_int(value);
	if (blocks == 16)
		cfg->block_length = BT_A2DP_BLOCK_LENGTH_16;
	else if (blocks == 12)
		cfg->block_length = BT_A2DP_BLOCK_LENGTH_12;
	else if (blocks == 8)
		cfg->block_length = BT_A2DP_BLOCK_LENGTH_8;
	else if (blocks == 4)
		cfg->block_length = BT_A2DP_BLOCK_LENGTH_4;
	else {
		GST_ERROR_OBJECT(sink, "Invalid blocks %d", blocks);
		return FALSE;
	}

	value = gst_structure_get_value(structure, "bitpool");
	cfg->max_bitpool = cfg->min_bitpool = g_value_get_int(value);

	memcpy(pkt, cfg, sizeof(*pkt));

	return TRUE;
}

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

	ret = gst_avdtp_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->link_mtu,
					&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 gboolean server_callback(GIOChannel *chan,
					GIOCondition cond, gpointer data)
{
	GstAvdtpSink *sink;

	if (cond & G_IO_HUP || cond & G_IO_NVAL)
		return FALSE;
	else if (cond & G_IO_ERR) {
		sink = GST_AVDTP_SINK(data);
		GST_WARNING_OBJECT(sink, "Untreated callback G_IO_ERR");
	}

	return TRUE;
}

static GstStructure *gst_avdtp_sink_parse_sbc_caps(
			GstAvdtpSink *self, sbc_capabilities_t *sbc)
{
	GstStructure *structure;
	GValue *value;
	GValue *list;
	gboolean mono, stereo;

	structure = gst_structure_empty_new("audio/x-sbc");
	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING);

	/* mode */
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
		g_value_set_static_string(value, "mono");
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) {
		g_value_set_static_string(value, "stereo");
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) {
		g_value_set_static_string(value, "dual");
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) {
		g_value_set_static_string(value, "joint");
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "mode", list);
		g_free(list);
		list = NULL;
	}

	/* subbands */
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	value = g_value_init(value, G_TYPE_INT);
	if (sbc->subbands & BT_A2DP_SUBBANDS_4) {
		g_value_set_int(value, 4);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->subbands & BT_A2DP_SUBBANDS_8) {
		g_value_set_int(value, 8);
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "subbands", list);
		g_free(list);
		list = NULL;
	}

	/* blocks */
	value = g_value_init(value, G_TYPE_INT);
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_16) {
		g_value_set_int(value, 16);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_12) {
		g_value_set_int(value, 12);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_8) {
		g_value_set_int(value, 8);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_4) {
		g_value_set_int(value, 4);
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "blocks", list);
		g_free(list);
		list = NULL;
	}

	/* allocation */
	g_value_init(value, G_TYPE_STRING);
	list = g_value_init(g_new0(GValue,1), GST_TYPE_LIST);
	if (sbc->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) {
		g_value_set_static_string(value, "loudness");
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->allocation_method & BT_A2DP_ALLOCATION_SNR) {
		g_value_set_static_string(value, "snr");
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "allocation", list);
		g_free(list);
		list = NULL;
	}

	/* rate */
	g_value_init(value, G_TYPE_INT);
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {
		g_value_set_int(value, 48000);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {
		g_value_set_int(value, 44100);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {
		g_value_set_int(value, 32000);
		gst_value_list_prepend_value(list, value);
	}
	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {
		g_value_set_int(value, 16000);
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "rate", list);
		g_free(list);
		list = NULL;
	}

	/* bitpool */
	value = g_value_init(value, GST_TYPE_INT_RANGE);
	gst_value_set_int_range(value,
			MIN(sbc->min_bitpool, TEMPLATE_MAX_BITPOOL),
			MIN(sbc->max_bitpool, TEMPLATE_MAX_BITPOOL));
	gst_structure_set_value(structure, "bitpool", value);
	g_value_unset(value);

	/* channels */
	mono = FALSE;
	stereo = FALSE;
	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
		mono = TRUE;
	if ((sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
			(sbc->channel_mode &
			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
			(sbc->channel_mode &
			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
		stereo = TRUE;

	if (mono && stereo) {
		g_value_init(value, GST_TYPE_INT_RANGE);
		gst_value_set_int_range(value, 1, 2);
	} else {
		g_value_init(value, G_TYPE_INT);
		if (mono)
			g_value_set_int(value, 1);
		else if (stereo)
			g_value_set_int(value, 2);
		else {
			GST_ERROR_OBJECT(self,
				"Unexpected number of channels");
			g_value_set_int(value, 0);
		}
	}

	gst_structure_set_value(structure, "channels", value);
	g_free(value);

	return structure;
}

static GstStructure *gst_avdtp_sink_parse_mpeg_caps(
			GstAvdtpSink *self, mpeg_capabilities_t *mpeg)
{
	GstStructure *structure;
	GValue *value;
	GValue *list;
	gboolean valid_layer = FALSE;
	gboolean mono, stereo;

	GST_LOG_OBJECT(self, "parsing mpeg caps");

	structure = gst_structure_empty_new("audio/mpeg");
	value = g_new0(GValue, 1);
	g_value_init(value, G_TYPE_INT);

	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	g_value_set_int(value, 1);
	gst_value_list_prepend_value(list, value);
	g_value_set_int(value, 2);
	gst_value_list_prepend_value(list, value);
	gst_structure_set_value(structure, "mpegversion", list);
	g_free(list);

	/* layer */
	GST_LOG_OBJECT(self, "setting mpeg layer");
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	if (mpeg->layer & BT_MPEG_LAYER_1) {
		g_value_set_int(value, 1);
		gst_value_list_prepend_value(list, value);
		valid_layer = TRUE;
	}
	if (mpeg->layer & BT_MPEG_LAYER_2) {
		g_value_set_int(value, 2);
		gst_value_list_prepend_value(list, value);
		valid_layer = TRUE;
	}
	if (mpeg->layer & BT_MPEG_LAYER_3) {
		g_value_set_int(value, 3);
		gst_value_list_prepend_value(list, value);
		valid_layer = TRUE;
	}
	if (list) {
		gst_structure_set_value(structure, "layer", list);
		g_free(list);
		list = NULL;
	}

	if (!valid_layer) {
		gst_structure_free(structure);
		g_free(value);
		return NULL;
	}

	/* rate */
	GST_LOG_OBJECT(self, "setting mpeg rate");
	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_48000) {
		g_value_set_int(value, 48000);
		gst_value_list_prepend_value(list, value);
	}
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_44100) {
		g_value_set_int(value, 44100);
		gst_value_list_prepend_value(list, value);
	}
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_32000) {
		g_value_set_int(value, 32000);
		gst_value_list_prepend_value(list, value);
	}
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_24000) {
		g_value_set_int(value, 24000);
		gst_value_list_prepend_value(list, value);
	}
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_22050) {
		g_value_set_int(value, 22050);
		gst_value_list_prepend_value(list, value);
	}
	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_16000) {
		g_value_set_int(value, 16000);
		gst_value_list_prepend_value(list, value);
	}
	g_value_unset(value);
	if (list) {
		gst_structure_set_value(structure, "rate", list);
		g_free(list);
		list = NULL;
	}

	/* channels */
	GST_LOG_OBJECT(self, "setting mpeg channels");
	mono = FALSE;
	stereo = FALSE;
	if (mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
		mono = TRUE;
	if ((mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
			(mpeg->channel_mode &
			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
			(mpeg->channel_mode &
			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
		stereo = TRUE;

	if (mono && stereo) {
		g_value_init(value, GST_TYPE_INT_RANGE);
		gst_value_set_int_range(value, 1, 2);
	} else {
		g_value_init(value, G_TYPE_INT);
		if (mono)
			g_value_set_int(value, 1);
		else if (stereo)
			g_value_set_int(value, 2);
		else {
			GST_ERROR_OBJECT(self,
				"Unexpected number of channels");
			g_value_set_int(value, 0);
		}
	}
	gst_structure_set_value(structure, "channels", value);
	g_free(value);

	return structure;
}

static gboolean gst_avdtp_sink_update_caps(GstAvdtpSink *self)
{
	sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities;
	mpeg_capabilities_t *mpeg = &self->data->caps.mpeg_capabilities;
	GstStructure *sbc_structure;
	GstStructure *mpeg_structure;
	gchar *tmp;

	GST_LOG_OBJECT(self, "updating device caps");

	sbc_structure = gst_avdtp_sink_parse_sbc_caps(self, sbc);
	mpeg_structure = gst_avdtp_sink_parse_mpeg_caps(self, mpeg);

	if (self->dev_caps != NULL)
		gst_caps_unref(self->dev_caps);
	self->dev_caps = gst_caps_new_full(sbc_structure, NULL);
	if (mpeg_structure != NULL)
		gst_caps_append_structure(self->dev_caps, mpeg_structure);

	tmp = gst_caps_to_string(self->dev_caps);
	GST_DEBUG_OBJECT(self, "Device capabilities: %s", tmp);
	g_free(tmp);

	return TRUE;
}

static gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self)
{
	gchar *buf[BT_AUDIO_IPC_PACKET_SIZE];
	struct bt_getcapabilities_req *req = (void *) buf;
	struct bt_getcapabilities_rsp *rsp = (void *) buf;
	GIOError io_error;

	memset(req, 0, BT_AUDIO_IPC_PACKET_SIZE);

	req->h.msg_type = BT_GETCAPABILITIES_REQ;
	if (self->device == NULL)
		return FALSE;
	strncpy(req->device, self->device, 18);
	if (self->autoconnect)
		req->flags |= BT_FLAG_AUTOCONNECT;

	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while asking device caps");
		return FALSE;
	}

	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->rsp_h.msg_h, BT_GETCAPABILITIES_RSP);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while getting device caps");
		return FALSE;
	}

	if (rsp->rsp_h.posix_errno != 0) {
		GST_ERROR_OBJECT(self, "BT_GETCAPABILITIES failed : %s(%d)",
					strerror(rsp->rsp_h.posix_errno),
					rsp->rsp_h.posix_errno);
		return FALSE;
	}

	memcpy(&self->data->caps, rsp, sizeof(*rsp));
	if (!gst_avdtp_sink_update_caps(self)) {
		GST_WARNING_OBJECT(self, "failed to update capabilities");
		return FALSE;
	}

	return TRUE;
}

static gint gst_avdtp_sink_get_channel_mode(const gchar *mode)
{
	if (strcmp(mode, "stereo") == 0)
		return BT_A2DP_CHANNEL_MODE_STEREO;
	else if (strcmp(mode, "joint-stereo") == 0)
		return BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
	else if (strcmp(mode, "dual-channel") == 0)
		return BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
	else if (strcmp(mode, "mono") == 0)
		return BT_A2DP_CHANNEL_MODE_MONO;
	else
		return -1;
}

static void gst_avdtp_sink_tag(const GstTagList *taglist,
			const gchar* tag, gpointer user_data)
{
	gboolean crc;
	gchar *channel_mode = NULL;
	GstAvdtpSink *self = GST_AVDTP_SINK(user_data);

	if (strcmp(tag, "has-crc") == 0) {

		if (!gst_tag_list_get_boolean(taglist, tag, &crc)) {
			GST_WARNING_OBJECT(self, "failed to get crc tag");
			return;
		}

		gst_avdtp_sink_set_crc(self, crc);

	} else if (strcmp(tag, "channel-mode") == 0) {

		if (!gst_tag_list_get_string(taglist, tag, &channel_mode)) {
			GST_WARNING_OBJECT(self,
				"failed to get channel-mode tag");
			return;
		}

		self->channel_mode = gst_avdtp_sink_get_channel_mode(
					channel_mode);
		if (self->channel_mode == -1)
			GST_WARNING_OBJECT(self, "Received invalid channel "
					"mode: %s", channel_mode);
		g_free(channel_mode);

	} else
		GST_DEBUG_OBJECT(self, "received unused tag: %s", tag);
}

static gboolean gst_avdtp_sink_event(GstBaseSink *basesink,
			GstEvent *event)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
	GstTagList *taglist = NULL;

	if (GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
		/* we check the tags, mp3 has tags that are importants and
		 * are outside caps */
		gst_event_parse_tag(event, &taglist);
		gst_tag_list_foreach(taglist, gst_avdtp_sink_tag, self);
	}

	return TRUE;
}

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);
	memset(self->data, 0, sizeof(struct bluetooth_data));

	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;
}

static gboolean gst_avdtp_sink_stream_start(GstAvdtpSink *self)
{
	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
	struct bt_streamstart_req *req = (void *) buf;
	struct bt_streamstart_rsp *rsp = (void *) buf;
	struct bt_streamfd_ind *ind = (void*) buf;
	GIOError io_error;

	GST_DEBUG_OBJECT(self, "stream start");

	memset (req, 0, sizeof(buf));
	req->h.msg_type = BT_STREAMSTART_REQ;

	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error ocurred while sending "
					"start packet");
		return FALSE;
	}

	GST_DEBUG_OBJECT(self, "stream start packet sent");

	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->rsp_h.msg_h, BT_STREAMSTART_RSP);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while stream "
			"start confirmation");
		return FALSE;
	}

	if (rsp->rsp_h.posix_errno != 0) {
		GST_ERROR_OBJECT(self, "BT_STREAMSTART_RSP failed : %s(%d)",
					strerror(rsp->rsp_h.posix_errno),
					rsp->rsp_h.posix_errno);
		return FALSE;
	}

	GST_DEBUG_OBJECT(self, "stream started");

	io_error = gst_avdtp_sink_audioservice_expect(self, &ind->h,
			BT_STREAMFD_IND);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while receiving "
			"stream filedescriptor");
		return FALSE;
	}

	if (!gst_avdtp_sink_conf_recv_stream_fd(self))
		return FALSE;

	return TRUE;
}

static gboolean gst_avdtp_sink_init_mp3_pkt_conf(
		GstAvdtpSink *self, GstCaps *caps,
		mpeg_capabilities_t *pkt)
{
	const GValue *value = NULL;
	gint rate, layer;
	const gchar* name;
	GstStructure *structure = gst_caps_get_structure(caps, 0);

	name = gst_structure_get_name(structure);

	if (!(IS_MPEG_AUDIO(name))) {
		GST_ERROR_OBJECT(self, "Unexpected format %s, "
				"was expecting mp3", name);
		return FALSE;
	}

	/* layer */
	value = gst_structure_get_value(structure, "layer");
	layer = g_value_get_int(value);
	if (layer == 1)
		pkt->layer = BT_MPEG_LAYER_1;
	else if (layer == 2)
		pkt->layer = BT_MPEG_LAYER_2;
	else if (layer == 3)
		pkt->layer = BT_MPEG_LAYER_3;
	else {
		GST_ERROR_OBJECT(self, "Unexpected layer: %d", layer);
		return FALSE;
	}

	/* crc */
	if (self->mp3_using_crc != -1)
		pkt->crc = self->mp3_using_crc;
	else {
		GST_ERROR_OBJECT(self, "No info about crc was received, "
				" can't proceed");
		return FALSE;
	}

	/* channel mode */
	if (self->channel_mode != -1)
		pkt->channel_mode = self->channel_mode;
	else {
		GST_ERROR_OBJECT(self, "No info about channel mode "
				"received, can't proceed");
		return FALSE;
	}

	/* mpf - we will only use the mandatory one */
	pkt->mpf = 0;

	value = gst_structure_get_value(structure, "rate");
	rate = g_value_get_int(value);
	if (rate == 44100)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_44100;
	else if (rate == 48000)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_48000;
	else if (rate == 32000)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_32000;
	else if (rate == 24000)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_24000;
	else if (rate == 22050)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_22050;
	else if (rate == 16000)
		pkt->frequency = BT_MPEG_SAMPLING_FREQ_16000;
	else {
		GST_ERROR_OBJECT(self, "Invalid rate while setting caps");
		return FALSE;
	}

	/* vbr - we always say its vbr, we don't have how to know it */
	pkt->bitrate = 0x8000;

	return TRUE;
}

static gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
			GstCaps *caps)
{
	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
	struct bt_setconfiguration_req *req = (void *) buf;
	struct bt_setconfiguration_rsp *rsp = (void *) buf;
	gboolean ret;
	GIOError io_error;
	gchar *temp;
	GstStructure *structure;

	temp = gst_caps_to_string(caps);
	GST_DEBUG_OBJECT(self, "configuring device with caps: %s", temp);
	g_free(temp);

	memset (req, 0, sizeof(buf));
	req->h.msg_type = BT_SETCONFIGURATION_REQ;
	req->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
	strncpy(req->device, self->device, 18);
	structure = gst_caps_get_structure(caps, 0);

	if (gst_structure_has_name(structure, "audio/x-sbc"))
		ret = gst_avdtp_sink_init_sbc_pkt_conf(self, caps,
				&req->sbc_capabilities);
	else if (gst_structure_has_name(structure, "audio/mpeg"))
		ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
				&req->mpeg_capabilities);
	else
		ret = FALSE;

	if (!ret) {
		GST_ERROR_OBJECT(self, "Couldn't parse caps "
				"to packet configuration");
		return FALSE;
	}

	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error ocurred while sending "
					"configurarion packet");
		return FALSE;
	}

	GST_DEBUG_OBJECT(self, "configuration packet sent");

	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->rsp_h.msg_h, BT_SETCONFIGURATION_RSP);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while receiving device "
					"confirmation");
		return FALSE;
	}

	if (rsp->rsp_h.posix_errno != 0) {
		GST_ERROR_OBJECT(self, "BT_SETCONFIGURATION_RSP failed : "
					"%s(%d)",
					strerror(rsp->rsp_h.posix_errno),
					rsp->rsp_h.posix_errno);
		return FALSE;
	}

	self->data->link_mtu = rsp->link_mtu;
	GST_DEBUG_OBJECT(self, "configuration set");

	return TRUE;
}

static GstFlowReturn gst_avdtp_sink_preroll(GstBaseSink *basesink,
					GstBuffer *buffer)
{
	GstAvdtpSink *sink = GST_AVDTP_SINK(basesink);
	gboolean ret;

	GST_AVDTP_SINK_MUTEX_LOCK(sink);

	ret = gst_avdtp_sink_stream_start(sink);

	GST_AVDTP_SINK_MUTEX_UNLOCK(sink);

	if (!ret)
		return GST_FLOW_ERROR;

	return GST_FLOW_OK;
}

static GstFlowReturn gst_avdtp_sink_render(GstBaseSink *basesink,
					GstBuffer *buffer)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
	gsize ret;
	GIOError err;

	err = g_io_channel_write(self->stream, (gchar*)GST_BUFFER_DATA(buffer),
			 (gsize)(GST_BUFFER_SIZE(buffer)), &ret);

	if (err != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while writting to socket: %d %s",
				errno, strerror(errno));
		return GST_FLOW_ERROR;
	}

	return GST_FLOW_OK;
}

static gboolean gst_avdtp_sink_unlock(GstBaseSink *basesink)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);

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

	return TRUE;
}

static GstFlowReturn gst_avdtp_sink_buffer_alloc(GstBaseSink *basesink,
				guint64 offset, guint size, GstCaps* caps,
				GstBuffer **buf)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);

	*buf = gst_buffer_new_and_alloc(size);
	if (!(*buf)) {
		GST_ERROR_OBJECT(self, "buffer allocation failed");
		return GST_FLOW_ERROR;
	}

	gst_buffer_set_caps(*buf, caps);

	GST_BUFFER_OFFSET(*buf) = offset;

	return GST_FLOW_OK;
}

static void gst_avdtp_sink_class_init(GstAvdtpSinkClass *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_avdtp_sink_finalize);
	object_class->set_property = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_set_property);
	object_class->get_property = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_get_property);

	basesink_class->start = GST_DEBUG_FUNCPTR(gst_avdtp_sink_start);
	basesink_class->stop = GST_DEBUG_FUNCPTR(gst_avdtp_sink_stop);
	basesink_class->render = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_render);
	basesink_class->preroll = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_preroll);
	basesink_class->unlock = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_unlock);
	basesink_class->event = GST_DEBUG_FUNCPTR(
					gst_avdtp_sink_event);

	basesink_class->buffer_alloc =
		GST_DEBUG_FUNCPTR(gst_avdtp_sink_buffer_alloc);

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

	g_object_class_install_property(object_class, PROP_AUTOCONNECT,
					g_param_spec_boolean("auto-connect",
					"Auto-connect",
					"Automatically attempt to connect "
					"to device", DEFAULT_AUTOCONNECT,
					G_PARAM_READWRITE));

	GST_DEBUG_CATEGORY_INIT(avdtp_sink_debug, "avdtpsink", 0,
				"A2DP headset sink element");
}

static void gst_avdtp_sink_init(GstAvdtpSink *self,
			GstAvdtpSinkClass *klass)
{
	self->device = NULL;
	self->data = NULL;

	self->stream = NULL;

	self->dev_caps = NULL;

	self->autoconnect = DEFAULT_AUTOCONNECT;

	self->sink_lock = g_mutex_new();

	/* FIXME this is for not synchronizing with clock, should be tested
	 * with devices to see the behaviour
	gst_base_sink_set_sync(GST_BASE_SINK(self), FALSE);
	*/
}

static GIOError gst_avdtp_sink_audioservice_send(
					GstAvdtpSink *self,
					const bt_audio_msg_header_t *msg)
{
	GIOError error;
	gsize written;

	error = g_io_channel_write(self->server, (const gchar*) msg,
			BT_AUDIO_IPC_PACKET_SIZE, &written);
	if (error != G_IO_ERROR_NONE)
		GST_ERROR_OBJECT(self, "Error sending data to audio service:"
			" %s(%d)", strerror(errno), errno);

	return error;
}

static GIOError gst_avdtp_sink_audioservice_recv(
					GstAvdtpSink *self,
					bt_audio_msg_header_t *inmsg)
{
	GIOError status;
	gsize bytes_read;
	const char *type;

	status = g_io_channel_read(self->server, (gchar*) inmsg,
			BT_AUDIO_IPC_PACKET_SIZE, &bytes_read);
	if (status != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error receiving data from "
				"audio service");
		return status;
	}

	type = bt_audio_strmsg(inmsg->msg_type);
	if (!type) {
		status = G_IO_ERROR_INVAL;
		GST_ERROR_OBJECT(self, "Bogus message type %d "
				"received from audio service",
				inmsg->msg_type);
	}

	return status;
}

static GIOError gst_avdtp_sink_audioservice_expect(
			GstAvdtpSink *self, bt_audio_msg_header_t *outmsg,
			int expected_type)
{
	GIOError status;

	status = gst_avdtp_sink_audioservice_recv(self, outmsg);
	if (status != G_IO_ERROR_NONE)
		return status;

	if (outmsg->msg_type != expected_type)
		status = G_IO_ERROR_INVAL;

	return status;
}

gboolean gst_avdtp_sink_plugin_init (GstPlugin * plugin)
{
	return gst_element_register (plugin, "avdtpsink",
			GST_RANK_NONE, GST_TYPE_AVDTP_SINK);
}


/* public functions */
GstCaps *gst_avdtp_sink_get_device_caps(GstAvdtpSink *sink)
{
	if (sink->dev_caps == NULL)
		return NULL;

	return gst_caps_copy(sink->dev_caps);
}

gboolean gst_avdtp_sink_set_device_caps(GstAvdtpSink *self,
			GstCaps *caps)
{
	gboolean ret;

	GST_DEBUG_OBJECT(self, "setting device caps");
	GST_AVDTP_SINK_MUTEX_LOCK(self);
	ret = gst_avdtp_sink_configure(self, caps);

	if (self->stream_caps)
		gst_caps_unref(self->stream_caps);
	self->stream_caps = gst_caps_ref(caps);

	GST_AVDTP_SINK_MUTEX_UNLOCK(self);

	return ret;
}

guint gst_avdtp_sink_get_link_mtu(GstAvdtpSink *sink)
{
	return sink->data->link_mtu;
}

void gst_avdtp_sink_set_device(GstAvdtpSink *self, const gchar* dev)
{
	if (self->device != NULL)
		g_free(self->device);

	GST_LOG_OBJECT(self, "Setting device: %s", dev);
	self->device = g_strdup(dev);
}

gchar *gst_avdtp_sink_get_device(GstAvdtpSink *self)
{
	return g_strdup(self->device);
}

void gst_avdtp_sink_set_crc(GstAvdtpSink *self, gboolean crc)
{
	gint new_crc;

	new_crc = crc ? CRC_PROTECTED : CRC_UNPROTECTED;

	/* test if we already received a different crc */
	if (self->mp3_using_crc != -1 && new_crc != self->mp3_using_crc) {
		GST_WARNING_OBJECT(self, "crc changed during stream");
		return;
	}
	self->mp3_using_crc = new_crc;

}

void gst_avdtp_sink_set_channel_mode(GstAvdtpSink *self,
			const gchar *mode)
{
	gint new_mode;

	new_mode = gst_avdtp_sink_get_channel_mode(mode);

	if (self->channel_mode != -1 && new_mode != self->channel_mode) {
		GST_WARNING_OBJECT(self, "channel mode changed during stream");
		return;
	}

	self->channel_mode = new_mode;
	if (self->channel_mode == -1)
		GST_WARNING_OBJECT(self, "Received invalid channel "
				"mode: %s", mode);
}


