/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011-2012  Intel Corporation
 *  Copyright (C) 2004-2010  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 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 <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
#include <getopt.h>
#include <stdbool.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <netdb.h>
#include <arpa/inet.h>

#include "src/shared/util.h"
#include "src/shared/mainloop.h"
#include "src/shared/ecc.h"
#include "monitor/bt.h"

#define HCI_PRIMARY	0x00
#define HCI_AMP		0x01

#define BTPROTO_HCI	1
struct sockaddr_hci {
	sa_family_t	hci_family;
	unsigned short	hci_dev;
	unsigned short  hci_channel;
};
#define HCI_CHANNEL_USER	1

static uint16_t hci_index = 0;
static bool client_active = false;
static bool debug_enabled = false;
static bool emulate_ecc = false;
static bool skip_first_zero = false;

static void hexdump_print(const char *str, void *user_data)
{
	printf("%s%s\n", (char *) user_data, str);
}

struct proxy {
	/* Receive commands, ACL and SCO data */
	int host_fd;
	uint8_t host_buf[4096];
	uint16_t host_len;
	bool host_shutdown;
	bool host_skip_first_zero;

	/* Receive events, ACL and SCO data */
	int dev_fd;
	uint8_t dev_buf[4096];
	uint16_t dev_len;
	bool dev_shutdown;

	/* ECC emulation */
	uint8_t event_mask[8];
	uint8_t local_sk256[32];
};

static bool write_packet(int fd, const void *data, size_t size,
							void *user_data)
{
	while (size > 0) {
		ssize_t written;

		written = write(fd, data, size);
		if (written < 0) {
			if (errno == EAGAIN || errno == EINTR)
				continue;
			return false;
		}

		if (debug_enabled)
			util_hexdump('<', data, written, hexdump_print,
								user_data);

		data += written;
		size -= written;
	}

	return true;
}

static void host_write_packet(struct proxy *proxy, void *buf, uint16_t len)
{
	if (!write_packet(proxy->dev_fd, buf, len, "D: ")) {
		fprintf(stderr, "Write to device descriptor failed\n");
		mainloop_remove_fd(proxy->dev_fd);
	}
}

static void dev_write_packet(struct proxy *proxy, void *buf, uint16_t len)
{
	if (!write_packet(proxy->host_fd, buf, len, "H: ")) {
		fprintf(stderr, "Write to host descriptor failed\n");
		mainloop_remove_fd(proxy->host_fd);
	}
}

static void cmd_status(struct proxy *proxy, uint8_t status, uint16_t opcode)
{
	size_t buf_size = 1 + sizeof(struct bt_hci_evt_hdr) +
					sizeof(struct bt_hci_evt_cmd_status);
	void *buf = alloca(buf_size);
	struct bt_hci_evt_hdr *hdr = buf + 1;
	struct bt_hci_evt_cmd_status *cs = buf + 1 + sizeof(*hdr);

	*((uint8_t *) buf) = BT_H4_EVT_PKT;

	hdr->evt = BT_HCI_EVT_CMD_STATUS;
	hdr->plen = sizeof(*cs);

	cs->status = status;
	cs->ncmd = 0x01;
	cs->opcode = cpu_to_le16(opcode);

	dev_write_packet(proxy, buf, buf_size);
}

static void le_meta_event(struct proxy *proxy, uint8_t event,
						void *data, uint8_t len)
{
	size_t buf_size = 1 + sizeof(struct bt_hci_evt_hdr) + 1 + len;
	void *buf = alloca(buf_size);
	struct bt_hci_evt_hdr *hdr = buf + 1;

	*((uint8_t *) buf) = BT_H4_EVT_PKT;

	hdr->evt = BT_HCI_EVT_LE_META_EVENT;
	hdr->plen = 1 + len;

	*((uint8_t *) (buf + 1 + sizeof(*hdr))) = event;

	if (len > 0)
		memcpy(buf + 1 + sizeof(*hdr) + 1, data, len);

	dev_write_packet(proxy, buf, buf_size);
}

