/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2009  Nokia 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 <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/in.h>

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

#define AVDTP_PKT_TYPE_SINGLE		0x00
#define AVDTP_PKT_TYPE_START		0x01
#define AVDTP_PKT_TYPE_CONTINUE		0x02
#define AVDTP_PKT_TYPE_END		0x03

#define AVDTP_MSG_TYPE_COMMAND		0x00
#define AVDTP_MSG_TYPE_GEN_REJECT	0x01
#define AVDTP_MSG_TYPE_ACCEPT		0x02
#define AVDTP_MSG_TYPE_REJECT		0x03

#define AVDTP_DISCOVER			0x01
#define AVDTP_GET_CAPABILITIES		0x02
#define AVDTP_SET_CONFIGURATION		0x03
#define AVDTP_GET_CONFIGURATION		0x04
#define AVDTP_RECONFIGURE		0x05
#define AVDTP_OPEN			0x06
#define AVDTP_START			0x07
#define AVDTP_CLOSE			0x08
#define AVDTP_SUSPEND			0x09
#define AVDTP_ABORT			0x0A

#define AVDTP_SEP_TYPE_SOURCE		0x00
#define AVDTP_SEP_TYPE_SINK		0x01

#define AVDTP_MEDIA_TYPE_AUDIO		0x00
#define AVDTP_MEDIA_TYPE_VIDEO		0x01
#define AVDTP_MEDIA_TYPE_MULTIMEDIA	0x02

#if __BYTE_ORDER == __LITTLE_ENDIAN

struct avdtp_header {
	uint8_t message_type:2;
	uint8_t packet_type:2;
	uint8_t transaction:4;
	uint8_t signal_id:6;
	uint8_t rfa0:2;
} __attribute__ ((packed));

struct seid_info {
	uint8_t rfa0:1;
	uint8_t inuse:1;
	uint8_t seid:6;
	uint8_t rfa2:3;
	uint8_t type:1;
	uint8_t media_type:4;
} __attribute__ ((packed));

struct avdtp_start_header {
	uint8_t message_type:2;
	uint8_t packet_type:2;
	uint8_t transaction:4;
	uint8_t no_of_packets;
	uint8_t signal_id:6;
	uint8_t rfa0:2;
} __attribute__ ((packed));

struct avdtp_continue_header {
	uint8_t message_type:2;
	uint8_t packet_type:2;
	uint8_t transaction:4;
} __attribute__ ((packed));

struct avctp_header {
	uint8_t ipid:1;
	uint8_t cr:1;
	uint8_t packet_type:2;
	uint8_t transaction:4;
	uint16_t pid;
} __attribute__ ((packed));
#define AVCTP_HEADER_LENGTH 3

#elif __BYTE_ORDER == __BIG_ENDIAN

struct avdtp_header {
	uint8_t transaction:4;
	uint8_t packet_type:2;
	uint8_t message_type:2;
	uint8_t rfa0:2;
	uint8_t signal_id:6;
} __attribute__ ((packed));

struct seid_info {
	uint8_t seid:6;
	uint8_t inuse:1;
	uint8_t rfa0:1;
	uint8_t media_type:4;
	uint8_t type:1;
	uint8_t rfa2:3;
} __attribute__ ((packed));

struct avdtp_start_header {
	uint8_t transaction:4;
	uint8_t packet_type:2;
	uint8_t message_type:2;
	uint8_t no_of_packets;
	uint8_t rfa0:2;
	uint8_t signal_id:6;
} __attribute__ ((packed));

struct avdtp_continue_header {
	uint8_t transaction:4;
	uint8_t packet_type:2;
	uint8_t message_type:2;
} __attribute__ ((packed));

struct avctp_header {
	uint8_t transaction:4;
	uint8_t packet_type:2;
	uint8_t cr:1;
	uint8_t ipid:1;
	uint16_t pid;
} __attribute__ ((packed));
#define AVCTP_HEADER_LENGTH 3

#else
#error "Unknown byte order"
#endif

#define AVCTP_COMMAND		0
#define AVCTP_RESPONSE		1

#define AVCTP_PACKET_SINGLE	0

static const unsigned char media_transport[] = {
		0x01,	/* Media transport category */
		0x00,
		0x07,	/* Media codec category */
		0x06,
		0x00,	/* Media type audio */
		0x00,	/* Codec SBC */
		0x22,	/* 44.1 kHz, stereo */
		0x15,	/* 16 blocks, 8 subbands */
		0x02,
		0x33,
};

