/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2009  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_shutdown(self->stream, TRUE, NULL);
		g_io_channel_unref(self->stream);
		self->stream = NULL;
	}

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

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

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

	return TRUE;
}

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) &&
				!(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;

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

	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_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_start(GstBaseSink *basesink)
{
	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
	gint sk;
	gint err;

	GST_INFO_OBJECT(self, "start");

	self->watch_id = 0;

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

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

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

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

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

	return TRUE;

failed:
	bt_audio_service_close(sk);
	return FALSE;
}

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

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

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

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