static void host_emulate_ecc(struct proxy *proxy, void *buf, uint16_t len)
{
	uint8_t pkt_type = *((uint8_t *) buf);
	struct bt_hci_cmd_hdr *hdr = buf + 1;
	struct bt_hci_cmd_le_set_event_mask *lsem;
	struct bt_hci_cmd_le_generate_dhkey *lgd;
	struct bt_hci_evt_le_read_local_pk256_complete lrlpkc;
	struct bt_hci_evt_le_generate_dhkey_complete lgdc;

	if (pkt_type != BT_H4_CMD_PKT) {
		host_write_packet(proxy, buf, len);
		return;
	}

	switch (le16_to_cpu(hdr->opcode)) {
	case BT_HCI_CMD_LE_SET_EVENT_MASK:
		lsem = buf + 1 + sizeof(*hdr);
		memcpy(proxy->event_mask, lsem->mask, 8);

		lsem->mask[0] &= ~0x80;		/* P-256 Public Key Complete */
		lsem->mask[1] &= ~0x01;		/* Generate DHKey Complete */

		host_write_packet(proxy, buf, len);
		break;

	case BT_HCI_CMD_LE_READ_LOCAL_PK256:
		if (!ecc_make_key(lrlpkc.local_pk256, proxy->local_sk256)) {
			cmd_status(proxy, BT_HCI_ERR_COMMAND_DISALLOWED,
					BT_HCI_CMD_LE_READ_LOCAL_PK256);
			break;
		}
		cmd_status(proxy, BT_HCI_ERR_SUCCESS,
					BT_HCI_CMD_LE_READ_LOCAL_PK256);

		if (!(proxy->event_mask[0] & 0x80))
			break;

		lrlpkc.status = BT_HCI_ERR_SUCCESS;
		le_meta_event(proxy, BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE,
						&lrlpkc, sizeof(lrlpkc));
		break;

	case BT_HCI_CMD_LE_GENERATE_DHKEY:
		lgd = buf + 1 + sizeof(*hdr);
		if (!ecdh_shared_secret(lgd->remote_pk256, proxy->local_sk256,
								lgdc.dhkey)) {
			cmd_status(proxy, BT_HCI_ERR_COMMAND_DISALLOWED,
						BT_HCI_CMD_LE_GENERATE_DHKEY);
			break;
		}
		cmd_status(proxy, BT_HCI_ERR_SUCCESS,
					BT_HCI_CMD_LE_GENERATE_DHKEY);

		if (!(proxy->event_mask[1] & 0x01))
			break;

		lgdc.status = BT_HCI_ERR_SUCCESS;
		le_meta_event(proxy, BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE,
							&lgdc, sizeof(lgdc));
		break;

	default:
		host_write_packet(proxy, buf, len);
		break;
	}
}

static void dev_emulate_ecc(struct proxy *proxy, void *buf, uint16_t len)
{
	uint8_t pkt_type = *((uint8_t *) buf);
	struct bt_hci_evt_hdr *hdr = buf + 1;
	struct bt_hci_evt_cmd_complete *cc;
	struct bt_hci_rsp_read_local_commands *rlc;

	if (pkt_type != BT_H4_EVT_PKT) {
		dev_write_packet(proxy, buf, len);
		return;
	}

	switch (hdr->evt) {
	case BT_HCI_EVT_CMD_COMPLETE:
		cc = buf + 1 + sizeof(*hdr);

		switch (le16_to_cpu(cc->opcode)) {
		case BT_HCI_CMD_READ_LOCAL_COMMANDS:
			rlc = buf + 1 + sizeof(*hdr) + sizeof(*cc);
			rlc->commands[34] |= 0x02;	/* P-256 Public Key */
			rlc->commands[34] |= 0x04;	/* Generate DHKey */
			break;
		}

		dev_write_packet(proxy, buf, len);
		break;

	default:
		dev_write_packet(proxy, buf, len);
		break;
	}
}

static void host_read_destroy(void *user_data)
{
	struct proxy *proxy = user_data;

	printf("Closing host descriptor\n");

	if (proxy->host_shutdown)
		shutdown(proxy->host_fd, SHUT_RDWR);

	close(proxy->host_fd);
	proxy->host_fd = -1;

	if (proxy->dev_fd < 0) {
		client_active = false;
		free(proxy);
	} else
		mainloop_remove_fd(proxy->dev_fd);
}

