/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2010  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 <dbus/dbus.h>

#include "ipc.h"
#include "rtp.h"
#include "a2dp-codecs.h"

#include "gstpragma.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

#ifndef DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD -1
#endif

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

	DBusConnection *conn;
	guint8 codec; /* Bluetooth transport configuration */
	gchar *uuid;
	guint8 *config;
	gint config_size;

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

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 void gst_avdtp_sink_transport_release(GstAvdtpSink *self)
{
	DBusMessage *msg;
	const char *access_type = "w";

	msg = dbus_message_new_method_call("org.bluez", self->transport,
						"org.bluez.MediaTransport",
						"Release");

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &access_type,
					DBUS_TYPE_INVALID);

	dbus_connection_send(self->data->conn, msg, NULL);

	dbus_message_unref(msg);
}

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) {
		if (self->transport)
			gst_avdtp_sink_transport_release(self);
		if (self->data->conn)
			dbus_connection_unref(self->data->conn);
		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);

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

	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;

	case PROP_TRANSPORT:
		if (sink->transport)
			g_free(sink->transport);
		sink->transport = g_value_dup_string(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;

	case PROP_TRANSPORT:
		g_value_set_string(value, sink->transport);
		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) &&
				!(codec->lock & BT_WRITE_LOCK))
			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_SBC_SINK);
	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;

	/* Proceed if stream was already acquired */
	if (self->stream != NULL)
		goto proceed;

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

proceed:
	/* 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)
{
	if (cond & G_IO_HUP || cond & G_IO_NVAL)
		return FALSE;
	else if (cond & G_IO_ERR)
		GST_WARNING_OBJECT(GST_AVDTP_SINK(data),
					"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;

	if (sbc == NULL)
		return NULL;

	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 GstStructure *gst_avdtp_sink_parse_sbc_raw(GstAvdtpSink *self)
{
	a2dp_sbc_t *sbc = (a2dp_sbc_t *) self->data->config;
	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_raw(GstAvdtpSink *self)
{
	a2dp_mpeg_t *mpeg = (a2dp_mpeg_t *) self->data->config;
	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_config(GstAvdtpSink *self)
{
	GstStructure *structure;
	gchar *tmp;

	switch (self->data->codec) {
	case A2DP_CODEC_SBC:
		structure = gst_avdtp_sink_parse_sbc_raw(self);
		break;
	case A2DP_CODEC_MPEG12:
		structure = gst_avdtp_sink_parse_mpeg_raw(self);
		break;
	default:
		GST_ERROR_OBJECT(self, "Unsupported configuration");
		return FALSE;
	}

	if (structure == NULL)
		return FALSE;

	if (self->dev_caps != NULL)
		gst_caps_unref(self->dev_caps);

	self->dev_caps = gst_caps_new_full(structure, NULL);

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

	return TRUE;
}

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");

	if (self->data->config_size != 0 && self->data->config != NULL)
		return gst_avdtp_sink_update_config(self);

	sbc = (void *) gst_avdtp_find_caps(self, BT_A2DP_SBC_SINK);
	mpeg = (void *) gst_avdtp_find_caps(self, BT_A2DP_MPEG12_SINK);

	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->destination, 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_transport_parse_property(GstAvdtpSink *self,
							DBusMessageIter *i)
{
	const char *key;
	DBusMessageIter variant_i;

	if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
		GST_ERROR_OBJECT(self, "Property name not a string.");
		return FALSE;
	}

	dbus_message_iter_get_basic(i, &key);

	if (!dbus_message_iter_next(i))  {
		GST_ERROR_OBJECT(self, "Property value missing");
		return FALSE;
	}

	if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
		GST_ERROR_OBJECT(self, "Property value not a variant.");
		return FALSE;
	}

	dbus_message_iter_recurse(i, &variant_i);

	switch (dbus_message_iter_get_arg_type(&variant_i)) {
	case DBUS_TYPE_BYTE: {
		uint8_t value;
		dbus_message_iter_get_basic(&variant_i, &value);

		if (g_str_equal(key, "Codec") == TRUE)
			self->data->codec = value;

		break;
	}
	case DBUS_TYPE_UINT16: {
		uint16_t value;
		dbus_message_iter_get_basic(&variant_i, &value);

		if (g_str_equal(key, "OMTU") == TRUE)
			self->data->link_mtu = value;

		break;
	}
        case DBUS_TYPE_STRING: {
		const char *value;
		dbus_message_iter_get_basic(&variant_i, &value);

		if (g_str_equal(key, "UUID") == TRUE) {
			g_free(self->data->uuid);
			self->data->uuid = g_strdup(value);
		}

		break;
	}
	case DBUS_TYPE_ARRAY: {
		DBusMessageIter array_i;
		char *value;
		int size;

		dbus_message_iter_recurse(&variant_i, &array_i);
		dbus_message_iter_get_fixed_array(&array_i, &value, &size);

		if (g_str_equal(key, "Configuration")) {
			g_free(self->data->config);
			self->data->config = g_new0(guint8, size);
			self->data->config_size = size;
			memcpy(self->data->config, value, size);
		}

		break;
	}
	}

	return TRUE;
}

static gboolean gst_avdtp_sink_transport_acquire(GstAvdtpSink *self)
{
	DBusMessage *msg, *reply;
	DBusError err;
	const char *access_type = "w";
	int fd;

	dbus_error_init(&err);

	if (self->data->conn == NULL)
		self->data->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);

	msg = dbus_message_new_method_call("org.bluez", self->transport,
						"org.bluez.MediaTransport",
						"Acquire");

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &access_type,
					DBUS_TYPE_INVALID);

	reply = dbus_connection_send_with_reply_and_block(self->data->conn,
							msg, -1, &err);

	if (dbus_error_is_set(&err))
		goto fail;

	if (dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd,
					DBUS_TYPE_INVALID) == FALSE)
		goto fail;

	dbus_message_unref(reply);

	self->stream = g_io_channel_unix_new(fd);
	g_io_channel_set_close_on_unref(self->stream, TRUE);
	GST_DEBUG_OBJECT(self, "stream_fd=%d", fd);

	return TRUE;

fail:
	GST_ERROR_OBJECT(self, "Failed to acquire transport stream: %s",
				err.message);

	dbus_error_free(&err);

	if (reply)
		dbus_message_unref(msg);

	return FALSE;
}

static gboolean gst_avdtp_sink_transport_get_properties(GstAvdtpSink *self)
{
	DBusMessage *msg, *reply;
	DBusMessageIter arg_i, ele_i;
	DBusError err;

	dbus_error_init(&err);

	/* Transport need to be acquire first to make sure the MTUs are
	   available */
	if (gst_avdtp_sink_transport_acquire(self) == FALSE)
		return FALSE;

	msg = dbus_message_new_method_call("org.bluez", self->transport,
						"org.bluez.MediaTransport",
						"GetProperties");
	reply = dbus_connection_send_with_reply_and_block(self->data->conn,
							msg, -1, &err);

	if (dbus_error_is_set(&err) || reply == NULL) {
		GST_ERROR_OBJECT(self, "Failed to get transport properties: %s",
					err.message);
		goto fail;
	}

	if (!dbus_message_iter_init(reply, &arg_i)) {
		GST_ERROR_OBJECT(self, "GetProperties reply has no arguments.");
		goto fail;
	}

	if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_ARRAY) {
		GST_ERROR_OBJECT(self, "GetProperties argument is not an array.");
		goto fail;
	}

	dbus_message_iter_recurse(&arg_i, &ele_i);
	while (dbus_message_iter_get_arg_type(&ele_i) != DBUS_TYPE_INVALID) {

		if (dbus_message_iter_get_arg_type(&ele_i) ==
				DBUS_TYPE_DICT_ENTRY) {
			DBusMessageIter dict_i;

			dbus_message_iter_recurse(&ele_i, &dict_i);

			gst_avdtp_sink_transport_parse_property(self, &dict_i);
		}

		if (!dbus_message_iter_next(&ele_i))
			break;
	}

	return gst_avdtp_sink_update_caps(self);

