/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2002  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2003-2008  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 <stdint.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>
#include <syslog.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/resource.h>

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

#include <netdb.h>

#include <glib.h>

#if __BYTE_ORDER == __LITTLE_ENDIAN
static inline uint64_t ntoh64(uint64_t n)
{
	uint64_t h;
	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
	h = ntohl(n >> 32);
	h |= tmp << 32;
	return h;
}
#elif __BYTE_ORDER == __BIG_ENDIAN
#define ntoh64(x) (x)
#else
#error "Unknown byte order"
#endif
#define hton64(x) ntoh64(x)

#define GHCI_DEV		"/dev/ghci"

#define VHCI_DEV		"/dev/vhci"
#define VHCI_UDEV		"/dev/hci_vhci"

#define VHCI_MAX_CONN		12

#define VHCI_ACL_MTU		192
#define VHCI_ACL_MAX_PKT	8

struct vhci_device {
	uint8_t		features[8];
	uint8_t		name[248];
	uint8_t		dev_class[3];
	uint8_t		inq_mode;
	uint8_t		eir_fec;
	uint8_t		eir_data[240];
	uint16_t	acl_cnt;
	bdaddr_t	bdaddr;
	int		fd;
	int		dd;
	GIOChannel	*scan;
};

struct vhci_conn {
	bdaddr_t	dest;
	uint16_t	handle;
	GIOChannel	*chan;
};

struct vhci_link_info {
	bdaddr_t	bdaddr;
	uint8_t		dev_class[3];
	uint8_t		link_type;
	uint8_t		role;
} __attribute__ ((packed));

static struct vhci_device vdev;
static struct vhci_conn *vconn[VHCI_MAX_CONN];

struct btsnoop_hdr {
	uint8_t		id[8];		/* Identification Pattern */
	uint32_t	version;	/* Version Number = 1 */
	uint32_t	type;		/* Datalink Type */
} __attribute__ ((packed));
#define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr))

struct btsnoop_pkt {
	uint32_t	size;		/* Original Length */
	uint32_t	len;		/* Included Length */
	uint32_t	flags;		/* Packet Flags */
	uint32_t	drops;		/* Cumulative Drops */
	uint64_t	ts;		/* Timestamp microseconds */
	uint8_t		data[0];	/* Packet Data */
} __attribute__ ((packed));
#define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt))

static uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00 };

static GMainLoop *event_loop;

static volatile sig_atomic_t __io_canceled;

static inline void io_init(void)
{
	__io_canceled = 0;
}

static inline void io_cancel(void)
{
	__io_canceled = 1;
}

static void sig_term(int sig)
{
	io_cancel();
	g_main_loop_quit(event_loop);
}

static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data);
static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data);
static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data);

static inline int read_n(int fd, void *buf, int len)
{
	register int w, t = 0;

	while (!__io_canceled && len > 0) {
		if ((w = read(fd, buf, len)) < 0 ){
			if( errno == EINTR || errno == EAGAIN )
				continue;
			return -1;
		}
		if (!w)
			return 0;
		len -= w; buf += w; t += w;
	}
	return t;
}

/* Write exactly len bytes (Signal safe)*/
static inline int write_n(int fd, void *buf, int len)
{
	register int w, t = 0;

	while (!__io_canceled && len > 0) {
		if ((w = write(fd, buf, len)) < 0 ){
			if( errno == EINTR || errno == EAGAIN )
				continue;
			return -1;
		}
		if (!w)
			return 0;
		len -= w; buf += w; t += w;
	}
	return t;
}

static int create_snoop(char *file)
{
	struct btsnoop_hdr hdr;
	int fd, len;

	fd = open(file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	if (fd < 0)
		return fd;

	memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id));
	hdr.version = htonl(1);
	hdr.type = htonl(1002);

	len = write(fd, &hdr, BTSNOOP_HDR_SIZE);
	if (len < 0) {
		close(fd);
		return -EIO;
	}

	if (len != BTSNOOP_HDR_SIZE) {
		close(fd);
		return -1;
	}

	return fd;
}