static void host_read_callback(int fd, uint32_t events, void *user_data)
{
	struct proxy *proxy = user_data;
	struct bt_hci_cmd_hdr *cmd_hdr;
	struct bt_hci_acl_hdr *acl_hdr;
	struct bt_hci_sco_hdr *sco_hdr;
	ssize_t len;
	uint16_t pktlen;

	if (events & (EPOLLERR | EPOLLHUP)) {
		fprintf(stderr, "Error from host descriptor\n");
		mainloop_remove_fd(proxy->host_fd);
		return;
	}

	if (events & EPOLLRDHUP) {
		fprintf(stderr, "Remote hangup of host descriptor\n");
		mainloop_remove_fd(proxy->host_fd);
		return;
	}

	len = read(proxy->host_fd, proxy->host_buf + proxy->host_len,
				sizeof(proxy->host_buf) - proxy->host_len);
	if (len < 0) {
		if (errno == EAGAIN || errno == EINTR)
			return;

		fprintf(stderr, "Read from host descriptor failed\n");
		mainloop_remove_fd(proxy->host_fd);
		return;
	}

	if (debug_enabled)
		util_hexdump('>', proxy->host_buf + proxy->host_len, len,
						hexdump_print, "H: ");

	if (proxy->host_skip_first_zero && len > 0) {
		proxy->host_skip_first_zero = false;
		if (proxy->host_buf[proxy->host_len] == '\0') {
			printf("Skipping initial zero byte\n");
			len--;
			memmove(proxy->host_buf + proxy->host_len,
				proxy->host_buf + proxy->host_len + 1, len);
		}
	}

	proxy->host_len += len;

process_packet:
	if (proxy->host_len < 1)
		return;

	switch (proxy->host_buf[0]) {
	case BT_H4_CMD_PKT:
		if (proxy->host_len < 1 + sizeof(*cmd_hdr))
			return;

		cmd_hdr = (void *) (proxy->host_buf + 1);
		pktlen = 1 + sizeof(*cmd_hdr) + cmd_hdr->plen;
		break;
	case BT_H4_ACL_PKT:
		if (proxy->host_len < 1 + sizeof(*acl_hdr))
			return;

		acl_hdr = (void *) (proxy->host_buf + 1);
		pktlen = 1 + sizeof(*acl_hdr) + cpu_to_le16(acl_hdr->dlen);
		break;
	case BT_H4_SCO_PKT:
		if (proxy->host_len < 1 + sizeof(*sco_hdr))
			return;

		sco_hdr = (void *) (proxy->host_buf + 1);
		pktlen = 1 + sizeof(*sco_hdr) + sco_hdr->dlen;
		break;
	case 0xff:
		/* Notification packet from /dev/vhci - ignore */
		proxy->host_len = 0;
		return;
	default:
		fprintf(stderr, "Received unknown host packet type 0x%02x\n",
							proxy->host_buf[0]);
		mainloop_remove_fd(proxy->host_fd);
		return;
	}

	if (proxy->host_len < pktlen)
		return;

	if (emulate_ecc)
		host_emulate_ecc(proxy, proxy->host_buf, pktlen);
	else
		host_write_packet(proxy, proxy->host_buf, pktlen);

	if (proxy->host_len > pktlen) {
		memmove(proxy->host_buf, proxy->host_buf + pktlen,
						proxy->host_len - pktlen);
		proxy->host_len -= pktlen;
		goto process_packet;
	}

	proxy->host_len = 0;
}

static void dev_read_destroy(void *user_data)
{
	struct proxy *proxy = user_data;

	printf("Closing device descriptor\n");

	if (proxy->dev_shutdown)
		shutdown(proxy->dev_fd, SHUT_RDWR);

	close(proxy->dev_fd);
	proxy->dev_fd = -1;

	if (proxy->host_fd < 0) {
		client_active = false;
		free(proxy);
	} else
		mainloop_remove_fd(proxy->host_fd);
}

