/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
 *
 *
 *  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 <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <glib.h>

#include "btio/btio.h"
#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "profiles/audio/a2dp-codecs.h"
#include "src/log.h"
#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "a2dp.h"
#include "utils.h"
#include "bluetooth.h"
#include "avdtp.h"
#include "avrcp.h"
#include "audio-msg.h"

#define L2CAP_PSM_AVDTP 0x19
#define SVC_HINT_CAPTURING 0x08
#define IDLE_TIMEOUT 1
#define AUDIO_RETRY_TIMEOUT 2

static GIOChannel *server = NULL;
static GSList *devices = NULL;
static GSList *endpoints = NULL;
static GSList *setups = NULL;
static bdaddr_t adapter_addr;
static uint32_t record_id = 0;
static guint audio_retry_id = 0;
static bool audio_retrying = false;

static struct ipc *hal_ipc = NULL;
static struct ipc *audio_ipc = NULL;

struct a2dp_preset {
	void *data;
	int8_t len;
};

struct a2dp_endpoint {
	uint8_t id;
	uint8_t codec;
	struct avdtp_local_sep *sep;
	struct a2dp_preset *caps;
	GSList *presets;
};

struct a2dp_device {
	bdaddr_t	dst;
	uint8_t		state;
	GIOChannel	*io;
	struct avdtp	*session;
	guint		idle_id;
};

struct a2dp_setup {
	struct a2dp_device *dev;
	struct a2dp_endpoint *endpoint;
	struct a2dp_preset *preset;
	struct avdtp_stream *stream;
	uint8_t state;
};

static int device_cmp(gconstpointer s, gconstpointer user_data)
{
	const struct a2dp_device *dev = s;
	const bdaddr_t *dst = user_data;

	return bacmp(&dev->dst, dst);
}

static void preset_free(void *data)
{
	struct a2dp_preset *preset = data;

	g_free(preset->data);
	g_free(preset);
}

static void unregister_endpoint(void *data)
{
	struct a2dp_endpoint *endpoint = data;

	if (endpoint->sep)
		avdtp_unregister_sep(endpoint->sep);

	if (endpoint->caps)
		preset_free(endpoint->caps);

	g_slist_free_full(endpoint->presets, preset_free);

	g_free(endpoint);
}

static void setup_free(void *data)
{
	struct a2dp_setup *setup = data;

	if (!g_slist_find(setup->endpoint->presets, setup->preset))
		preset_free(setup->preset);

	g_free(setup);
}

static void setup_remove(struct a2dp_setup *setup)
{
	setups = g_slist_remove(setups, setup);
	setup_free(setup);
}

static void setup_remove_all_by_dev(struct a2dp_device *dev)
{
	GSList *l = setups;

	while (l) {
		struct a2dp_setup *setup = l->data;
		GSList *next = g_slist_next(l);

		if (setup->dev == dev)
			setup_remove(setup);

		l = next;
	}
}

static void a2dp_device_free(void *data)
{
	struct a2dp_device *dev = data;

	if (dev->idle_id > 0)
		g_source_remove(dev->idle_id);

	if (dev->session)
		avdtp_unref(dev->session);

	if (dev->io) {
		g_io_channel_shutdown(dev->io, FALSE, NULL);
		g_io_channel_unref(dev->io);
	}

	setup_remove_all_by_dev(dev);

	g_free(dev);
}

static void a2dp_device_remove(struct a2dp_device *dev)
{
	devices = g_slist_remove(devices, dev);
	a2dp_device_free(dev);
}

static struct a2dp_device *a2dp_device_new(const bdaddr_t *dst)
{
	struct a2dp_device *dev;

	dev = g_new0(struct a2dp_device, 1);
	bacpy(&dev->dst, dst);
	devices = g_slist_prepend(devices, dev);

	return dev;
}

static bool a2dp_device_connect(struct a2dp_device *dev, BtIOConnect cb)
{
	GError *err = NULL;

	dev->io = bt_io_connect(cb, dev, NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_AVDTP,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		return false;
	}

	return true;
}

static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
{
	struct hal_ev_a2dp_conn_state ev;
	char address[18];

	if (dev->state == state)
		return;

	dev->state = state;

	ba2str(&dev->dst, address);
	DBG("device %s state %u", address, state);

	bdaddr2android(&dev->dst, ev.bdaddr);
	ev.state = state;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE,
							sizeof(ev), &ev);

	if (state != HAL_A2DP_STATE_DISCONNECTED)
		return;

	bt_avrcp_disconnect(&dev->dst);

	a2dp_device_remove(dev);
}