static int write_snoop(int fd, int type, int incoming, unsigned char *buf, int len)
{
	struct btsnoop_pkt pkt;
	struct timeval tv;
	uint32_t size = len;
	uint64_t ts;
	int err;

	if (fd < 0)
		return -1;

	memset(&tv, 0, sizeof(tv));
	gettimeofday(&tv, NULL);
	ts = (tv.tv_sec - 946684800ll) * 1000000ll + tv.tv_usec;

	pkt.size = htonl(size);
	pkt.len  = pkt.size;
	pkt.flags = ntohl(incoming & 0x01);
	pkt.drops = htonl(0);
	pkt.ts = hton64(ts + 0x00E03AB44A676000ll);

	if (type == HCI_COMMAND_PKT || type == HCI_EVENT_PKT)
		pkt.flags |= ntohl(0x02);

	err = write(fd, &pkt, BTSNOOP_PKT_SIZE);
	err = write(fd, buf, size);

	return 0;
}

static struct vhci_conn *conn_get_by_bdaddr(bdaddr_t *ba)
{
	register int i;

	for (i = 0; i < VHCI_MAX_CONN; i++)
		if (!bacmp(&vconn[i]->dest, ba))
			return vconn[i];

	return NULL;
}

static void command_status(uint16_t ogf, uint16_t ocf, uint8_t status)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_cmd_status *cs;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_CMD_STATUS;
	he->plen = EVT_CMD_STATUS_SIZE;

	cs = (void *) ptr; ptr += EVT_CMD_STATUS_SIZE;

	cs->status = status;
	cs->ncmd   = 1;
	cs->opcode = htobs(cmd_opcode_pack(ogf, ocf));

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s(%d)",
						strerror(errno), errno);
}

static void command_complete(uint16_t ogf, uint16_t ocf, int plen, void *data)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_cmd_complete *cc;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_CMD_COMPLETE;
	he->plen = EVT_CMD_COMPLETE_SIZE + plen; 

	cc = (void *) ptr; ptr += EVT_CMD_COMPLETE_SIZE;

	cc->ncmd = 1;
	cc->opcode = htobs(cmd_opcode_pack(ogf, ocf));

	if (plen) {
		memcpy(ptr, data, plen);
		ptr += plen;
	}

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s(%d)",
						strerror(errno), errno);
}

static void connect_request(struct vhci_conn *conn)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_conn_request *cr;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_CONN_REQUEST;
	he->plen = EVT_CONN_REQUEST_SIZE; 

	cr = (void *) ptr; ptr += EVT_CONN_REQUEST_SIZE;

	bacpy(&cr->bdaddr, &conn->dest);
	memset(&cr->dev_class, 0, sizeof(cr->dev_class));
	cr->link_type = ACL_LINK;

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s (%d)",
						strerror(errno), errno);
}

static void connect_complete(struct vhci_conn *conn)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_conn_complete *cc;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_CONN_COMPLETE;
	he->plen = EVT_CONN_COMPLETE_SIZE; 

	cc = (void *) ptr; ptr += EVT_CONN_COMPLETE_SIZE;

	bacpy(&cc->bdaddr, &conn->dest);
	cc->status = 0x00;
	cc->handle = htobs(conn->handle);
	cc->link_type = ACL_LINK;
	cc->encr_mode = 0x00;

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s (%d)",
						strerror(errno), errno);
}

static void disconn_complete(struct vhci_conn *conn)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_disconn_complete *dc;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_DISCONN_COMPLETE;
	he->plen = EVT_DISCONN_COMPLETE_SIZE;

	dc = (void *) ptr; ptr += EVT_DISCONN_COMPLETE_SIZE;

	dc->status = 0x00;
	dc->handle = htobs(conn->handle);
	dc->reason = 0x00;

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s (%d)",
						strerror(errno), errno);

	vdev.acl_cnt = 0;
}

