/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2014 Intel Corporation
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; 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 <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include <glib.h>

#include "src/shared/util.h"
#include "btio/btio.h"
#include "avdtp.h"

static GMainLoop *mainloop = NULL;
static int dev_role = AVDTP_SEP_TYPE_SOURCE;
static bool preconf = false;
static struct avdtp *avdtp = NULL;
struct avdtp_stream *avdtp_stream = NULL;
struct avdtp_local_sep *local_sep = NULL;
struct avdtp_remote_sep *remote_sep = NULL;
static GIOChannel *io = NULL;
static bool reject = false;
static bdaddr_t src;
static bdaddr_t dst;
static uint16_t version = 0x0103;
static guint media_player = 0;
static guint media_recorder = 0;
static guint idle_id = 0;

static bool fragment = false;

static enum {
	CMD_GET_CONF,
	CMD_OPEN,
	CMD_START,
	CMD_SUSPEND,
	CMD_CLOSE,
	CMD_ABORT,
	CMD_DELAY,
	CMD_NONE,
} command = CMD_NONE;

static const char sbc_codec[] = {0x00, 0x00, 0x11, 0x15, 0x02, 0x40};
static const char sbc_media_frame[] = {
	0x00, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x01, 0x9c, 0xfd, 0x40, 0xbd, 0xde, 0xa9, 0x75, 0x43, 0x20, 0x87, 0x64,
	0x44, 0x32, 0x7f, 0xbe, 0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x7f, 0xbe,
	0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x7f, 0xbe, 0xf7, 0x76, 0xfe, 0xf7,
	0xbb, 0xbb, 0x80, 0x3e, 0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x83, 0x41,
	0x07, 0x77, 0x09, 0x07, 0x43, 0xb3, 0x81, 0xbc, 0xf8, 0x77, 0x02, 0xe5,
	0xa4, 0x3a, 0xa0, 0xcb, 0x38, 0xbb, 0x57, 0x90, 0xd9, 0x08, 0x9c, 0x1d,
	0x86, 0x59, 0x01, 0x0c, 0x21, 0x44, 0x68, 0x35, 0xa8, 0x57, 0x97, 0x0e,
	0x9b, 0xbb, 0x62, 0xc4, 0xca, 0x57, 0x04, 0xa1, 0xca, 0x3b, 0xa3, 0x48,
	0xd2, 0x66, 0x11, 0x33, 0x6a, 0x3b, 0xb4, 0xbb, 0x08, 0x77, 0x17, 0x03,
	0xb4, 0x3b, 0x79, 0x3b, 0x46, 0x97, 0x0e, 0xf7, 0x3d, 0xbb, 0x3d, 0x49,
	0x25, 0x86, 0x88, 0xb4, 0xad, 0x3b, 0x62, 0xbb, 0xa4, 0x47, 0x29, 0x99,
	0x3b, 0x3b, 0xaf, 0xc6, 0xd4, 0x37, 0x68, 0x94, 0x0a, 0xbb
	};

static void parse_command(const char *cmd)
{
	if (!strncmp(cmd, "getconf", sizeof("getconf"))) {
		command = CMD_GET_CONF;
	} else if (!strncmp(cmd, "open", sizeof("open"))) {
		command = CMD_OPEN;
	} else if (!strncmp(cmd, "start", sizeof("start"))) {
		command = CMD_START;
	} else if (!strncmp(cmd, "suspend", sizeof("suspend"))) {
		command = CMD_SUSPEND;
	} else if (!strncmp(cmd, "close", sizeof("close"))) {
		command = CMD_CLOSE;
	} else if (!strncmp(cmd, "abort", sizeof("abort"))) {
		command = CMD_ABORT;
	} else if (!strncmp(cmd, "delay", sizeof("delay"))) {
		command = CMD_DELAY;
	} else {
		printf("Unknown command '%s'\n", cmd);
		printf("(getconf open start suspend close abort delay)\n");
		exit(1);
	}
}