static int media_sock = -1;

static void dump_avctp_header(struct avctp_header *hdr)
{
	printf("TL %d PT %d CR %d IPID %d PID 0x%04x\n", hdr->transaction,
			hdr->packet_type, hdr->cr, hdr->ipid, ntohs(hdr->pid));
}

static void dump_avdtp_header(struct avdtp_header *hdr)
{
	printf("TL %d PT %d MT %d SI %d\n", hdr->transaction,
			hdr->packet_type, hdr->message_type, hdr->signal_id);
}

static void dump_buffer(const unsigned char *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		printf("%02x ", buf[i]);
	printf("\n");
}

static void process_avdtp(int srv_sk, int sk, unsigned char reject,
								int fragment)
{
	unsigned char buf[672];
	ssize_t len;

	while (1) {
		struct avdtp_header *hdr = (void *) buf;

		len = read(sk, buf, sizeof(buf));
		if (len <= 0) {
			perror("Read failed");
			break;
		}

		dump_buffer(buf, len);
		dump_avdtp_header(hdr);

		if (hdr->packet_type != AVDTP_PKT_TYPE_SINGLE) {
			fprintf(stderr, "Only single packets are supported\n");
			break;
		}

		if (hdr->message_type != AVDTP_MSG_TYPE_COMMAND) {
			fprintf(stderr, "Ignoring non-command messages\n");
			continue;
		}

		switch (hdr->signal_id) {
		case AVDTP_DISCOVER:
			if (reject == AVDTP_DISCOVER) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = 0x29; /* Unsupported configuration */
				printf("Rejecting discover command\n");
				len = write(sk, buf, 3);
			} else {
				struct seid_info *sei = (void *) (buf + 2);
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				buf[2] = 0x00;
				buf[3] = 0x00;
				sei->seid = 0x01;
				sei->type = AVDTP_SEP_TYPE_SINK;
				sei->media_type = AVDTP_MEDIA_TYPE_AUDIO;
				printf("Accepting discover command\n");
				len = write(sk, buf, 4);
			}
			break;

		case AVDTP_GET_CAPABILITIES:
			if (reject == AVDTP_GET_CAPABILITIES) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = 0x29; /* Unsupported configuration */
				printf("Rejecting get capabilties command\n");
				len = write(sk, buf, 3);
			} else if (fragment) {
				struct avdtp_start_header *start = (void *) buf;

				printf("Sending fragmented reply to getcap\n");

				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;

				/* Start packet */
				hdr->packet_type = AVDTP_PKT_TYPE_START;
				start->signal_id = AVDTP_GET_CAPABILITIES;
				start->no_of_packets = 3;
				memcpy(&buf[3], media_transport,
						sizeof(media_transport));
				len = write(sk, buf,
						3 + sizeof(media_transport));

				/* Continue packet */
				hdr->packet_type = AVDTP_PKT_TYPE_CONTINUE;
				memcpy(&buf[1], media_transport,
						sizeof(media_transport));
				len = write(sk, buf,
						1 + sizeof(media_transport));

				/* End packet */
				hdr->packet_type = AVDTP_PKT_TYPE_END;
				memcpy(&buf[1], media_transport,
						sizeof(media_transport));
				len = write(sk, buf,
						1 + sizeof(media_transport));
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				memcpy(&buf[2], media_transport,
						sizeof(media_transport));
				printf("Accepting get capabilities command\n");
				len = write(sk, buf,
						2 + sizeof(media_transport));
			}
			break;

		case AVDTP_SET_CONFIGURATION:
			if (reject == AVDTP_SET_CONFIGURATION) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = buf[4];
				buf[3] = 0x13; /* SEP In Use */
				printf("Rejecting set configuration command\n");
				len = write(sk, buf, 4);
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting set configuration command\n");
				len = write(sk, buf, 2);
			}
			break;

		case AVDTP_GET_CONFIGURATION:
			if (reject == AVDTP_GET_CONFIGURATION) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = 0x12; /* Bad ACP SEID */
				printf("Rejecting get configuration command\n");
				len = write(sk, buf, 3);
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting get configuration command\n");
				len = write(sk, buf, 2);
			}
			break;

		case AVDTP_OPEN:
			if (reject == AVDTP_OPEN) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = 0x31; /* Bad State */
				printf("Rejecting open command\n");
				len = write(sk, buf, 3);
			} else {
				struct sockaddr_l2 addr;
				socklen_t optlen;

				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting open command\n");
				len = write(sk, buf, 2);

				memset(&addr, 0, sizeof(addr));
				optlen = sizeof(addr);

				media_sock = accept(srv_sk,
						(struct sockaddr *) &addr,
								&optlen);
				if (media_sock < 0) {
					perror("Accept failed");
					break;
				}
			}
			break;

		case AVDTP_START:
			if (reject == AVDTP_ABORT)
				printf("Ignoring start to cause abort");
			else if (reject == AVDTP_START) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[3] = 0x31; /* Bad State */
				printf("Rejecting start command\n");
				len = write(sk, buf, 4);
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting start command\n");
				len = write(sk, buf, 2);
			}
			break;

		case AVDTP_CLOSE:
			if (reject == AVDTP_CLOSE) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[2] = 0x31; /* Bad State */
				printf("Rejecting close command\n");
				len = write(sk, buf, 3);
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting close command\n");
				len = write(sk, buf, 2);
				if (media_sock >= 0) {
					close(media_sock);
					media_sock = -1;
				}
			}
			break;

		case AVDTP_SUSPEND:
			if (reject == AVDTP_SUSPEND) {
				hdr->message_type = AVDTP_MSG_TYPE_REJECT;
				buf[3] = 0x31; /* Bad State */
				printf("Rejecting suspend command\n");
				len = write(sk, buf, 4);
			} else {
				hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
				printf("Accepting suspend command\n");
				len = write(sk, buf, 2);
			}
			break;

		case AVDTP_ABORT:
			hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
			printf("Accepting abort command\n");
			len = write(sk, buf, 2);
			if (media_sock >= 0) {
				close(media_sock);
				media_sock = -1;
			}
			break;

		default:
			buf[1] = 0x00;
			printf("Unknown command\n");
			len = write(sk, buf, 2);
			break;
		}
	}
}