static void num_completed_pkts(struct vhci_conn *conn)
{
	uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf;
	evt_num_comp_pkts *np;
	hci_event_hdr *he;

	/* Packet type */
	*ptr++ = HCI_EVENT_PKT;

	/* Event header */
	he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE;

	he->evt  = EVT_NUM_COMP_PKTS;
	he->plen = EVT_NUM_COMP_PKTS_SIZE;

	np = (void *) ptr; ptr += EVT_NUM_COMP_PKTS_SIZE;
	np->num_hndl = 1;

	*((uint16_t *) ptr) = htobs(conn->handle); ptr += 2;
	*((uint16_t *) ptr) = htobs(vdev.acl_cnt); ptr += 2;

	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);

	if (write(vdev.fd, buf, ptr - buf) < 0)
		syslog(LOG_ERR, "Can't send event: %s (%d)",
						strerror(errno), errno);
}

static int scan_enable(uint8_t *data)
{
	struct sockaddr_in sa;
	GIOChannel *sk_io;
	bdaddr_t ba;
	int sk, opt;

	if (!(*data & SCAN_PAGE)) {
		if (vdev.scan) {
			g_io_channel_close(vdev.scan);
			vdev.scan = NULL;
		}
		return 0;
	}

	if (vdev.scan)
		return 0;

	if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		syslog(LOG_ERR, "Can't create socket: %s (%d)",
						strerror(errno), errno);
		return 1;
	}

	opt = 1;
	setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	baswap(&ba, &vdev.bdaddr);
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = *(uint32_t *) &ba;
	sa.sin_port = *(uint16_t *) &ba.b[4];
	if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) {
		syslog(LOG_ERR, "Can't bind socket: %s (%d)",
						strerror(errno), errno);
		goto failed;
	}

	if (listen(sk, 10)) {
		syslog(LOG_ERR, "Can't listen on socket: %s (%d)",
						strerror(errno), errno);
		goto failed;
	}

	sk_io = g_io_channel_unix_new(sk);
	g_io_add_watch(sk_io, G_IO_IN | G_IO_NVAL, io_conn_ind, NULL);
	vdev.scan = sk_io;
	return 0;

failed:
	close(sk);
	return 1;
}

static void accept_connection(uint8_t *data)
{
	accept_conn_req_cp *cp = (void *) data;
	struct vhci_conn *conn;

	if (!(conn = conn_get_by_bdaddr(&cp->bdaddr)))
		return;

	connect_complete(conn);

	g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP,
			io_acl_data, (gpointer) conn);
}

static void close_connection(struct vhci_conn *conn)
{
	syslog(LOG_INFO, "Closing connection %s handle %d",
					batostr(&conn->dest), conn->handle);

	g_io_channel_close(conn->chan);
	g_io_channel_unref(conn->chan);

	vconn[conn->handle - 1] = NULL;
	disconn_complete(conn);
	free(conn);
}

static void disconnect(uint8_t *data)
{
	disconnect_cp *cp = (void *) data;
	struct vhci_conn *conn;
	uint16_t handle;

	handle = btohs(cp->handle);

	if (handle - 1 > VHCI_MAX_CONN)
		return;

	if (!(conn = vconn[handle-1]))
		return;

	close_connection(conn);
}

static void create_connection(uint8_t *data)
{
	create_conn_cp *cp = (void *) data;
	struct vhci_link_info info;
	struct vhci_conn *conn;
	struct sockaddr_in sa;
	int h, sk, opt;
	bdaddr_t ba;

	for (h = 0; h < VHCI_MAX_CONN; h++)
		if (!vconn[h])
			goto do_connect;

	syslog(LOG_ERR, "Too many connections");
	return;

do_connect:
	if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		syslog(LOG_ERR, "Can't create socket: %s (%d)",
						strerror(errno), errno);
		return;
	}

	opt = 1;
	setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	baswap(&ba, &vdev.bdaddr);
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = INADDR_ANY;	// *(uint32_t *) &ba;
	sa.sin_port = 0;			// *(uint16_t *) &ba.b[4];
	if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) {
		syslog(LOG_ERR, "Can't bind socket: %s (%d)",
						strerror(errno), errno);
		close(sk);
		return;
	}

	baswap(&ba, &cp->bdaddr);
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = *(uint32_t *) &ba;
	sa.sin_port = *(uint16_t *) &ba.b[4];
	if (connect(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
		syslog(LOG_ERR, "Can't connect: %s (%d)",
						strerror(errno), errno);
		close(sk);
		return;
	}

	/* Send info */
	memset(&info, 0, sizeof(info));
	bacpy(&info.bdaddr, &vdev.bdaddr);
	info.link_type = ACL_LINK;
	info.role = 1;
	write_n(sk, (void *) &info, sizeof(info));

	if (!(conn = malloc(sizeof(*conn)))) {
		syslog(LOG_ERR, "Can't alloc new connection: %s (%d)",
						strerror(errno), errno);
		close(sk);
		return;
	}

	memcpy((uint8_t *) &ba, (uint8_t *) &sa.sin_addr, 4);
	memcpy((uint8_t *) &ba.b[4], (uint8_t *) &sa.sin_port, 2);
	baswap(&conn->dest, &ba);

	vconn[h] = conn;
	conn->handle = h + 1;
	conn->chan = g_io_channel_unix_new(sk);

	connect_complete(conn);
	g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP,
				io_acl_data, (gpointer) conn);
	return;
}

