/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2002-2004  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation;
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 *  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
 *  CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
 *  COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
 *  SOFTWARE IS DISCLAIMED.
 *
 *
 *  $Id$
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <getopt.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

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

static volatile sig_atomic_t __io_canceled = 0;

static void sig_hup(int sig)
{
	return;
}

static void sig_term(int sig)
{
	__io_canceled = 1;
}

static char *cmtp_state[] = {
	"unknown",
	"connected",
	"open",
	"bound",
	"listening",
	"connecting",
	"connecting",
	"config",
	"disconnecting",
	"closed"
};

static char *cmtp_flagstostr(uint32_t flags)
{
	static char str[100] = "";

	strcat(str, "[");

	if (flags & (1 << CMTP_LOOPBACK))
		strcat(str, "loopback");

	strcat(str, "]");

	return str;
}

static int get_psm(bdaddr_t *src, bdaddr_t *dst, unsigned short *psm)
{
	sdp_session_t *s;
	sdp_list_t *srch, *attrs, *rsp;
	uuid_t svclass;
	uint16_t attr;
	int err;

	if (!(s = sdp_connect(src, dst, 0)))
		return -1;

	sdp_uuid16_create(&svclass, CIP_SVCLASS_ID);
	srch = sdp_list_append(NULL, &svclass);

	attr = SDP_ATTR_PROTO_DESC_LIST;
	attrs = sdp_list_append(NULL, &attr);

	err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);

	sdp_close(s);

	if (err)
		return 0;

	for (; rsp; rsp = rsp->next) {
		sdp_record_t *rec = (sdp_record_t *) rsp->data;
		sdp_list_t *protos;

		if (!sdp_get_access_protos(rec, &protos)) {
			unsigned short p = sdp_get_proto_port(protos, L2CAP_UUID);
			if (p > 0) {
				*psm = p;
				return 1;
			}
		}
	}

	return 0;
}

static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint32_t flags)
{
	struct cmtp_connadd_req req;
	struct hci_dev_info di;
	struct sockaddr_l2 addr;
	struct l2cap_options opts;
	socklen_t size;
	int sk;

	hci_devinfo(dev_id, &di);
	if (!(di.link_policy & HCI_LP_RSWITCH)) {
		printf("Local device is not accepting role switch\n");
	}

	if ((sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
		perror("Can't create L2CAP socket");
		exit(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 L2CAP socket");
		close(sk);
		exit(1);
	}

	memset(&opts, 0, sizeof(opts));
	size = sizeof(opts);

	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) {
		perror("Can't get L2CAP options");
		close(sk);
		exit(1);
	}

	opts.imtu = CMTP_DEFAULT_MTU;
	opts.omtu = CMTP_DEFAULT_MTU;
	opts.flush_to = 0xffff;

	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
		perror("Can't set L2CAP options");
		close(sk);
		exit(1);
	}

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

	if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("Can't connect L2CAP socket");
		close(sk);
		exit(1);
	}

	req.sock = sk;
	req.flags = flags;

	if (ioctl(ctl, CMTPCONNADD, &req) < 0) {
		perror("Can't create connection");
		exit(1);
	}

	return sk;
}

static void cmd_show(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
{
	struct cmtp_connlist_req req;
	struct cmtp_conninfo ci[16];
	char addr[18];
	int i;

	req.cnum = 16;
	req.ci   = ci;

	if (ioctl(ctl, CMTPGETCONNLIST, &req) < 0) {
		perror("Can't get connection list");
		exit(1);
	}

	for (i = 0; i < req.cnum; i++) {
		ba2str(&ci[i].bdaddr, addr);
		printf("%d %s %s %s\n", ci[i].num, addr,
			cmtp_state[ci[i].state],
			ci[i].flags ? cmtp_flagstostr(ci[i].flags) : "");
	}
}

static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
{
	inquiry_info *info = NULL;
	bdaddr_t src, dst;
	unsigned short psm;
	int i, dev_id, num_rsp, length, flags;
	char addr[18];
	uint8_t class[3];

	ba2str(bdaddr, addr);
	dev_id = hci_devid(addr);
	if (dev_id < 0) {
		dev_id = hci_get_route(NULL);
		hci_devba(dev_id, &src);
	} else
		bacpy(&src, bdaddr);

	length  = 8;	/* ~10 seconds */
	num_rsp = 0;
	flags   = 0;

	printf("Searching ...\n");

	num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags);

	for (i = 0; i < num_rsp; i++) {
		memcpy(class, (info+i)->dev_class, 3);
		if ((class[1] == 2) && ((class[0] / 4) == 5)) {
			bacpy(&dst, &(info+i)->bdaddr);
			ba2str(&dst, addr);

			printf("\tChecking service for %s\n", addr);
			if (!get_psm(&src, &dst, &psm))
				continue;

			bt_free(info);

			printf("\tConnecting to device %s\n", addr);
			do_connect(ctl, dev_id, &src, &dst, psm, 0);
			return;
		}
	}

	bt_free(info);
	fprintf(stderr, "\tNo devices in range or visible\n");
	exit(1);
}