static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
{
	struct hal_ev_a2dp_audio_state ev;
	char address[18];

	if (setup->state == state)
		return;

	setup->state = state;

	ba2str(&setup->dev->dst, address);
	DBG("device %s state %u", address, state);

	bdaddr2android(&setup->dev->dst, ev.bdaddr);
	ev.state = state;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE,
							sizeof(ev), &ev);
}

static void disconnect_cb(void *user_data)
{
	struct a2dp_device *dev = user_data;

	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
}

static int sbc_check_config(void *caps, uint8_t caps_len, void *conf,
							uint8_t conf_len)
{
	a2dp_sbc_t *cap, *config;

	if (conf_len != caps_len || conf_len != sizeof(a2dp_sbc_t)) {
		error("SBC: Invalid configuration size (%u)", conf_len);
		return -EINVAL;
	}

	cap = caps;
	config = conf;

	if (!(cap->frequency & config->frequency)) {
		error("SBC: Unsupported frequency (%u) by endpoint",
							config->frequency);
		return -EINVAL;
	}

	if (!(cap->channel_mode & config->channel_mode)) {
		error("SBC: Unsupported channel mode (%u) by endpoint",
							config->channel_mode);
		return -EINVAL;
	}

	if (!(cap->block_length & config->block_length)) {
		error("SBC: Unsupported block length (%u) by endpoint",
							config->block_length);
		return -EINVAL;
	}

	if (!(cap->allocation_method & config->allocation_method)) {
		error("SBC: Unsupported allocation method (%u) by endpoint",
							config->block_length);
		return -EINVAL;
	}

	if (config->max_bitpool < cap->min_bitpool) {
		error("SBC: Invalid maximun bitpool (%u < %u)",
					config->max_bitpool, cap->min_bitpool);
		return -EINVAL;
	}

	if (config->min_bitpool > cap->max_bitpool) {
		error("SBC: Invalid minimun bitpool (%u > %u)",
					config->min_bitpool, cap->min_bitpool);
		return -EINVAL;
	}

	if (config->max_bitpool > cap->max_bitpool)
		return -ERANGE;

	if (config->min_bitpool < cap->min_bitpool)
		return -ERANGE;

	return 0;
}

static int check_capabilities(struct a2dp_preset *preset,
				struct avdtp_media_codec_capability *codec,
				uint8_t codec_len)
{
	/* Codec specific */
	switch (codec->media_codec_type) {
	case A2DP_CODEC_SBC:
		return sbc_check_config(codec->data, codec_len, preset->data,
								preset->len);
	default:
		return -EINVAL;
	}
}

static struct a2dp_preset *sbc_select_range(void *caps, uint8_t caps_len,
						void *conf, uint8_t conf_len)
{
	struct a2dp_preset *p;
	a2dp_sbc_t *cap, *config;

	cap = caps;
	config = conf;

	config->min_bitpool = MAX(config->min_bitpool, cap->min_bitpool);
	config->max_bitpool = MIN(config->max_bitpool, cap->max_bitpool);

	p = g_new0(struct a2dp_preset, 1);
	p->len = conf_len;
	p->data = g_memdup(conf, p->len);

	return p;
}

static struct a2dp_preset *select_preset_range(struct a2dp_preset *preset,
				struct avdtp_media_codec_capability *codec,
				uint8_t codec_len)
{
	/* Codec specific */
	switch (codec->media_codec_type) {
	case A2DP_CODEC_SBC:
		return sbc_select_range(codec->data, codec_len, preset->data,
								preset->len);
	default:
		return NULL;
	}
}

static struct a2dp_preset *select_preset(struct a2dp_endpoint *endpoint,
						struct avdtp_remote_sep *rsep)
{
	struct avdtp_service_capability *service;
	struct avdtp_media_codec_capability *codec;
	GSList *l;
	uint8_t codec_len;

	service = avdtp_get_codec(rsep);
	codec = (struct avdtp_media_codec_capability *) service->data;
	codec_len = service->length - sizeof(*codec);