static void process_avctp(int sk, int reject)
{
	unsigned char buf[672];
	ssize_t len;

	while (1) {
		struct avctp_header *hdr = (void *) buf;

		len = read(sk, buf, sizeof(buf));
		if (len <= 0) {
			perror("Read failed");
			break;
		}

		dump_buffer(buf, len);

		if (len >= AVCTP_HEADER_LENGTH)
			dump_avctp_header(hdr);
	}
}

static int set_minimum_mtu(int sk)
{
	struct l2cap_options l2o;
	socklen_t optlen;

	memset(&l2o, 0, sizeof(l2o));
	optlen = sizeof(l2o);

	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &optlen) < 0) {
		perror("getsockopt");
		return -1;
	}

	l2o.imtu = 48;
	l2o.omtu = 48;

	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) {
		perror("setsockopt");
		return -1;
	}

	return 0;
}

static void do_listen(const bdaddr_t *src, unsigned char reject, int fragment)
{
	struct sockaddr_l2 addr;
	socklen_t optlen;
	int sk, nsk;

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (sk < 0) {
		perror("Can't create socket");
		return;
	}

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, src);
	addr.l2_psm = htobs(25);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Can't bind socket");
		goto error;
	}

	if (fragment)
		set_minimum_mtu(sk);

	if (listen(sk, 10)) {
		perror("Can't listen on the socket");
		goto error;
	}

	while (1) {
		memset(&addr, 0, sizeof(addr));
		optlen = sizeof(addr);

		nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
		if (nsk < 0) {
			perror("Accept failed");
			continue;
		}

		process_avdtp(sk, nsk, reject, fragment);

		if (media_sock >= 0) {
			close(media_sock);
			media_sock = -1;
		}

		close(nsk);
	}

error:
	close(sk);
}

static int do_connect(const bdaddr_t *src, const bdaddr_t *dst, int avctp,
								int fragment)
{
	struct sockaddr_l2 addr;
	int sk, err;

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (sk < 0) {
		perror("Can't create socket");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, src);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Can't bind socket");
		goto error;
	}

	if (fragment)
		set_minimum_mtu(sk);

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, dst);
	addr.l2_psm = htobs(avctp ? 23 : 25);

	err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
	if (err < 0) {
		perror("Unable to connect");
		goto error;
	}

	return sk;