static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
{
	bdaddr_t src, dst;
	unsigned short psm;
	int dev_id;
	char addr[18];

	if (argc < 2)
		return;

	str2ba(argv[1], &dst);

	ba2str(bdaddr, addr);
	dev_id = hci_devid(addr);
	if (dev_id < 0) {
		dev_id = hci_get_route(&dst);
		hci_devba(dev_id, &src);
	} else
		bacpy(&src, bdaddr);

	if (argc < 3) {
		if (!get_psm(&src, &dst, &psm))
			psm = 4099;
	} else
		psm = atoi(argv[2]);

	do_connect(ctl, dev_id, &src, &dst, psm, 0);
}

static void cmd_release(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
{
	struct cmtp_conndel_req req;
	struct cmtp_connlist_req cl;
	struct cmtp_conninfo ci[16];

	if (argc < 2) {
		cl.cnum = 16;
		cl.ci   = ci;

		if (ioctl(ctl, CMTPGETCONNLIST, &cl) < 0) {
			perror("Can't get connection list");
			exit(1);
		}

		if (cl.cnum == 0)
			return;

		if (cl.cnum != 1) {
			fprintf(stderr, "You have to specifiy the device address.\n");
			exit(1);
		}

		bacpy(&req.bdaddr, &ci[0].bdaddr);
	} else
		str2ba(argv[1], &req.bdaddr);

	if (ioctl(ctl, CMTPCONNDEL, &req) < 0) {
		perror("Can't release connection");
		exit(1);
	}
}

static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
{
	struct cmtp_conndel_req req;
	struct sigaction sa;
	struct pollfd p;
	bdaddr_t src, dst;
	unsigned short psm;
	int dev_id, sk;
	char addr[18];

	if (argc < 2)
		return;

	str2ba(argv[1], &dst);

	ba2str(bdaddr, addr);
	dev_id = hci_devid(addr);
	if (dev_id < 0) {
		dev_id = hci_get_route(&dst);
		hci_devba(dev_id, &src);
	} else
		bacpy(&src, bdaddr);

	ba2str(&dst, addr);
	printf("Connecting to %s in loopback mode\n", addr);

	if (argc < 3) {
		if (!get_psm(&src, &dst, &psm))
			psm = 4099;
	} else
		psm = atoi(argv[2]);

	sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));

	printf("Press CTRL-C for hangup\n");

	memset(&sa, 0, sizeof(sa));
	sa.sa_flags   = SA_NOCLDSTOP;
	sa.sa_handler = SIG_IGN;
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGPIPE, &sa, NULL);

	sa.sa_handler = sig_term;
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT,  &sa, NULL);

	sa.sa_handler = sig_hup;
	sigaction(SIGHUP, &sa, NULL);

	p.fd = sk;
	p.events = POLLERR | POLLHUP;

	while (!__io_canceled) {
		p.revents = 0;
		if (poll(&p, 1, 100))
			break;
	}

	bacpy(&req.bdaddr, &dst);
	ioctl(ctl, CMTPCONNDEL, &req);
}

static struct {
	char *cmd;
	char *alt;
	void (*func)(int ctl, bdaddr_t *bdaddr, int argc, char **argv);
	char *opt;
	char *doc;
} command[] = {
	{ "show",     "list",       cmd_show,     0,          "Show remote connections"      },
	{ "search",   "scan",       cmd_search,   0,          "Search for a remote device"   },
	{ "connect",  "create",     cmd_create,   "<bdaddr>", "Connect a remote device"      },
	{ "release",  "disconnect", cmd_release,  "[bdaddr]", "Disconnect the remote device" },
	{ "loopback", "test",       cmd_loopback, "<bdaddr>", "Loopback test of a device"    },
	{ NULL, NULL, NULL, 0, 0 }
};

static void usage(void)
{
	int i;

	printf("ciptool - Bluetooth Common ISDN Access Profile (CIP)\n\n");

	printf("Usage:\n"
		"\tciptool [options] [command]\n"
		"\n");

	printf("Options:\n"
		"\t-i [hciX|bdaddr]   Local HCI device or BD Address\n"
		"\t-h, --help         Display help\n"
		"\n");

	printf("Commands:\n");
	for (i = 0; command[i].cmd; i++)
		printf("\t%-8s %-10s\t%s\n", command[i].cmd,
		command[i].opt ? command[i].opt : " ",
		command[i].doc);
	printf("\n");
}

static struct option main_options[] = {
	{ "help",	0, 0, 'h' },
	{ "device",	1, 0, 'i' },
	{ 0, 0, 0, 0 }
};

int main(int argc, char *argv[])
{
	bdaddr_t bdaddr;
	int i, opt, ctl;

	bacpy(&bdaddr, BDADDR_ANY);

	while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
		switch(opt) {
		case 'i':
			if (!strncmp(optarg, "hci", 3))
				hci_devba(atoi(optarg + 3), &bdaddr);
			else
				str2ba(optarg, &bdaddr);
			break;
		case 'h':
			usage();
			exit(0);
		default:
			exit(0);
		}
	}

	argc -= optind;
	argv += optind;
	optind = 0;

	if (argc < 1) {
		usage();
		return 0;
	}

	if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_CMTP)) < 0 ) {
		perror("Can't open CMTP control socket");
		exit(1);
	}

	for (i = 0; command[i].cmd; i++) {
		if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4))
			continue;
		command[i].func(ctl, &bdaddr, argc, argv);
		close(ctl);
		exit(0);
	}

	usage();

	close(ctl);

	return 0;
}