static void dev_read_callback(int fd, uint32_t events, void *user_data)
{
	struct proxy *proxy = user_data;
	struct bt_hci_evt_hdr *evt_hdr;
	struct bt_hci_acl_hdr *acl_hdr;
	struct bt_hci_sco_hdr *sco_hdr;
	ssize_t len;
	uint16_t pktlen;

	if (events & (EPOLLERR | EPOLLHUP)) {
		fprintf(stderr, "Error from device descriptor\n");
		mainloop_remove_fd(proxy->dev_fd);
		return;
	}

	if (events & EPOLLRDHUP) {
		fprintf(stderr, "Remote hangup of device descriptor\n");
		mainloop_remove_fd(proxy->host_fd);
		return;
	}

	len = read(proxy->dev_fd, proxy->dev_buf + proxy->dev_len,
				sizeof(proxy->dev_buf) - proxy->dev_len);
	if (len < 0) {
		if (errno == EAGAIN || errno == EINTR)
			return;

		fprintf(stderr, "Read from device descriptor failed\n");
		mainloop_remove_fd(proxy->dev_fd);
		return;
	}

	if (debug_enabled)
		util_hexdump('>', proxy->dev_buf + proxy->dev_len, len,
						hexdump_print, "D: ");

	proxy->dev_len += len;

process_packet:
	if (proxy->dev_len < 1)
		return;

	switch (proxy->dev_buf[0]) {
	case BT_H4_EVT_PKT:
		if (proxy->dev_len < 1 + sizeof(*evt_hdr))
			return;

		evt_hdr = (void *) (proxy->dev_buf + 1);
		pktlen = 1 + sizeof(*evt_hdr) + evt_hdr->plen;
		break;
	case BT_H4_ACL_PKT:
		if (proxy->dev_len < 1 + sizeof(*acl_hdr))
			return;

		acl_hdr = (void *) (proxy->dev_buf + 1);
		pktlen = 1 + sizeof(*acl_hdr) + cpu_to_le16(acl_hdr->dlen);
		break;
	case BT_H4_SCO_PKT:
		if (proxy->dev_len < 1 + sizeof(*sco_hdr))
			return;

		sco_hdr = (void *) (proxy->dev_buf + 1);
		pktlen = 1 + sizeof(*sco_hdr) + sco_hdr->dlen;
		break;
	default:
		fprintf(stderr, "Received unknown device packet type 0x%02x\n",
							proxy->dev_buf[0]);
		mainloop_remove_fd(proxy->dev_fd);
		return;
	}

	if (proxy->dev_len < pktlen)
		return;

	if (emulate_ecc)
		dev_emulate_ecc(proxy, proxy->dev_buf, pktlen);
	else
		dev_write_packet(proxy, proxy->dev_buf, pktlen);

	if (proxy->dev_len > pktlen) {
		memmove(proxy->dev_buf, proxy->dev_buf + pktlen,
						proxy->dev_len - pktlen);
		proxy->dev_len -= pktlen;
		goto process_packet;
	}

	proxy->dev_len = 0;
}

static bool setup_proxy(int host_fd, bool host_shutdown,
						int dev_fd, bool dev_shutdown)
{
	struct proxy *proxy;

	proxy = new0(struct proxy, 1);
	if (!proxy)
		return false;

	if (emulate_ecc)
		printf("Enabling ECC emulation\n");

	proxy->host_fd = host_fd;
	proxy->host_shutdown = host_shutdown;
	proxy->host_skip_first_zero = skip_first_zero;

	proxy->dev_fd = dev_fd;
	proxy->dev_shutdown = dev_shutdown;

	mainloop_add_fd(proxy->host_fd, EPOLLIN | EPOLLRDHUP,
				host_read_callback, proxy, host_read_destroy);

	mainloop_add_fd(proxy->dev_fd, EPOLLIN | EPOLLRDHUP,
				dev_read_callback, proxy, dev_read_destroy);

	return true;
}

static int open_channel(uint16_t index)
{
	struct sockaddr_hci addr;
	int fd;

	printf("Opening user channel for hci%u\n", hci_index);

	fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
	if (fd < 0) {
		perror("Failed to open Bluetooth socket");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.hci_family = AF_BLUETOOTH;
	addr.hci_dev = index;
	addr.hci_channel = HCI_CHANNEL_USER;

	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		close(fd);
		perror("Failed to bind Bluetooth socket");
		return -1;
	}

	return fd;
}