	for (l = endpoint->presets; l; l = g_slist_next(l)) {
		struct a2dp_preset *preset = l->data;
		int err;

		err = check_capabilities(preset, codec, codec_len);
		if (err == 0)
			return preset;

		if (err == -ERANGE)
			return select_preset_range(preset, codec, codec_len);
	}

	return NULL;
}

static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
			struct a2dp_preset *preset, struct avdtp_stream *stream)
{
	struct a2dp_setup *setup;

	setup = g_new0(struct a2dp_setup, 1);
	setup->dev = dev;
	setup->endpoint = endpoint;
	setup->preset = preset;
	setup->stream = stream;
	setups = g_slist_append(setups, setup);

	if (dev->idle_id > 0) {
		g_source_remove(dev->idle_id);
		dev->idle_id = 0;
	}
}

static int select_configuration(struct a2dp_device *dev,
				struct a2dp_endpoint *endpoint,
				struct avdtp_remote_sep *rsep)
{
	struct a2dp_preset *preset;
	struct avdtp_stream *stream;
	struct avdtp_service_capability *service;
	struct avdtp_media_codec_capability *codec;
	GSList *caps;
	int err;

	preset = select_preset(endpoint, rsep);
	if (!preset) {
		error("Unable to select codec preset");
		return -EINVAL;
	}

	service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0);
	caps = g_slist_append(NULL, service);

	codec = g_malloc0(sizeof(*codec) + preset->len);
	codec->media_type = AVDTP_MEDIA_TYPE_AUDIO;
	codec->media_codec_type = endpoint->codec;
	memcpy(codec->data, preset->data, preset->len);

	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec,
						sizeof(*codec) + preset->len);
	caps = g_slist_append(caps, service);

	g_free(codec);

	err = avdtp_set_configuration(dev->session, rsep, endpoint->sep, caps,
								&stream);
	g_slist_free_full(caps, g_free);
	if (err < 0) {
		error("avdtp_set_configuration: %s", strerror(-err));
		return err;
	}

	setup_add(dev, endpoint, preset, stream);

	return 0;
}

static void discover_cb(struct avdtp *session, GSList *seps,
				struct avdtp_error *err, void *user_data)
{
	struct a2dp_device *dev = user_data;
	struct a2dp_endpoint *endpoint = NULL;
	struct avdtp_remote_sep *rsep = NULL;
	GSList *l;

	for (l = endpoints; l; l = g_slist_next(l)) {
		endpoint = l->data;

		rsep = avdtp_find_remote_sep(session, endpoint->sep);
		if (rsep)
			break;
	}

	if (!rsep) {
		error("Unable to find matching endpoint");
		goto failed;
	}

	if (select_configuration(dev, endpoint, rsep) < 0)
		goto failed;

	return;

failed:
	avdtp_shutdown(session);
}

static gboolean idle_timeout(gpointer user_data)
{
	struct a2dp_device *dev = user_data;
	int err;

	dev->idle_id = 0;

	err = avdtp_discover(dev->session, discover_cb, dev);
	if (err == 0)
		return FALSE;

	error("avdtp_discover: %s", strerror(-err));
	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);

	return FALSE;
}

static void signaling_connect_cb(GIOChannel *chan, GError *err,
							gpointer user_data)
{
	struct a2dp_device *dev = user_data;
	uint16_t imtu, omtu;
	GError *gerr = NULL;
	int fd;

	if (err) {
		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
		error("%s", err->message);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_IMTU, &imtu,
			BT_IO_OPT_OMTU, &omtu,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		goto failed;
	}

	fd = g_io_channel_unix_get_fd(chan);

	/* FIXME: Add proper version */
	dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
	if (!dev->session)
		goto failed;

	avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);

	if (dev->io) {
		g_io_channel_unref(dev->io);
		dev->io = NULL;
	}

	/* Proceed to stream setup if initiator */
	if (dev->state == HAL_A2DP_STATE_CONNECTING) {
		int perr;

		perr = avdtp_discover(dev->session, discover_cb, dev);
		if (perr < 0) {
			error("avdtp_discover: %s", strerror(-perr));
			goto failed;
		}
		bt_avrcp_connect(&dev->dst);
	} else /* Init idle timeout to discover */
		dev->idle_id = g_timeout_add_seconds(IDLE_TIMEOUT, idle_timeout,
									dev);

	return;

failed:
	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
}