error:
	close(sk);
	return -1;
}

static void do_avdtp_send(int sk, const bdaddr_t *src, const bdaddr_t *dst,
				unsigned char cmd, int invalid, int preconf)
{
	unsigned char buf[672];
	struct avdtp_header *hdr = (void *) buf;
	ssize_t len;

	memset(buf, 0, sizeof(buf));

	switch (cmd) {
	case AVDTP_DISCOVER:
		if (invalid)
			hdr->message_type = 0x01;
		else
			hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_DISCOVER;
		len = write(sk, buf, 2);
		break;

	case AVDTP_GET_CAPABILITIES:
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_GET_CAPABILITIES;
		buf[2] = 1 << 2; /* SEID 1 */
		len = write(sk, buf, invalid ? 2 : 3);
		break;

	case AVDTP_SET_CONFIGURATION:
		if (preconf)
			do_avdtp_send(sk, src, dst, cmd, 0, 0);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_SET_CONFIGURATION;
		buf[2] = 1 << 2; /* ACP SEID */
		buf[3] = 1 << 2; /* INT SEID */
		memcpy(&buf[4], media_transport, sizeof(media_transport));
		if (invalid)
			buf[5] = 0x01; /* LOSC != 0 */
		len = write(sk, buf, 4 + sizeof(media_transport));
		break;

	case AVDTP_GET_CONFIGURATION:
		if (preconf)
			do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_GET_CONFIGURATION;
		if (invalid)
			buf[2] = 13 << 2; /* Invalid ACP SEID */
		else
			buf[2] = 1 << 2; /* Valid ACP SEID */
		len = write(sk, buf, 3);
		break;

	case AVDTP_OPEN:
		if (preconf)
			do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_OPEN;
		buf[2] = 1 << 2; /* ACP SEID */
		len = write(sk, buf, 3);
		break;

	case AVDTP_START:
		if (preconf)
			do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
		if (!invalid)
			do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 0);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_START;
		buf[2] = 1 << 2; /* ACP SEID */
		len = write(sk, buf, 3);
		break;

	case AVDTP_CLOSE:
		if (preconf) {
			do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
			do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 0);
		}
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_CLOSE;
		if (invalid)
			buf[2] = 13 << 2; /* Invalid ACP SEID */
		else
			buf[2] = 1 << 2; /* Valid ACP SEID */
		len = write(sk, buf, 3);
		break;

	case AVDTP_SUSPEND:
		if (invalid)
			do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, preconf);
		else
			do_avdtp_send(sk, src, dst, AVDTP_START, 0, preconf);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_SUSPEND;
		buf[2] = 1 << 2; /* ACP SEID */
		len = write(sk, buf, 3);
		break;

	case AVDTP_ABORT:
		do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 1);
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = AVDTP_ABORT;
		buf[2] = 1 << 2; /* ACP SEID */
		len = write(sk, buf, 3);
		break;

	default:
		hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
		hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
		hdr->signal_id = cmd;
		len = write(sk, buf, 2);
		break;
	}

	do {
		len = read(sk, buf, sizeof(buf));

		dump_buffer(buf, len);
		dump_avdtp_header(hdr);
	} while (len < 2 || (hdr->message_type != AVDTP_MSG_TYPE_ACCEPT &&
				hdr->message_type != AVDTP_MSG_TYPE_REJECT &&
				hdr->message_type != AVDTP_MSG_TYPE_GEN_REJECT));

	if (cmd == AVDTP_OPEN && len >= 2 &&
				hdr->message_type == AVDTP_MSG_TYPE_ACCEPT)
		media_sock = do_connect(src, dst, 0, 0);
}

static void do_avctp_send(int sk, int invalid)
{
	unsigned char buf[672];
	struct avctp_header *hdr = (void *) buf;
	unsigned char play_pressed[] = { 0x00, 0x48, 0x7c, 0x44, 0x00 };
	ssize_t len;

	memset(buf, 0, sizeof(buf));

	hdr->packet_type = AVCTP_PACKET_SINGLE;
	hdr->cr = AVCTP_COMMAND;
	if (invalid)
		hdr->pid = 0xffff;
	else
		hdr->pid = htons(AV_REMOTE_SVCLASS_ID);

	memcpy(&buf[AVCTP_HEADER_LENGTH], play_pressed, sizeof(play_pressed));

	len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));

	len = read(sk, buf, sizeof(buf));

	dump_buffer(buf, len);
	if (len >= AVCTP_HEADER_LENGTH)
		dump_avctp_header(hdr);
}