static void server_callback(int fd, uint32_t events, void *user_data)
{
	union {
		struct sockaddr common;
		struct sockaddr_un sun;
		struct sockaddr_in sin;
	} addr;
	socklen_t len;
	int host_fd, dev_fd;

	if (events & (EPOLLERR | EPOLLHUP)) {
		mainloop_quit();
		return;
	}

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

	if (getsockname(fd, &addr.common, &len) < 0) {
		perror("Failed to get socket name");
		return;
	}

	host_fd = accept(fd, &addr.common, &len);
	if (host_fd < 0) {
		perror("Failed to accept client socket");
		return;
	}

	if (client_active) {
		fprintf(stderr, "Active client already present\n");
		close(host_fd);
		return;
	}

	dev_fd = open_channel(hci_index);
	if (dev_fd < 0) {
		close(host_fd);
		return;
	}

	printf("New client connected\n");

	if (!setup_proxy(host_fd, true, dev_fd, false)) {
		close(dev_fd);
		close(host_fd);
		return;
	}

	client_active = true;
}

static int open_unix(const char *path)
{
	struct sockaddr_un addr;
	size_t len;
	int fd;

	len = strlen(path);
	if (len > sizeof(addr.sun_path) - 1) {
		fprintf(stderr, "Path too long\n");
		return -1;
	}

	unlink(path);

	fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
	if (fd < 0) {
		perror("Failed to open Unix server socket");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, path, len);

	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Failed to bind Unix server socket");
		close(fd);
		return -1;
	}

	if (listen(fd, 1) < 0) {
		perror("Failed to listen Unix server socket");
		close(fd);
		return -1;
	}

	if (chmod(path, 0666) < 0)
		perror("Failed to change mode");

	return fd;
}

static int open_tcp(const char *address, unsigned int port)
{
	struct sockaddr_in addr;
	int fd, opt = 1;

	fd = socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
	if (fd < 0) {
		perror("Failed to open TCP server socket");
		return -1;
	}

	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(address);
	addr.sin_port = htons(port);

	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Failed to bind TCP server socket");
		close(fd);
		return -1;
	}

	if (listen(fd, 1) < 0) {
		perror("Failed to listen TCP server socket");
		close(fd);
		return -1;
	}

	return fd;
}

static int connect_tcp(const char *address, unsigned int port)
{
	struct sockaddr_in addr;
	int fd;

	fd = socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
	if (fd < 0) {
		perror("Failed to open TCP client socket");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(address);
	addr.sin_port = htons(port);

	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Failed to connect TCP client socket");
		close(fd);
		return -1;
	}

	return fd;
}

static int open_vhci(uint8_t type)
{
	uint8_t create_req[2] = { 0xff, type };
	ssize_t written;
	int fd;

	fd = open("/dev/vhci", O_RDWR | O_CLOEXEC);
	if (fd < 0) {
		perror("Failed to open /dev/vhci device");
		return -1;
	}

	written = write(fd, create_req, sizeof(create_req));
	if (written < 0) {
		perror("Failed to set device type");
		close(fd);
		return -1;
	}

	return fd;
}

static void signal_callback(int signum, void *user_data)
{
	switch (signum) {
	case SIGINT:
	case SIGTERM:
		mainloop_quit();
		break;
	}
}

static void usage(void)
{
	printf("btproxy - Bluetooth controller proxy\n"
		"Usage:\n");
	printf("\tbtproxy [options]\n");
	printf("Options:\n"
		"\t-c, --connect <address>     Connect to server\n"
		"\t-l, --listen [address]      Use TCP server\n"
		"\t-u, --unix [path]           Use Unix server\n"
		"\t-p, --port <port>           Use specified TCP port\n"
		"\t-i, --index <num>           Use specified controller\n"
		"\t-a, --amp                   Create AMP controller\n"
		"\t-e, --ecc                   Emulate ECC support\n"
		"\t-d, --debug                 Enable debugging output\n"
		"\t-h, --help                  Show help options\n");
}