static void send_command(void)
{
	avdtp_state_t state = avdtp_sep_get_state(local_sep);

	switch (command) {
	case CMD_GET_CONF:
		avdtp_get_configuration(avdtp, avdtp_stream);
		break;
	case CMD_OPEN:
		if (state == AVDTP_STATE_CONFIGURED)
			avdtp_open(avdtp, avdtp_stream);
		break;
	case CMD_START:
		if (state == AVDTP_STATE_OPEN)
			avdtp_start(avdtp, avdtp_stream);
		break;
	case CMD_SUSPEND:
		if (state == AVDTP_STATE_STREAMING)
			avdtp_suspend(avdtp , avdtp_stream);
		break;
	case CMD_CLOSE:
		if (state == AVDTP_STATE_STREAMING)
			avdtp_close(avdtp, avdtp_stream, FALSE);
		break;
	case CMD_ABORT:
		avdtp_abort(avdtp , avdtp_stream);
		break;
	case CMD_DELAY:
		avdtp_delay_report(avdtp , avdtp_stream , 250);
		break;
	case CMD_NONE:
	default:
		break;
	}
}

static gboolean media_writer(gpointer user_data)
{
	uint16_t omtu;
	int fd;
	int to_write;

	if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL))
		return TRUE;

	if (omtu < sizeof(sbc_media_frame))
		to_write = omtu;
	else
		to_write = sizeof(sbc_media_frame);

	if (write(fd, sbc_media_frame, to_write) < 0)
		return TRUE;

	send_command();

	return TRUE;
}

static bool start_media_player(void)
{
	int fd;
	uint16_t omtu;

	printf("Media streaming started\n");

	if (media_player || !avdtp_stream)
		return false;

	if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL))
		return false;

	media_player = g_timeout_add(200, media_writer, NULL);
	if (!media_player)
		return false;

	return true;
}

static void stop_media_player(void)
{
	if (!media_player)
		return;

	printf("Media streaming stopped\n");

	g_source_remove(media_player);
	media_player = 0;
}

#if __BYTE_ORDER == __LITTLE_ENDIAN

struct rtp_header {
	unsigned cc:4;
	unsigned x:1;
	unsigned p:1;
	unsigned v:2;

	unsigned pt:7;
	unsigned m:1;

	uint16_t sequence_number;
	uint32_t timestamp;
	uint32_t ssrc;
	uint32_t csrc[0];
} __attribute__ ((packed));

#elif __BYTE_ORDER == __BIG_ENDIAN

struct rtp_header {
	unsigned v:2;
	unsigned p:1;
	unsigned x:1;
	unsigned cc:4;

	unsigned m:1;
	unsigned pt:7;

	uint16_t sequence_number;
	uint32_t timestamp;
	uint32_t ssrc;
	uint32_t csrc[0];
} __attribute__ ((packed));

#else
#error "Unknown byte order"
#endif

static gboolean media_reader(GIOChannel *source, GIOCondition condition,
								gpointer data)
{
	char buf[UINT16_MAX];
	struct rtp_header *rtp = (void *) buf;
	static bool decode = false;
	uint16_t imtu;
	int fd, ret;

	if (!avdtp_stream_get_transport(avdtp_stream, &fd, &imtu, NULL, NULL))
		return TRUE;

	ret = read(fd, buf, imtu);
	if (ret < 0) {
		printf("Reading failed (%s)\n", strerror(errno));
		return TRUE;
	}

	if (ret < (int) sizeof(*rtp)) {
		printf("Not enough media data received (%u bytes)", ret);
		return TRUE;
	}

	if (!decode) {
		printf("V=%u P=%u X=%u CC=%u M=%u PT=%u SeqNr=%d\n",
			rtp->v, rtp->p, rtp->x, rtp->cc, rtp->m, rtp->pt,
			be16_to_cpu(rtp->sequence_number));
		decode = true;
	}

	send_command();

	return TRUE;
}

static bool start_media_recorder(void)
{
	int fd;
	uint16_t omtu;
	GIOChannel *chan;

	printf("Media recording started\n");

	if (media_recorder || !avdtp_stream)
		return false;

	if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL))
		return false;

	chan = g_io_channel_unix_new(fd);

	media_recorder = g_io_add_watch(chan, G_IO_IN, media_reader, NULL);
	g_io_channel_unref(chan);

	if (!media_recorder)
		return false;

	return true;
}

static void stop_media_recorder(void)
{
	if (!media_recorder)
		return;

	printf("Media recording stopped\n");

	g_source_remove(media_recorder);
	media_recorder = 0;
}