static void bt_a2dp_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_a2dp_connect *cmd = buf;
	struct a2dp_device *dev;
	uint8_t status;
	char addr[18];
	bdaddr_t dst;
	GSList *l;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = a2dp_device_new(&dst);
	if (!a2dp_device_connect(dev, signaling_connect_cb)) {
		a2dp_device_remove(dev);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	ba2str(&dev->dst, addr);
	DBG("connecting to %s", addr);

	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status);
}

static void bt_a2dp_disconnect(const void *buf, uint16_t len)
{
	const struct hal_cmd_a2dp_connect *cmd = buf;
	uint8_t status;
	struct a2dp_device *dev;
	GSList *l;
	bdaddr_t dst;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;
	status = HAL_STATUS_SUCCESS;

	if (dev->io) {
		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
		goto failed;
	}

	/* Wait AVDTP session to shutdown */
	avdtp_shutdown(dev->session);
	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING);

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
									status);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_A2DP_CONNECT */
	{ bt_a2dp_connect, false, sizeof(struct hal_cmd_a2dp_connect) },
	/* HAL_OP_A2DP_DISCONNECT */
	{ bt_a2dp_disconnect, false, sizeof(struct hal_cmd_a2dp_disconnect) },
};

static struct a2dp_setup *find_setup_by_device(struct a2dp_device *dev)
{
	GSList *l;

	for (l = setups; l; l = g_slist_next(l)) {
		struct a2dp_setup *setup = l->data;

		if (setup->dev == dev)
			return setup;
	}

	return NULL;
}

static void transport_connect_cb(GIOChannel *chan, GError *err,
							gpointer user_data)
{
	struct a2dp_device *dev = user_data;
	struct a2dp_setup *setup;
	uint16_t imtu, omtu;
	GError *gerr = NULL;
	int fd;

	if (err) {
		error("%s", err->message);
		return;
	}

	setup = find_setup_by_device(dev);
	if (!setup) {
		error("Unable to find stream setup");
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_IMTU, &imtu,
			BT_IO_OPT_OMTU, &omtu,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		return;
	}

	fd = g_io_channel_unix_get_fd(chan);

	if (!avdtp_stream_set_transport(setup->stream, fd, imtu, omtu)) {
		error("avdtp_stream_set_transport: failed");
		return;
	}

	g_io_channel_set_close_on_unref(chan, FALSE);

	if (dev->io) {
		g_io_channel_unref(dev->io);
		dev->io = NULL;
	}

	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
}

static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct a2dp_device *dev;
	bdaddr_t src, dst;
	char address[18];
	GError *gerr = NULL;
	GSList *l;

	if (err) {
		error("%s", err->message);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		g_io_channel_shutdown(chan, TRUE, NULL);
		return;
	}

	ba2str(&dst, address);
	DBG("Incoming connection from %s", address);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (l) {
		transport_connect_cb(chan, err, l->data);
		return;
	}

	dev = a2dp_device_new(&dst);
	signaling_connect_cb(chan, err, dev);
}

static sdp_record_t *a2dp_record(void)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
	sdp_profile_desc_t profile[1];
	sdp_list_t *aproto, *proto[2];
	sdp_record_t *record;
	sdp_data_t *psm, *version, *features;
	uint16_t lp = AVDTP_UUID;
	uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(NULL, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &a2dp_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
	profile[0].version = a2dp_ver;
	pfseq = sdp_list_append(NULL, &profile[0]);
	sdp_set_profile_descs(record, pfseq);

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
	psm = sdp_data_alloc(SDP_UINT16, &lp);
	proto[0] = sdp_list_append(proto[0], psm);
	apseq = sdp_list_append(NULL, proto[0]);

	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
	proto[1] = sdp_list_append(NULL, &avdtp_uuid);
	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
	proto[1] = sdp_list_append(proto[1], version);
	apseq = sdp_list_append(apseq, proto[1]);

	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);

	features = sdp_data_alloc(SDP_UINT16, &feat);
	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);

	sdp_set_info_attr(record, "Audio Source", NULL, NULL);

	sdp_data_free(psm);
	sdp_data_free(version);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(apseq, NULL);
	sdp_list_free(pfseq, NULL);
	sdp_list_free(aproto, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(svclass_id, NULL);

	return record;
}