static const struct option main_options[] = {
	{ "redirect", no_argument,       NULL, 'r' },
	{ "connect",  required_argument, NULL, 'c' },
	{ "listen",   optional_argument, NULL, 'l' },
	{ "unix",     optional_argument, NULL, 'u' },
	{ "port",     required_argument, NULL, 'p' },
	{ "index",    required_argument, NULL, 'i' },
	{ "amp",      no_argument,       NULL, 'a' },
	{ "ecc",      no_argument,       NULL, 'e' },
	{ "debug",    no_argument,       NULL, 'd' },
	{ "version",  no_argument,       NULL, 'v' },
	{ "help",     no_argument,       NULL, 'h' },
	{ }
};

int main(int argc, char *argv[])
{
	const char *connect_address = NULL;
	const char *server_address = NULL;
	const char *unix_path = NULL;
	unsigned short tcp_port = 0xb1ee;	/* 45550 */
	bool use_redirect = false;
	uint8_t type = HCI_PRIMARY;
	const char *str;
	sigset_t mask;

	for (;;) {
		int opt;

		opt = getopt_long(argc, argv, "rc:l::u::p:i:aezdvh",
						main_options, NULL);
		if (opt < 0)
			break;

		switch (opt) {
		case 'r':
			use_redirect = true;
			break;
		case 'c':
			connect_address = optarg;
			break;
		case 'l':
			if (optarg)
				server_address = optarg;
			else
				server_address = "0.0.0.0";
			break;
		case 'u':
			if (optarg) {
				struct sockaddr_un addr;

				unix_path = optarg;
				if (strlen(unix_path) >
						sizeof(addr.sun_path) - 1) {
					fprintf(stderr, "Path too long\n");
					return EXIT_FAILURE;
				}
			} else
				unix_path = "/tmp/bt-server-bredr";
			break;
		case 'p':
			tcp_port = atoi(optarg);
			break;
		case 'i':
			if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
				str = optarg + 3;
			else
				str = optarg;
			if (!isdigit(*str)) {
				usage();
				return EXIT_FAILURE;
			}
			hci_index = atoi(str);
			break;
		case 'a':
			type = HCI_AMP;
			break;
		case 'e':
			emulate_ecc = true;
			break;
		case 'z':
			skip_first_zero = true;
			break;
		case 'd':
			debug_enabled = true;
			break;
		case 'v':
			printf("%s\n", VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage();
			return EXIT_SUCCESS;
		default:
			return EXIT_FAILURE;
		}
	}

	if (argc - optind > 0) {
		fprintf(stderr, "Invalid command line parameters\n");
		return EXIT_FAILURE;
	}

	if (unix_path && (server_address || use_redirect)) {
		fprintf(stderr, "Invalid to specify TCP and Unix servers\n");
		return EXIT_FAILURE;
	}

	if (connect_address && (unix_path || server_address || use_redirect)) {
		fprintf(stderr, "Invalid to specify client and server mode\n");
		return EXIT_FAILURE;
	}

	mainloop_init();

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGTERM);

	mainloop_set_signal(&mask, signal_callback, NULL, NULL);

	if (connect_address || use_redirect) {
		int host_fd, dev_fd;

		if (use_redirect) {
			printf("Creating local redirect\n");

			dev_fd = open_channel(hci_index);
		} else {
			printf("Connecting to %s:%u\n", connect_address,
								tcp_port);

			dev_fd = connect_tcp(connect_address, tcp_port);
		}

		if (dev_fd < 0)
			return EXIT_FAILURE;

		printf("Opening virtual device\n");

		host_fd = open_vhci(type);
		if (host_fd < 0) {
			close(dev_fd);
			return EXIT_FAILURE;
		}

		if (!setup_proxy(host_fd, false, dev_fd, true)) {
			close(dev_fd);
			close(host_fd);
			return EXIT_FAILURE;
		}
	} else {
		int server_fd;

		if (unix_path) {
			printf("Listening on %s\n", unix_path);

			server_fd = open_unix(unix_path);
		} else if (server_address) {
			printf("Listening on %s:%u\n", server_address,
								tcp_port);

			server_fd = open_tcp(server_address, tcp_port);
		} else {
			fprintf(stderr, "Missing emulator device\n");
			return EXIT_FAILURE;
		}

		if (server_fd < 0)
			return EXIT_FAILURE;

		mainloop_add_fd(server_fd, EPOLLIN, server_callback,
							NULL, NULL);
	}

	return mainloop_run();
}