static void usage()
{
	printf("avtest - Audio/Video testing ver %s\n", VERSION);
	printf("Usage:\n"
		"\tavtest [options] [remote address]\n");
	printf("Options:\n"
		"\t--device <hcidev>    HCI device\n"
		"\t--reject <command>   Reject command\n"
		"\t--send <command>     Send command\n"
		"\t--preconf            Configure stream before actual command\n"
		"\t--wait <N>           Wait N seconds before exiting\n"
		"\t--fragment           Use minimum MTU and fragmented messages\n"
		"\t--invalid <command>  Send invalid command\n");
}

static struct option main_options[] = {
	{ "help",	0, 0, 'h' },
	{ "device",	1, 0, 'i' },
	{ "reject",	1, 0, 'r' },
	{ "send",	1, 0, 's' },
	{ "invalid",	1, 0, 'f' },
	{ "preconf",	0, 0, 'c' },
	{ "fragment",   0, 0, 'F' },
	{ "avctp",	0, 0, 'C' },
	{ "wait",	1, 0, 'w' },
	{ 0, 0, 0, 0 }
};

static unsigned char parse_cmd(const char *arg)
{
	if (!strncmp(arg, "discov", 6))
		return AVDTP_DISCOVER;
	else if (!strncmp(arg, "capa", 4))
		return AVDTP_GET_CAPABILITIES;
	else if (!strncmp(arg, "getcapa", 7))
		return AVDTP_GET_CAPABILITIES;
	else if (!strncmp(arg, "setconf", 7))
		return AVDTP_SET_CONFIGURATION;
	else if (!strncmp(arg, "getconf", 7))
		return AVDTP_GET_CONFIGURATION;
	else if (!strncmp(arg, "open", 4))
		return AVDTP_OPEN;
	else if (!strncmp(arg, "start", 5))
		return AVDTP_START;
	else if (!strncmp(arg, "close", 5))
		return AVDTP_CLOSE;
	else if (!strncmp(arg, "suspend", 7))
		return AVDTP_SUSPEND;
	else if (!strncmp(arg, "abort", 7))
		return AVDTP_ABORT;
	else
		return atoi(arg);
}

enum {
	MODE_NONE, MODE_REJECT, MODE_SEND,
};

int main(int argc, char *argv[])
{
	unsigned char cmd = 0x00;
	bdaddr_t src, dst;
	int opt, mode = MODE_NONE, sk, invalid = 0, preconf = 0, fragment = 0;
	int avctp = 0, wait_before_exit = 0;

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

	while ((opt = getopt_long(argc, argv, "+i:r:s:f:hcFCw:",
						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 'r':
			mode = MODE_REJECT;
			cmd = parse_cmd(optarg);
			break;

		case 'f':
			invalid = 1;
			/* Intentionally missing break */

		case 's':
			mode = MODE_SEND;
			cmd = parse_cmd(optarg);
			break;

		case 'c':
			preconf = 1;
			break;

		case 'F':
			fragment = 1;
			break;

		case 'C':
			avctp = 1;
			break;

		case 'w':
			wait_before_exit = atoi(optarg);
			break;

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

	if (argv[optind])
		str2ba(argv[optind], &dst);

	if (avctp) {
		avctp = mode;
		mode = MODE_SEND;
	}

	switch (mode) {
	case MODE_REJECT:
		do_listen(&src, cmd, fragment);
		break;
	case MODE_SEND:
		sk = do_connect(&src, &dst, avctp, fragment);
		if (sk < 0)
			exit(1);
		if (avctp) {
			if (avctp == MODE_SEND)
				do_avctp_send(sk, invalid);
			else
				process_avctp(sk, cmd);
		} else
			do_avdtp_send(sk, &src, &dst, cmd, invalid, preconf);
		if (wait_before_exit) {
			printf("Waiting %d seconds before exiting\n", wait_before_exit);
			sleep(wait_before_exit);
		}
		if (media_sock >= 0)
			close(media_sock);
		close(sk);
		break;
	default:
		fprintf(stderr, "No operating mode specified!\n");
		exit(1);
	}

	return 0;
}