static gboolean sep_getcap_ind(struct avdtp *session,
					struct avdtp_local_sep *sep,
					GSList **caps, uint8_t *err,
					void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_preset *cap = endpoint->caps;
	struct avdtp_service_capability *service;
	struct avdtp_media_codec_capability *codec;

	*caps = NULL;

	service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0);
	*caps = g_slist_append(*caps, service);

	codec = g_malloc0(sizeof(*codec) + cap->len);
	codec->media_type = AVDTP_MEDIA_TYPE_AUDIO;
	codec->media_codec_type = endpoint->codec;
	memcpy(codec->data, cap->data, cap->len);

	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec,
						sizeof(*codec) + cap->len);
	*caps = g_slist_append(*caps, service);
	g_free(codec);

	return TRUE;
}

static int check_config(struct a2dp_endpoint *endpoint,
						struct a2dp_preset *config)
{
	GSList *l;
	struct a2dp_preset *caps;

	for (l = endpoint->presets; l; l = g_slist_next(l)) {
		struct a2dp_preset *preset = l->data;

		if (preset->len != config->len)
			continue;

		if (memcmp(preset->data, config->data, preset->len) == 0)
			return 0;
	}

	caps = endpoint->caps;

	/* Codec specific */
	switch (endpoint->codec) {
	case A2DP_CODEC_SBC:
		return sbc_check_config(caps->data, caps->len, config->data,
								config->len);
	default:
		return -EINVAL;
	}
}

static struct a2dp_device *find_device_by_session(struct avdtp *session)
{
	GSList *l;

	for (l = devices; l; l = g_slist_next(l)) {
		struct a2dp_device *dev = l->data;

		if (dev->session == session)
			return dev;
	}

	return NULL;
}

static struct a2dp_setup *find_setup(uint8_t id)
{
	GSList *l;

	for (l = setups; l; l = g_slist_next(l)) {
		struct a2dp_setup *setup = l->data;

		if (setup->endpoint->id == id)
			return setup;
	}

	return NULL;
}

static void setup_remove_by_id(uint8_t id)
{
	struct a2dp_setup *setup;

	setup = find_setup(id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u", id);
		return;
	}

	setup_remove(setup);
}

static gboolean sep_setconf_ind(struct avdtp *session,
						struct avdtp_local_sep *sep,
						struct avdtp_stream *stream,
						GSList *caps,
						avdtp_set_configuration_cb cb,
						void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_device *dev;
	struct a2dp_preset *preset = NULL;

	DBG("");

	dev = find_device_by_session(session);
	if (!dev) {
		error("Unable to find device for session %p", session);
		return FALSE;
	}

	for (; caps != NULL; caps = g_slist_next(caps)) {
		struct avdtp_service_capability *cap = caps->data;
		struct avdtp_media_codec_capability *codec;

		if (cap->category == AVDTP_DELAY_REPORTING)
			return FALSE;

		if (cap->category != AVDTP_MEDIA_CODEC)
			continue;

		codec = (struct avdtp_media_codec_capability *) cap->data;

		if (codec->media_codec_type != endpoint->codec)
			return FALSE;

		preset = g_new0(struct a2dp_preset, 1);
		preset->len = cap->length - sizeof(*codec);
		preset->data = g_memdup(codec->data, preset->len);

		if (check_config(endpoint, preset) < 0) {
			preset_free(preset);
			return FALSE;
		}
	}

	if (!preset)
		return FALSE;

	setup_add(dev, endpoint, preset, stream);

	cb(session, stream, NULL);

	return TRUE;
}

static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
				struct avdtp_stream *stream, uint8_t *err,
				void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u",
								endpoint->id);
		*err = AVDTP_SEP_NOT_IN_USE;
		return FALSE;
	}

	return TRUE;
}

static gboolean sep_close_ind(struct avdtp *session,
						struct avdtp_local_sep *sep,
						struct avdtp_stream *stream,
						uint8_t *err,
						void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u",
								endpoint->id);
		*err = AVDTP_SEP_NOT_IN_USE;
		return FALSE;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_STOPPED);

	setup_remove(setup);

	return TRUE;
}

static gboolean sep_start_ind(struct avdtp *session,
						struct avdtp_local_sep *sep,
						struct avdtp_stream *stream,
						uint8_t *err,
						void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u",
								endpoint->id);
		*err = AVDTP_SEP_NOT_IN_USE;
		return FALSE;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_STARTED);

	return TRUE;
}