static void inline hci_link_control(uint16_t ocf, int plen, uint8_t *data)
{
	uint8_t status;

	const uint16_t ogf = OGF_LINK_CTL;

	switch (ocf) {
	case OCF_CREATE_CONN:
		command_status(ogf, ocf, 0x00);
		create_connection(data);
		break;

	case OCF_ACCEPT_CONN_REQ:
		command_status(ogf, ocf, 0x00);
		accept_connection(data);
		break;

	case OCF_DISCONNECT:
		command_status(ogf, ocf, 0x00);
		disconnect(data);
		break;

	default:
		status = 0x01;
		command_complete(ogf, ocf, 1, &status);
		break;
	}
}

static void inline hci_link_policy(uint16_t ocf, int plen, uint8_t *data)
{
	uint8_t status;

	const uint16_t ogf = OGF_INFO_PARAM;

	switch (ocf) {
	default:
		status = 0x01;
		command_complete(ogf, ocf, 1, &status);
		break;
	}
}

static void inline hci_host_control(uint16_t ocf, int plen, uint8_t *data)
{
	read_local_name_rp ln;
	read_class_of_dev_rp cd;
	read_inquiry_mode_rp im;
	read_ext_inquiry_response_rp ir;
	uint8_t status;

	const uint16_t ogf = OGF_HOST_CTL;

	switch (ocf) {
	case OCF_RESET:
		status = 0x00;
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_SET_EVENT_FLT:
		status = 0x00;
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_CHANGE_LOCAL_NAME:
		status = 0x00;
		memcpy(vdev.name, data, sizeof(vdev.name));
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_READ_LOCAL_NAME:
		ln.status = 0x00;
		memcpy(ln.name, vdev.name, sizeof(ln.name));
		command_complete(ogf, ocf, sizeof(ln), &ln);
		break;

	case OCF_WRITE_CONN_ACCEPT_TIMEOUT:
	case OCF_WRITE_PAGE_TIMEOUT:
		status = 0x00;
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_WRITE_SCAN_ENABLE:
		status = scan_enable(data);
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_WRITE_AUTH_ENABLE:
		status = 0x00;
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_WRITE_ENCRYPT_MODE:
		status = 0x00;
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_READ_CLASS_OF_DEV:
		cd.status = 0x00;
		memcpy(cd.dev_class, vdev.dev_class, 3);
		command_complete(ogf, ocf, sizeof(cd), &cd);
		break;

	case OCF_WRITE_CLASS_OF_DEV:
		status = 0x00;
		memcpy(vdev.dev_class, data, 3);
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_READ_INQUIRY_MODE:
		im.status = 0x00;
		im.mode = vdev.inq_mode;
		command_complete(ogf, ocf, sizeof(im), &im);
		break;

	case OCF_WRITE_INQUIRY_MODE:
		status = 0x00;
		vdev.inq_mode = data[0];
		command_complete(ogf, ocf, 1, &status);
		break;

	case OCF_READ_EXT_INQUIRY_RESPONSE:
		ir.status = 0x00;
		ir.fec = vdev.eir_fec;
		memcpy(ir.data, vdev.eir_data, 240);
		command_complete(ogf, ocf, sizeof(ir), &ir);
		break;

	case OCF_WRITE_EXT_INQUIRY_RESPONSE:
		status = 0x00;
		vdev.eir_fec = data[0];
		memcpy(vdev.eir_data, data + 1, 240);
		command_complete(ogf, ocf, 1, &status);
		break;

	default:
		status = 0x01;
		command_complete(ogf, ocf, 1, &status);
		break;
	}
}