static void set_configuration_cfm(struct avdtp *session,
					struct avdtp_local_sep *lsep,
					struct avdtp_stream *stream,
					struct avdtp_error *err,
					void *user_data)
{
	printf("%s\n", __func__);

	if (preconf)
		avdtp_open(avdtp, avdtp_stream);
}

static void get_configuration_cfm(struct avdtp *session,
					struct avdtp_local_sep *lsep,
					struct avdtp_stream *stream,
					struct avdtp_error *err,
					void *user_data)
	{
	printf("%s\n", __func__);
}

static void disconnect_cb(void *user_data)
{
	printf("Disconnected\n");

	g_main_loop_quit(mainloop);
}

static void discover_cb(struct avdtp *session, GSList *seps,
				struct avdtp_error *err, void *user_data)
{
	struct avdtp_service_capability *service;
	GSList *caps = NULL;
	int ret;

	remote_sep = avdtp_find_remote_sep(avdtp, local_sep);
	if (!remote_sep) {
		printf("Unable to find matching endpoint\n");
		avdtp_shutdown(session);
		return;
	}

	printf("Matching endpoint found\n");

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

	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, sbc_codec,
							sizeof(sbc_codec));
	caps = g_slist_append(caps, service);

	ret = avdtp_set_configuration(avdtp, remote_sep, local_sep, caps,
								&avdtp_stream);

	g_slist_free_full(caps, g_free);

	if (ret < 0) {
		printf("Failed to set configuration (%s)\n", strerror(-ret));
		avdtp_shutdown(session);
	}
}

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

	if (err) {
		printf("%s\n", err->message);
		g_main_loop_quit(mainloop);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_IMTU, &imtu,
			BT_IO_OPT_OMTU, &omtu,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_INVALID);
	if (gerr) {
		printf("%s\n", gerr->message);
		g_main_loop_quit(mainloop);
		return;
	}

	printf("Connected (imtu=%d omtu=%d)\n", imtu, omtu);

	fd = g_io_channel_unix_get_fd(chan);

	if (avdtp && avdtp_stream) {
		if (!avdtp_stream_set_transport(avdtp_stream, fd, imtu, omtu)) {
			printf("avdtp_stream_set_transport: failed\n");
			g_main_loop_quit(mainloop);
		}

		g_io_channel_set_close_on_unref(chan, FALSE);

		send_command();

		return;
	}

	avdtp = avdtp_new(fd, imtu, omtu, version);
	if (!avdtp) {
		printf("Failed to create avdtp instance\n");
		g_main_loop_quit(mainloop);
		return;
	}

	avdtp_add_disconnect_cb(avdtp, disconnect_cb, NULL);

	if (preconf) {
		int ret;

		ret = avdtp_discover(avdtp, discover_cb, NULL);
		if (ret < 0) {
			printf("avdtp_discover failed: %s", strerror(-ret));
			g_main_loop_quit(mainloop);
		}
	}
}

static GIOChannel *do_connect(GError **err)
{
	if (fragment)
		return bt_io_connect(connect_cb, NULL, NULL, err,
					BT_IO_OPT_SOURCE_BDADDR, &src,
					BT_IO_OPT_DEST_BDADDR, &dst,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_PSM, AVDTP_PSM,
					BT_IO_OPT_MTU, 48,
					BT_IO_OPT_INVALID);

	return bt_io_connect(connect_cb, NULL, NULL, err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_DEST_BDADDR, &dst,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_PSM, AVDTP_PSM,
				BT_IO_OPT_INVALID);
}

static void open_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	GError *gerr = NULL;

	printf("%s\n", __func__);

	do_connect(&gerr);
	if (gerr) {
		printf("connect failed: %s\n", gerr->message);
		g_error_free(gerr);
		g_main_loop_quit(mainloop);
	}
}

static void start_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
			struct avdtp_stream *stream, struct avdtp_error *err,
			void *user_data)
{
	printf("%s\n", __func__);

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		start_media_player();
	else
		start_media_recorder();
}

static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
			struct avdtp_stream *stream,
			struct avdtp_error *err, void *user_data)
{
	printf("%s\n", __func__);

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();
}

