/*
 *
 *  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_get_capabilities_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,
				guint8 expected_name);


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 codec_capabilities_t *gst_avdtp_find_caps(GstAvdtpSink *sink,
						uint8_t codec_type)
{
	struct bt_get_capabilities_rsp *rsp = sink->data->caps;
	codec_capabilities_t *codec = (void *) rsp->data;
	int bytes_left = rsp->h.length - sizeof(*rsp);

	while (bytes_left > 0) {
		if (codec->type == codec_type)
			break;

		bytes_left -= codec->length;
		codec = (void *) codec + codec->length;
	}

	if (bytes_left <= 0)
		return NULL;

	return codec;
}

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

	cfg = (void *) gst_avdtp_find_caps(sink, BT_A2DP_CODEC_SBC);
	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;

	if (!mpeg)
		return NULL;

	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;
	mpeg_capabilities_t *mpeg;
	GstStructure *sbc_structure;
	GstStructure *mpeg_structure;
	gchar *tmp;

	GST_LOG_OBJECT(self, "updating device caps");

	sbc = (void *) gst_avdtp_find_caps(self, BT_A2DP_CODEC_SBC);
	mpeg = (void *) gst_avdtp_find_caps(self, BT_A2DP_CODEC_MPEG12);

	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_SUGGESTED_BUFFER_SIZE];
	struct bt_get_capabilities_req *req = (void *) buf;
	struct bt_get_capabilities_rsp *rsp = (void *) buf;
	GIOError io_error;

	memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);

	req->h.type = BT_REQUEST;
	req->h.name = BT_GET_CAPABILITIES;
	req->h.length = sizeof(*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;
	}

	rsp->h.length = 0;
	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->h, BT_GET_CAPABILITIES);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while getting device caps");
		return FALSE;
	}

	self->data->caps = g_malloc0(rsp->h.length);
	memcpy(self->data->caps, rsp, rsp->h.length);
	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_SUGGESTED_BUFFER_SIZE];
	struct bt_start_stream_req *req = (void *) buf;
	struct bt_start_stream_rsp *rsp = (void *) buf;
	struct bt_new_stream_ind *ind = (void *) buf;
	GIOError io_error;

	memset(req, 0, sizeof(buf));
	req->h.type = BT_REQUEST;
	req->h.name = BT_START_STREAM;
	req->h.length = sizeof(*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;
	}

	rsp->h.length = sizeof(*rsp);
	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->h, BT_START_STREAM);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while stream "
			"start confirmation");
		return FALSE;
	}

	ind->h.length = sizeof(*ind);
	io_error = gst_avdtp_sink_audioservice_expect(self, &ind->h,
			BT_NEW_STREAM);
	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_SUGGESTED_BUFFER_SIZE];
	struct bt_set_configuration_req *req = (void *) buf;
	struct bt_set_configuration_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.type = BT_REQUEST;
	req->h.name = BT_SET_CONFIGURATION;
	req->h.length = sizeof(*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,
				(void *) &req->codec);
	else if (gst_structure_has_name(structure, "audio/mpeg"))
		ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
				(void *) &req->codec);
	else
		ret = FALSE;

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

	req->h.length += req->codec.length - sizeof(req->codec);
	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;
	}

	rsp->h.length = sizeof(*rsp);
	io_error = gst_avdtp_sink_audioservice_expect(self,
			&rsp->h, BT_SET_CONFIGURATION);
	if (io_error != G_IO_ERROR_NONE) {
		GST_ERROR_OBJECT(self, "Error while receiving device "
					"confirmation");
		return FALSE;
	}

	self->data->link_mtu = rsp->link_mtu;

	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;
	const char *type, *name;
	uint16_t length;

	length = msg->length ? msg->length : BT_SUGGESTED_BUFFER_SIZE;

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

	type = bt_audio_strtype(msg->type);
	name = bt_audio_strname(msg->name);

	GST_DEBUG_OBJECT(self, "sent: %s -> %s", type, name);

	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, *name;
	uint16_t length;

	length = inmsg->length ? inmsg->length : BT_SUGGESTED_BUFFER_SIZE;

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

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

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

	if (inmsg->type == BT_ERROR) {
		bt_audio_error_t *err = (void *) inmsg;
		status = G_IO_ERROR_INVAL;
		GST_ERROR_OBJECT(self, "%s failed : "
					"%s(%d)",
					name,
					strerror(err->posix_errno),
					err->posix_errno);
	}

	GST_DEBUG_OBJECT(self, "received: %s <- %s", type, name);

	return status;
}

static GIOError gst_avdtp_sink_audioservice_expect(
			GstAvdtpSink *self, bt_audio_msg_header_t *outmsg,
			guint8 expected_name)
{
	GIOError status;

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

	if (outmsg->name != expected_name)
		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);
}