static void inline hci_info_param(uint16_t ocf, int plen, uint8_t *data)
{
	read_local_version_rp lv;
	read_local_features_rp lf;
	read_local_ext_features_rp ef;
	read_buffer_size_rp bs;
	read_bd_addr_rp ba;
	uint8_t status;

	const uint16_t ogf = OGF_INFO_PARAM;

	switch (ocf) {
	case OCF_READ_LOCAL_VERSION:
		lv.status = 0x00;
		lv.hci_ver = 0x03;
		lv.hci_rev = htobs(0x0000);
		lv.lmp_ver = 0x03;
		lv.manufacturer = htobs(29);
		lv.lmp_subver = htobs(0x0000);
		command_complete(ogf, ocf, sizeof(lv), &lv);
		break;

	case OCF_READ_LOCAL_FEATURES:
		lf.status = 0x00;
		memcpy(lf.features, vdev.features, 8);
		command_complete(ogf, ocf, sizeof(lf), &lf);
		break;

	case OCF_READ_LOCAL_EXT_FEATURES:
		ef.status = 0x00;
		if (*data == 0) {
			ef.page_num = 0;
			ef.max_page_num = 0;
			memcpy(ef.features, vdev.features, 8);
		} else {
			ef.page_num = *data;
			ef.max_page_num = 0;
			memset(ef.features, 0, 8);
		}
		command_complete(ogf, ocf, sizeof(ef), &ef);
		break;

	case OCF_READ_BUFFER_SIZE:
		bs.status = 0x00;
		bs.acl_mtu = htobs(VHCI_ACL_MTU);
		bs.sco_mtu = 0;
		bs.acl_max_pkt = htobs(VHCI_ACL_MAX_PKT);
		bs.sco_max_pkt = htobs(0);
		command_complete(ogf, ocf, sizeof(bs), &bs);
		break;

	case OCF_READ_BD_ADDR:
		ba.status = 0x00;
		bacpy(&ba.bdaddr, &vdev.bdaddr);
		command_complete(ogf, ocf, sizeof(ba), &ba);
		break;

	default:
		status = 0x01;
		command_complete(ogf, ocf, 1, &status);
		break;
	}
}

static void hci_command(uint8_t *data)
{
	hci_command_hdr *ch;
	uint8_t *ptr = data;
	uint16_t ogf, ocf;

	ch = (hci_command_hdr *) ptr;
	ptr += HCI_COMMAND_HDR_SIZE;

	ch->opcode = btohs(ch->opcode);
	ogf = cmd_opcode_ogf(ch->opcode);
	ocf = cmd_opcode_ocf(ch->opcode);

	switch (ogf) {
	case OGF_LINK_CTL:
		hci_link_control(ocf, ch->plen, ptr);
		break;

	case OGF_LINK_POLICY:
		hci_link_policy(ocf, ch->plen, ptr);
		break;

	case OGF_HOST_CTL:
		hci_host_control(ocf, ch->plen, ptr);
		break;

	case OGF_INFO_PARAM:
		hci_info_param(ocf, ch->plen, ptr);
		break;
	}
}

static void hci_acl_data(uint8_t *data)
{
	hci_acl_hdr *ah = (void *) data;
	struct vhci_conn *conn;
	uint16_t handle;
	int fd;

	handle = acl_handle(btohs(ah->handle));

	if (handle > VHCI_MAX_CONN || !(conn = vconn[handle - 1])) {
		syslog(LOG_ERR, "Bad connection handle %d", handle);
		return;
	}

	fd = g_io_channel_unix_get_fd(conn->chan);
	if (write_n(fd, data, btohs(ah->dlen) + HCI_ACL_HDR_SIZE) < 0) {
		close_connection(conn);
		return;
	}

	if (++vdev.acl_cnt > VHCI_ACL_MAX_PKT - 1) {
		/* Send num of complete packets event */
		num_completed_pkts(conn);
		vdev.acl_cnt = 0;
	}
}