static gboolean sep_suspend_ind(struct avdtp *session,
						struct avdtp_local_sep *sep,
						struct avdtp_stream *stream,
						uint8_t *err,
						void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u",
								endpoint->id);
		*err = AVDTP_SEP_NOT_IN_USE;
		return FALSE;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_SUSPEND);

	return TRUE;
}

static struct avdtp_sep_ind sep_ind = {
	.get_capability		= sep_getcap_ind,
	.set_configuration	= sep_setconf_ind,
	.open			= sep_open_ind,
	.close			= sep_close_ind,
	.start			= sep_start_ind,
	.suspend		= sep_suspend_ind,
};

static void sep_setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
				struct avdtp_stream *stream,
				struct avdtp_error *err, void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;
	int ret;

	DBG("");

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for endpoint %u",
								endpoint->id);
		return;
	}

	if (err)
		goto failed;

	ret = avdtp_open(session, stream);
	if (ret < 0) {
		error("avdtp_open: %s", strerror(-ret));
		goto failed;
	}

	return;

failed:
	setup_remove(setup);
}

static void sep_open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_device *dev;

	DBG("");

	if (err)
		goto failed;

	dev = find_device_by_session(session);
	if (!dev) {
		error("Unable to find device for session");
		goto failed;
	}

	a2dp_device_connect(dev, transport_connect_cb);

	return;

failed:
	setup_remove_by_id(endpoint->id);
}

static void sep_start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	if (err) {
		setup_remove_by_id(endpoint->id);
		return;
	}

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for %u endpoint",
								endpoint->id);
		return;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_STARTED);
}

static void sep_suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	if (err) {
		setup_remove_by_id(endpoint->id);
		return;
	}

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for %u endpoint",
								endpoint->id);
		return;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_STOPPED);
}

static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;
	struct a2dp_setup *setup;

	DBG("");

	if (err)
		return;

	setup = find_setup(endpoint->id);
	if (!setup) {
		error("Unable to find stream setup for %u endpoint",
								endpoint->id);
		return;
	}

	bt_audio_notify_state(setup, HAL_AUDIO_STOPPED);

	setup_remove(setup);
}

static void sep_abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	struct a2dp_endpoint *endpoint = user_data;

	DBG("");

	if (err)
		return;

	setup_remove_by_id(endpoint->id);
}

static struct avdtp_sep_cfm sep_cfm = {
	.set_configuration	= sep_setconf_cfm,
	.open			= sep_open_cfm,
	.start			= sep_start_cfm,
	.suspend		= sep_suspend_cfm,
	.close			= sep_close_cfm,
	.abort			= sep_abort_cfm,
};

static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
							GSList *presets)
{
	struct a2dp_endpoint *endpoint;

	/* FIXME: Add proper check for uuid */

	endpoint = g_new0(struct a2dp_endpoint, 1);
	endpoint->id = g_slist_length(endpoints) + 1;
	endpoint->codec = codec;
	endpoint->sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
						AVDTP_MEDIA_TYPE_AUDIO,
						codec, FALSE, &sep_ind,
						&sep_cfm, endpoint);
	endpoint->caps = presets->data;
	endpoint->presets = g_slist_copy(g_slist_nth(presets, 1));

	endpoints = g_slist_append(endpoints, endpoint);

	return endpoint->id;
}

static GSList *parse_presets(const struct audio_preset *p, uint8_t count,
								uint16_t len)
{
	GSList *l = NULL;
	uint8_t i;

	for (i = 0; count > i; i++) {
		const uint8_t *ptr = (const uint8_t *) p;
		struct a2dp_preset *preset;

		if (len < sizeof(struct audio_preset)) {
			DBG("Invalid preset index %u", i);
			g_slist_free_full(l, preset_free);
			return NULL;
		}

		len -= sizeof(struct audio_preset);
		if (len == 0 || len < p->len) {
			DBG("Invalid preset size of %u for index %u", len, i);
			g_slist_free_full(l, preset_free);
			return NULL;
		}

		preset = g_new0(struct a2dp_preset, 1);
		preset->len = p->len;
		preset->data = g_memdup(p->data, preset->len);
		l = g_slist_append(l, preset);

		len -= preset->len;
		ptr += sizeof(*p) + preset->len;
		p = (const struct audio_preset *) ptr;
	}

	return l;
}