static void close_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
			struct avdtp_stream *stream,
			struct avdtp_error *err, void *user_data)
{
	printf("%s\n", __func__);

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();

	avdtp_stream = NULL;
}

static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
			struct avdtp_stream *stream,
			struct avdtp_error *err, void *user_data)
{
	printf("%s\n", __func__);

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();

	avdtp_stream = NULL;
}

static void reconfigure_cfm(struct avdtp *session,
				struct avdtp_local_sep *lsep,
				struct avdtp_stream *stream,
				struct avdtp_error *err, void *user_data)
{
	printf("%s\n", __func__);
}

static void delay_report_cfm(struct avdtp *session,
				struct avdtp_local_sep *lsep,
				struct avdtp_stream *stream,
				struct avdtp_error *err, void *user_data)
{
	printf("%s\n", __func__);
}

static struct avdtp_sep_cfm sep_cfm = {
	.set_configuration	= set_configuration_cfm,
	.get_configuration	= get_configuration_cfm,
	.open			= open_cfm,
	.start			= start_cfm,
	.suspend		= suspend_cfm,
	.close			= close_cfm,
	.abort			= abort_cfm,
	.reconfigure		= reconfigure_cfm,
	.delay_report		= delay_report_cfm,
};

static gboolean get_capability_ind(struct avdtp *session,
					struct avdtp_local_sep *sep,
					GSList **caps, uint8_t *err,
					void *user_data)
{
	struct avdtp_service_capability *service;
	int i;

	printf("%s\n", __func__);

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

	if (reject)
		return FALSE;

	*caps = NULL;

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

	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, sbc_codec,
						sizeof(sbc_codec));
	*caps = g_slist_append(*caps, service);

	if (fragment)
		for (i = 0; i < 10; i++) {
			service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC,
							sbc_codec,
							sizeof(sbc_codec));
			*caps = g_slist_append(*caps, service);
		}

	return TRUE;
}

static gboolean set_configuration_ind(struct avdtp *session,
					struct avdtp_local_sep *lsep,
					struct avdtp_stream *stream,
					GSList *caps,
					avdtp_set_configuration_cb cb,
					void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

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

	avdtp_stream = stream;

	cb(session, stream, NULL);

	send_command();

	return TRUE;
}

static gboolean get_configuration_ind(struct avdtp *session,
					struct avdtp_local_sep *lsep,
					uint8_t *err, void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	return TRUE;
}

static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *lsep,
				struct avdtp_stream *stream, uint8_t *err,
				void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	send_command();

	return TRUE;
}

static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *lsep,
				struct avdtp_stream *stream, uint8_t *err,
				void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		start_media_player();
	else
		start_media_recorder();

	send_command();

	return TRUE;
}

static gboolean suspend_ind(struct avdtp *session,
				struct avdtp_local_sep *sep,
				struct avdtp_stream *stream, uint8_t *err,
				void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();

	return TRUE;
}

static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
				struct avdtp_stream *stream, uint8_t *err,
				void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();

	avdtp_stream = NULL;

	return TRUE;
}

static void abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
			struct avdtp_stream *stream, uint8_t *err,
			void *user_data)
{
	printf("%s\n", __func__);

	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
		stop_media_player();
	else
		stop_media_recorder();

	avdtp_stream = NULL;
}

static gboolean reconfigure_ind(struct avdtp *session,
				struct avdtp_local_sep *lsep,
				uint8_t *err, void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	return TRUE;
}

static gboolean delayreport_ind(struct avdtp *session,
				struct avdtp_local_sep *lsep,
				uint8_t rseid, uint16_t delay,
				uint8_t *err, void *user_data)
{
	printf("%s\n", __func__);

	if (reject)
		return FALSE;

	return TRUE;
}

static struct avdtp_sep_ind sep_ind = {
	.get_capability		= get_capability_ind,
	.set_configuration	= set_configuration_ind,
	.get_configuration	= get_configuration_ind,
	.open			= open_ind,
	.close			= close_ind,
	.start			= start_ind,
	.suspend		= suspend_ind,
	.abort			= abort_ind,
	.reconfigure		= reconfigure_ind,
	.delayreport		= delayreport_ind,
};