static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct vhci_conn *conn = (struct vhci_conn *) data;
	unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr;
	hci_acl_hdr *ah;
	uint16_t flags;
	int fd, err, len;

	if (cond & G_IO_NVAL) {
		g_io_channel_unref(chan);
		return FALSE;
	}

	if (cond & G_IO_HUP) {
		close_connection(conn);
		return FALSE;
	}

	fd = g_io_channel_unix_get_fd(chan);

	ptr = buf + 1;
	if (read_n(fd, ptr, HCI_ACL_HDR_SIZE) <= 0) {
		close_connection(conn);
		return FALSE;
	}

	ah = (void *) ptr;
	ptr += HCI_ACL_HDR_SIZE;

	len = btohs(ah->dlen);
	if (read_n(fd, ptr, len) <= 0) {
		close_connection(conn);
		return FALSE;
	}

	buf[0] = HCI_ACLDATA_PKT;

	flags = acl_flags(btohs(ah->handle));
	ah->handle = htobs(acl_handle_pack(conn->handle, flags));
	len += HCI_ACL_HDR_SIZE + 1;

	write_snoop(vdev.dd, HCI_ACLDATA_PKT, 1, buf, len);

	err = write(vdev.fd, buf, len);

	return TRUE;
}

static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct vhci_link_info info;
	struct vhci_conn *conn;
	struct sockaddr_in sa;
	socklen_t len;
	int sk, nsk, h;

	if (cond & G_IO_NVAL)
		return FALSE;

	sk = g_io_channel_unix_get_fd(chan);

	len = sizeof(sa);
	if ((nsk = accept(sk, (struct sockaddr *) &sa, &len)) < 0)
		return TRUE;

	if (read_n(nsk, &info, sizeof(info)) < 0) {
		syslog(LOG_ERR, "Can't read link info");
		return TRUE;
	}

	if (!(conn = malloc(sizeof(*conn)))) {
		syslog(LOG_ERR, "Can't alloc new connection");
		close(nsk);
		return TRUE;
	}

	bacpy(&conn->dest, &info.bdaddr);

	for (h = 0; h < VHCI_MAX_CONN; h++)
		if (!vconn[h])
			goto accepted;

	syslog(LOG_ERR, "Too many connections");
	free(conn);
	close(nsk);
	return TRUE;

accepted:
	vconn[h] = conn;
	conn->handle = h + 1;
	conn->chan = g_io_channel_unix_new(nsk);
	connect_request(conn);

	return TRUE;
}

static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr;
	int type;
	gsize len;
	GIOError err;

	ptr = buf;

	if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) {
		if (err == G_IO_ERROR_AGAIN)
			return TRUE;

		syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno);
		g_io_channel_unref(chan);
		g_main_loop_quit(event_loop);
		return FALSE;
	}

	type = *ptr++;

	write_snoop(vdev.dd, type, 0, buf, len);

	switch (type) {
	case HCI_COMMAND_PKT:
		hci_command(ptr);
		break;

	case HCI_ACLDATA_PKT:
		hci_acl_data(ptr);
		break;

	default:
		syslog(LOG_ERR, "Unknown packet type 0x%2.2x", type);
		break;
	}

	return TRUE;
}

static int getbdaddrbyname(char *str, bdaddr_t *ba)
{
	int i, n, len;

	len = strlen(str);

	/* Check address format */
	for (i = 0, n = 0; i < len; i++)
		if (str[i] == ':')
			n++;

	if (n == 5) {
		/* BD address */
		baswap(ba, strtoba(str));
		return 0;
	}

	if (n == 1) {
		/* IP address + port */
		struct hostent *hent;
		bdaddr_t b;
		char *ptr;

		ptr = strchr(str, ':');
		*ptr++ = 0;

		if (!(hent = gethostbyname(str))) {
			fprintf(stderr, "Can't resolve %s\n", str);
			return -2;
		}

		memcpy(&b, hent->h_addr, 4);
		*(uint16_t *) (&b.b[4]) = htons(atoi(ptr));
		baswap(ba, &b);

		return 0;
	}

	fprintf(stderr, "Invalid address format\n");

	return -1;
}