static void bt_audio_open(const void *buf, uint16_t len)
{
	const struct audio_cmd_open *cmd = buf;
	struct audio_rsp_open rsp;
	GSList *presets;

	DBG("");

	audio_retrying = false;

	if (cmd->presets == 0) {
		error("No audio presets found");
		goto failed;
	}

	presets = parse_presets(cmd->preset, cmd->presets, len - sizeof(*cmd));
	if (!presets) {
		error("No audio presets found");
		goto failed;
	}

	rsp.id = register_endpoint(cmd->uuid, cmd->codec, presets);
	if (rsp.id == 0) {
		g_slist_free_full(presets, preset_free);
		error("Unable to register endpoint");
		goto failed;
	}

	g_slist_free(presets);

	ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN,
							sizeof(rsp), &rsp, -1);

	return;

failed:
	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN,
							AUDIO_STATUS_FAILED);
}

static struct a2dp_endpoint *find_endpoint(uint8_t id)
{
	GSList *l;

	for (l = endpoints; l; l = g_slist_next(l)) {
		struct a2dp_endpoint *endpoint = l->data;

		if (endpoint->id == id)
			return endpoint;
	}

	return NULL;
}

static void bt_audio_close(const void *buf, uint16_t len)
{
	const struct audio_cmd_close *cmd = buf;
	struct a2dp_endpoint *endpoint;

	DBG("");

	endpoint = find_endpoint(cmd->id);
	if (!endpoint) {
		error("Unable to find endpoint %u", cmd->id);
		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE,
							AUDIO_STATUS_FAILED);
		return;
	}

	endpoints = g_slist_remove(endpoints, endpoint);
	unregister_endpoint(endpoint);

	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE,
							AUDIO_STATUS_SUCCESS);
}

static void bt_stream_open(const void *buf, uint16_t len)
{
	const struct audio_cmd_open_stream *cmd = buf;
	struct audio_rsp_open_stream *rsp;
	struct a2dp_setup *setup;
	int fd;
	uint16_t omtu;

	DBG("");

	setup = find_setup(cmd->id);
	if (!setup) {
		error("Unable to find stream for endpoint %u", cmd->id);
		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
							AUDIO_STATUS_FAILED);
		return;
	}

	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu,
								NULL)) {
		error("avdtp_stream_get_transport: failed");
		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
							AUDIO_STATUS_FAILED);
		return;
	}

	len = sizeof(struct audio_rsp_open_stream) +
			sizeof(struct audio_preset) + setup->preset->len;
	rsp = g_malloc0(len);
	rsp->mtu = omtu;
	rsp->preset->len = setup->preset->len;
	memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);

	ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
								len, rsp, fd);

	g_free(rsp);
}

static void bt_stream_close(const void *buf, uint16_t len)
{
	const struct audio_cmd_close_stream *cmd = buf;
	struct a2dp_setup *setup;
	int err;

	DBG("");

	setup = find_setup(cmd->id);
	if (!setup) {
		error("Unable to find stream for endpoint %u", cmd->id);
		goto failed;
	}

	err = avdtp_close(setup->dev->session, setup->stream, FALSE);
	if (err < 0) {
		error("avdtp_close: %s", strerror(-err));
		goto failed;
	}

	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM,
							AUDIO_STATUS_SUCCESS);

	return;

failed:
	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM,
							AUDIO_STATUS_FAILED);
}

static void bt_stream_resume(const void *buf, uint16_t len)
{
	const struct audio_cmd_resume_stream *cmd = buf;
	struct a2dp_setup *setup;
	int err;

	DBG("");

	setup = find_setup(cmd->id);
	if (!setup) {
		error("Unable to find stream for endpoint %u", cmd->id);
		goto failed;
	}

	if (setup->state != HAL_AUDIO_STARTED) {
		err = avdtp_start(setup->dev->session, setup->stream);
		if (err < 0) {
			error("avdtp_start: %s", strerror(-err));
			goto failed;
		}
	}

	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM,
							AUDIO_STATUS_SUCCESS);

	return;

failed:
	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM,
							AUDIO_STATUS_FAILED);
}

static void bt_stream_suspend(const void *buf, uint16_t len)
{
	const struct audio_cmd_suspend_stream *cmd = buf;
	struct a2dp_setup *setup;
	int err;

	DBG("");

	setup = find_setup(cmd->id);
	if (!setup) {
		error("Unable to find stream for endpoint %u", cmd->id);
		goto failed;
	}

	err = avdtp_suspend(setup->dev->session, setup->stream);
	if (err < 0) {
		error("avdtp_suspend: %s", strerror(-err));
		goto failed;
	}

	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM,
							AUDIO_STATUS_SUCCESS);

	return;