static void usage(void)
{
	printf("avdtptest - AVDTP testing ver %s\n", VERSION);
	printf("Usage:\n"
		"\tavdtptest [options]\n");
	printf("options:\n"
		"\t-d <device_role>   SRC (source) or SINK (sink)\n"
		"\t-i <hcidev>        HCI adapter\n"
		"\t-c <bdaddr>        connect\n"
		"\t-l                 listen\n"
		"\t-r                 reject commands\n"
		"\t-f                 fragment\n"
		"\t-p                 configure stream\n"
		"\t-s <command>       send command\n"
		"\t-v <version>       set version (0x0100, 0x0102, 0x0103\n");
}

static struct option main_options[] = {
	{ "help",		0, 0, 'h' },
	{ "device_role",	1, 0, 'd' },
	{ "adapter",		1, 0, 'i' },
	{ "connect",		1, 0, 'c' },
	{ "listen",		0, 0, 'l' },
	{ "reject",		0, 0, 'r' },
	{ "fragment",		0, 0, 'f' },
	{ "preconf",		0, 0, 'p' },
	{ "send",		1, 0, 's' },
	{ "version",		1, 0, 'v' },
	{ 0, 0, 0, 0 }
};

static GIOChannel *do_listen(GError **err)
{
	if (fragment)
		return bt_io_listen(connect_cb, NULL, NULL, NULL, err,
					BT_IO_OPT_SOURCE_BDADDR, &src,
					BT_IO_OPT_PSM, AVDTP_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_MTU, 48,
					BT_IO_OPT_INVALID);

	return bt_io_listen(connect_cb, NULL, NULL, NULL, err,
					BT_IO_OPT_SOURCE_BDADDR, &src,
					BT_IO_OPT_PSM, AVDTP_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
}

int main(int argc, char *argv[])
{
	GError *err = NULL;
	int opt;

	bacpy(&src, BDADDR_ANY);
	bacpy(&dst, BDADDR_ANY);

	mainloop = g_main_loop_new(NULL, FALSE);
	if (!mainloop) {
		printf("Failed to create main loop\n");

		exit(1);
	}

	while ((opt = getopt_long(argc, argv, "d:hi:s:c:v:lrfp",
						main_options, NULL)) != EOF) {
		switch (opt) {
		case 'i':
			if (!strncmp(optarg, "hci", 3))
				hci_devba(atoi(optarg + 3), &src);
			else
				str2ba(optarg, &src);
			break;
		case 'd':
			if (!strncasecmp(optarg, "SRC", sizeof("SRC"))) {
				dev_role = AVDTP_SEP_TYPE_SOURCE;
			} else if (!strncasecmp(optarg, "SINK",
							sizeof("SINK"))) {
				dev_role = AVDTP_SEP_TYPE_SINK;
			} else {
				usage();
				exit(0);
			}
			break;
		case 'c':
			if (str2ba(optarg, &dst) < 0) {
				usage();
				exit(0);
			}
			break;
		case 'l':
			bacpy(&dst, BDADDR_ANY);
			break;
		case 'r':
			reject = true;
			break;
		case 'f':
			fragment = true;
			break;
		case 'p':
			preconf = true;
			break;
		case 's':
			parse_command(optarg);
			break;
		case 'v':
			version = strtol(optarg, NULL, 0);
			if (version != 0x0100 && version != 0x0102 &&
							version != 0x0103) {
				printf("invalid version\n");
				exit(0);
			}

			break;
		case 'h':
		default:
			usage();
			exit(0);
		}
	}

	local_sep = avdtp_register_sep(dev_role, AVDTP_MEDIA_TYPE_AUDIO,
					0x00, TRUE, &sep_ind, &sep_cfm, NULL);
	if (!local_sep) {
		printf("Failed to register sep\n");
		exit(0);
	}

	if (!bacmp(&dst, BDADDR_ANY)) {
		printf("Listening...\n");
		io = do_listen(&err);
	} else {
		printf("Connecting...\n");
		io = do_connect(&err);
	}

	if (!io) {
		printf("Failed: %s\n", err->message);
		g_error_free(err);
		exit(0);
	}

	g_main_loop_run(mainloop);

	printf("Done\n");

	avdtp_unref(avdtp);
	avdtp = NULL;

	g_main_loop_unref(mainloop);
	mainloop = NULL;

	return 0;
}