static void rewrite_bdaddr(unsigned char *buf, int len, bdaddr_t *bdaddr)
{
	hci_event_hdr *eh;
	unsigned char *ptr = buf;
	int type;

	if (!bdaddr)
		return;

	if (!bacmp(bdaddr, BDADDR_ANY))
		return;

	type = *ptr++;

	switch (type) {
	case HCI_EVENT_PKT:
		eh = (hci_event_hdr *) ptr;
		ptr += HCI_EVENT_HDR_SIZE;

		if (eh->evt == EVT_CMD_COMPLETE) {
			evt_cmd_complete *cc = (void *) ptr;

			ptr += EVT_CMD_COMPLETE_SIZE;

			if (cc->opcode == htobs(cmd_opcode_pack(OGF_INFO_PARAM,
						OCF_READ_BD_ADDR))) {
				bacpy((bdaddr_t *) (ptr + 1), bdaddr);
			}
		}
		break;
	}
}

static int run_proxy(int fd, int dev, bdaddr_t *bdaddr)
{
	unsigned char buf[HCI_MAX_FRAME_SIZE + 1];
	struct hci_dev_info di;
	struct hci_filter flt;
	struct pollfd p[2];
	int dd, err, len, need_raw;

	dd = hci_open_dev(dev);
	if (dd < 0) {
		syslog(LOG_ERR, "Can't open device hci%d: %s (%d)",
						dev, strerror(errno), errno);
		return 1;
	}

	if (hci_devinfo(dev, &di) < 0) {
		syslog(LOG_ERR, "Can't get device info for hci%d: %s (%d)",
						dev, strerror(errno), errno);
		hci_close_dev(dd);
		return 1;
	}

	need_raw = !hci_test_bit(HCI_RAW, &di.flags);

	hci_filter_clear(&flt);
	hci_filter_all_ptypes(&flt);
	hci_filter_all_events(&flt);

	if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
		syslog(LOG_ERR, "Can't set filter for hci%d: %s (%d)",
						dev, strerror(errno), errno);
		hci_close_dev(dd);
		return 1;
	}

	if (need_raw) {
		if (ioctl(dd, HCISETRAW, 1) < 0) {
			syslog(LOG_ERR, "Can't set raw mode on hci%d: %s (%d)",
						dev, strerror(errno), errno);
			hci_close_dev(dd);
			return 1;
		}
	}

	p[0].fd = fd;
	p[0].events = POLLIN;
	p[1].fd = dd;
	p[1].events = POLLIN;

	while (!__io_canceled) {
		p[0].revents = 0;
		p[1].revents = 0;
		err = poll(p, 2, 500);
		if (err < 0)
			break;
		if (!err)
			continue;

		if (p[0].revents & POLLIN) {
			len = read(fd, buf, sizeof(buf));
			if (len > 0) {
				rewrite_bdaddr(buf, len, bdaddr);
				err = write(dd, buf, len);
			}
		}

		if (p[1].revents & POLLIN) {
			len = read(dd, buf, sizeof(buf));
			if (len > 0) {
				rewrite_bdaddr(buf, len, bdaddr);
				err = write(fd, buf, len);
			}
		}
	}

	if (need_raw) {
		if (ioctl(dd, HCISETRAW, 0) < 0)
			syslog(LOG_ERR, "Can't clear raw mode on hci%d: %s (%d)",
						dev, strerror(errno), errno);
	}

	hci_close_dev(dd);

	syslog(LOG_INFO, "Exit");

	return 0;
}

static void usage(void)
{
	printf("hciemu - HCI emulator ver %s\n", VERSION);
	printf("Usage: \n");
	printf("\thciemu [-n] local_address\n");
}