failed:
	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM,
							AUDIO_STATUS_FAILED);
}

static const struct ipc_handler audio_handlers[] = {
	/* AUDIO_OP_OPEN */
	{ bt_audio_open, true, sizeof(struct audio_cmd_open) },
	/* AUDIO_OP_CLOSE */
	{ bt_audio_close, false, sizeof(struct audio_cmd_close) },
	/* AUDIO_OP_OPEN_STREAM */
	{ bt_stream_open, false, sizeof(struct audio_cmd_open_stream) },
	/* AUDIO_OP_CLOSE_STREAM */
	{ bt_stream_close, false, sizeof(struct audio_cmd_close_stream) },
	/* AUDIO_OP_RESUME_STREAM */
	{ bt_stream_resume, false, sizeof(struct audio_cmd_resume_stream) },
	/* AUDIO_OP_SUSPEND_STREAM */
	{ bt_stream_suspend, false, sizeof(struct audio_cmd_suspend_stream) },
};

static void bt_audio_unregister(void)
{
	DBG("");

	if (audio_retry_id > 0)
		g_source_remove(audio_retry_id);

	g_slist_free_full(endpoints, unregister_endpoint);
	endpoints = NULL;

	g_slist_free_full(setups, setup_free);
	setups = NULL;

	ipc_cleanup(audio_ipc);
	audio_ipc = NULL;
}

static bool bt_audio_register(ipc_disconnect_cb disconnect)
{
	DBG("");

	audio_ipc = ipc_init(BLUEZ_AUDIO_SK_PATH, sizeof(BLUEZ_AUDIO_SK_PATH),
				AUDIO_SERVICE_ID_MAX, false, disconnect, NULL);
	if (!audio_ipc)
		return false;

	ipc_register(audio_ipc, AUDIO_SERVICE_ID, audio_handlers,
						G_N_ELEMENTS(audio_handlers));

	return true;
}

static gboolean audio_retry_register(void *data)
{
	ipc_disconnect_cb cb = data;

	audio_retry_id = 0;
	audio_retrying = true;

	bt_audio_register(cb);

	return FALSE;
}

static void audio_disconnected(void *data)
{
	GSList *l;
	bool restart;

	DBG("");

	if (audio_retrying)
		goto retry;

	restart = endpoints != NULL ? true : false;

	bt_audio_unregister();

	for (l = devices; l; l = g_slist_next(l)) {
		struct a2dp_device *dev = l->data;

		avdtp_shutdown(dev->session);
	}

	if (!restart)
		return;

retry:
	audio_retry_id = g_timeout_add_seconds(AUDIO_RETRY_TIMEOUT,
						audio_retry_register,
						audio_disconnected);
}

bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;
	sdp_record_t *rec;

	DBG("");

	bacpy(&adapter_addr, addr);

	server = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_PSM, L2CAP_PSM_AVDTP,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_INVALID);
	if (!server) {
		error("Failed to listen on AVDTP channel: %s", err->message);
		g_error_free(err);
		return false;
	}

	rec = a2dp_record();
	if (!rec) {
		error("Failed to allocate A2DP record");
		goto fail;
	}

	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
		error("Failed to register A2DP record");
		sdp_record_free(rec);
		goto fail;
	}
	record_id = rec->handle;

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	if (bt_audio_register(audio_disconnected))
		return true;

fail:
	g_io_channel_shutdown(server, TRUE, NULL);
	g_io_channel_unref(server);
	server = NULL;
	return false;
}

void bt_a2dp_unregister(void)
{
	DBG("");

	g_slist_free_full(setups, setup_free);
	setups = NULL;

	g_slist_free_full(endpoints, unregister_endpoint);
	endpoints = NULL;

	g_slist_free_full(devices, a2dp_device_free);
	devices = NULL;

	ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP);
	hal_ipc = NULL;

	bt_adapter_remove_record(record_id);
	record_id = 0;

	if (server) {
		g_io_channel_shutdown(server, TRUE, NULL);
		g_io_channel_unref(server);
		server = NULL;
	}

	if (audio_ipc) {
		ipc_unregister(audio_ipc, AUDIO_SERVICE_ID);
		ipc_cleanup(audio_ipc);
		audio_ipc = NULL;
	}
}