fail:
	dbus_message_unref(msg);
	dbus_message_unref(reply);
	return FALSE;

}

static gboolean gst_avdtp_sink_start(GstBaseSink *basesink)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
	gint sk;
	gint err;

	GST_INFO_OBJECT(self, "start");

	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 (self->transport != NULL)
		return gst_avdtp_sink_transport_get_properties(self);

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

	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;

	if (self->transport != NULL)
		return gst_avdtp_sink_conf_recv_stream_fd(self);

	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_open_req *open_req = (void *) buf;
	struct bt_open_rsp *open_rsp = (void *) buf;
	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;
	codec_capabilities_t *codec = NULL;

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

	/* Transport already configured */
	if (self->transport != NULL)
		return TRUE;

	structure = gst_caps_get_structure(caps, 0);

	if (gst_structure_has_name(structure, "audio/x-sbc"))
		codec = (void *) gst_avdtp_find_caps(self, BT_A2DP_SBC_SINK);
	else if (gst_structure_has_name(structure, "audio/mpeg"))
		codec = (void *) gst_avdtp_find_caps(self, BT_A2DP_MPEG12_SINK);

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

	memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
	open_req->h.type = BT_REQUEST;
	open_req->h.name = BT_OPEN;
	open_req->h.length = sizeof(*open_req);

	strncpy(open_req->destination, self->device, 18);
	open_req->seid = codec->seid;
	open_req->lock = BT_WRITE_LOCK;

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

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

	memset(req, 0, sizeof(buf));
	req->h.type = BT_REQUEST;
	req->h.name = BT_SET_CONFIGURATION;
	req->h.length = sizeof(*req);
	memcpy(&req->codec, codec, sizeof(req->codec));

	if (codec->type == BT_A2DP_SBC_SINK)
		ret = gst_avdtp_sink_init_sbc_pkt_conf(self, caps,
				(void *) &req->codec);
	else
		ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
				(void *) &req->codec);

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

	g_object_class_install_property(object_class, PROP_TRANSPORT,
					g_param_spec_string("transport",
					"Transport",
					"Use configured transport",
					NULL, 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->transport = 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);
}

void gst_avdtp_sink_set_transport(GstAvdtpSink *self, const gchar *trans)
{
	if (self->transport != NULL)
		g_free(self->transport);

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

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

gchar *gst_avdtp_sink_get_transport(GstAvdtpSink *self)
{
	return g_strdup(self->transport);
}

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