static struct option main_options[] = {
	{ "device",	1, 0, 'd' },
	{ "bdaddr",	1, 0, 'b' },
	{ "snoop",	1, 0, 's' },
	{ "nodetach",	0, 0, 'n' },
	{ "help",	0, 0, 'h' },
	{ 0 }
};

int main(int argc, char *argv[])
{
	struct sigaction sa;
	GIOChannel *dev_io;
	char *device = NULL, *snoop = NULL;
	bdaddr_t bdaddr;
	int fd, dd, opt, detach = 1, dev = -1;

	bacpy(&bdaddr, BDADDR_ANY);

	while ((opt=getopt_long(argc, argv, "d:b:s:nh", main_options, NULL)) != EOF) {
		switch(opt) {
		case 'd':
			device = strdup(optarg);
			break;

		case 'b':
			str2ba(optarg, &bdaddr);
			break;

		case 's':
			snoop = strdup(optarg);
			break;

		case 'n':
			detach = 0;
			break;

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

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

	if (argc < 1) {
		usage();
		exit(1);
	}

	if (strlen(argv[0]) > 3 && !strncasecmp(argv[0], "hci", 3)) {
		dev = hci_devid(argv[0]);
		if (dev < 0) {
			perror("Invalid device");
			exit(1);
		}
	} else {
		if (getbdaddrbyname(argv[0], &vdev.bdaddr) < 0)
			exit(1);
	}

	if (detach) {
		if (daemon(0, 0)) {
			perror("Can't start daemon");
			exit(1);
		}
	}

	/* Start logging to syslog and stderr */
	openlog("hciemu", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
	syslog(LOG_INFO, "HCI emulation daemon ver %s started", VERSION);

	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);

	io_init();

	if (!device && dev >= 0)
		device = strdup(GHCI_DEV);

	/* Open and create virtual HCI device */
	if (device) {
		fd = open(device, O_RDWR);
		if (fd < 0) {
			syslog(LOG_ERR, "Can't open device %s: %s (%d)",
						device, strerror(errno), errno);
			free(device);
			exit(1);
		}
		free(device);
	} else {
		fd = open(VHCI_DEV, O_RDWR);
		if (fd < 0) {
			fd = open(VHCI_UDEV, O_RDWR);
			if (fd < 0) {
				syslog(LOG_ERR, "Can't open device %s: %s (%d)",
						VHCI_DEV, strerror(errno), errno);
				exit(1);
			}
		}
	}

	/* Create snoop file */
	if (snoop) {
		dd = create_snoop(snoop);
		if (dd < 0)
			syslog(LOG_ERR, "Can't create snoop file %s: %s (%d)",
						snoop, strerror(errno), errno);
		free(snoop);
	} else
		dd = -1;

	/* Create event loop */
	event_loop = g_main_loop_new(NULL, FALSE);

	if (dev >= 0)
		return run_proxy(fd, dev, &bdaddr);

	/* Device settings */
	vdev.features[0] = 0xff;
	vdev.features[1] = 0xff;
	vdev.features[2] = 0x8f;
	vdev.features[3] = 0xfe;
	vdev.features[4] = 0x9b;
	vdev.features[5] = 0xf9;
	vdev.features[6] = 0x01;
	vdev.features[7] = 0x80;

	memset(vdev.name, 0, sizeof(vdev.name));
	strncpy((char *) vdev.name, "BlueZ (Virtual HCI)", sizeof(vdev.name));

	vdev.dev_class[0] = 0x00;
	vdev.dev_class[1] = 0x00;
	vdev.dev_class[2] = 0x00;

	vdev.inq_mode = 0x00;
	vdev.eir_fec = 0x00;
	memset(vdev.eir_data, 0, sizeof(vdev.eir_data));

	vdev.fd = fd;
	vdev.dd = dd;

	dev_io = g_io_channel_unix_new(fd);
	g_io_add_watch(dev_io, G_IO_IN, io_hci_data, NULL);

	setpriority(PRIO_PROCESS, 0, -19);

	/* Start event processor */
	g_main_loop_run(event_loop);

	close(fd);

	if (dd >= 0)
		close(dd);

	syslog(LOG_INFO, "Exit");

	return 0;
}
