/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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 <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#if defined(ANDROID)
#include <sys/capability.h>
#endif

#include "lib/bluetooth.h"
#include "lib/hci.h"
#include "lib/mgmt.h"

#include "src/shared/mainloop.h"
#include "src/shared/btsnoop.h"
#include "src/log.h"

#define DEFAULT_SNOOP_FILE "/sdcard/btsnoop_hci.log"

static struct btsnoop *snoop = NULL;
static uint8_t monitor_buf[BTSNOOP_MAX_PACKET_SIZE];
static int monitor_fd = -1;

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

static uint32_t get_flags_from_opcode(uint16_t opcode)
{
	switch (opcode) {
	case BTSNOOP_OPCODE_NEW_INDEX:
	case BTSNOOP_OPCODE_DEL_INDEX:
		break;
	case BTSNOOP_OPCODE_COMMAND_PKT:
		return 0x02;
	case BTSNOOP_OPCODE_EVENT_PKT:
		return 0x03;
	case BTSNOOP_OPCODE_ACL_TX_PKT:
		return 0x00;
	case BTSNOOP_OPCODE_ACL_RX_PKT:
		return 0x01;
	case BTSNOOP_OPCODE_SCO_TX_PKT:
	case BTSNOOP_OPCODE_SCO_RX_PKT:
		break;
	case BTSNOOP_OPCODE_OPEN_INDEX:
	case BTSNOOP_OPCODE_CLOSE_INDEX:
		break;
	}

	return 0xff;
}

static void data_callback(int fd, uint32_t events, void *user_data)
{
	unsigned char control[32];
	struct mgmt_hdr hdr;
	struct msghdr msg;
	struct iovec iov[2];

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

	iov[0].iov_base = &hdr;
	iov[0].iov_len = MGMT_HDR_SIZE;
	iov[1].iov_base = monitor_buf;
	iov[1].iov_len = sizeof(monitor_buf);

	memset(&msg, 0, sizeof(msg));
	msg.msg_iov = iov;
	msg.msg_iovlen = 2;
	msg.msg_control = control;
	msg.msg_controllen = sizeof(control);

	while (true) {
		struct cmsghdr *cmsg;
		struct timeval *tv = NULL;
		struct timeval ctv;
		uint16_t opcode, index, pktlen;
		uint32_t flags;
		ssize_t len;

		len = recvmsg(monitor_fd, &msg, MSG_DONTWAIT);
		if (len < 0)
			break;

		if (len < MGMT_HDR_SIZE)
			break;

		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
					cmsg = CMSG_NXTHDR(&msg, cmsg)) {
			if (cmsg->cmsg_level != SOL_SOCKET)
				continue;

			if (cmsg->cmsg_type == SCM_TIMESTAMP) {
				memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
				tv = &ctv;
			}
		}

		opcode = btohs(hdr.opcode);
		index  = btohs(hdr.index);
		pktlen = btohs(hdr.len);

		if (index)
			continue;

		flags = get_flags_from_opcode(opcode);
		if (flags != 0xff)
			btsnoop_write(snoop, tv, flags, 0, monitor_buf, pktlen);
	}
}

static int open_monitor(const char *path)
{
	struct sockaddr_hci addr;
	int opt = 1;

	snoop = btsnoop_create(path, 0, 0, BTSNOOP_FORMAT_HCI);
	if (!snoop)
		return -1;

	monitor_fd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
	if (monitor_fd < 0)
		goto failed;

	memset(&addr, 0, sizeof(addr));
	addr.hci_family = AF_BLUETOOTH;
	addr.hci_dev = HCI_DEV_NONE;
	addr.hci_channel = HCI_CHANNEL_MONITOR;

	if (bind(monitor_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
		goto failed_close;

	if (setsockopt(monitor_fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))
									< 0)
		goto failed_close;

	mainloop_add_fd(monitor_fd, EPOLLIN, data_callback, NULL, NULL);

	return 0;

failed_close:
	close(monitor_fd);
	monitor_fd = -1;

failed:
	btsnoop_unref(snoop);
	snoop = NULL;

	return -1;
}

static void close_monitor(void)
{
	btsnoop_unref(snoop);
	snoop = NULL;

	close(monitor_fd);
	monitor_fd = -1;
}

static void set_capabilities(void)
{
#if defined(ANDROID)
	struct __user_cap_header_struct header;
	struct __user_cap_data_struct cap;

	header.version = _LINUX_CAPABILITY_VERSION;
	header.pid = 0;

	/*
	 * CAP_NET_RAW: for snooping
	 * CAP_DAC_READ_SEARCH: override path search permissions
	 */
	cap.effective = cap.permitted =
		CAP_TO_MASK(CAP_NET_RAW) |
		CAP_TO_MASK(CAP_DAC_READ_SEARCH);
	cap.inheritable = 0;

	/* TODO: Move to cap_set_proc once bionic support it */
	if (capset(&header, &cap) < 0)
		exit(EXIT_FAILURE);
#endif
}

int main(int argc, char *argv[])
{
	const char *path;
	sigset_t mask;

	__btd_log_init(NULL, 0);

	DBG("");

	set_capabilities();

	if (argc > 1)
		path = argv[1];
	else
		path = DEFAULT_SNOOP_FILE;

	mainloop_init();

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

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

	if (!strcmp(DEFAULT_SNOOP_FILE, path))
		rename(DEFAULT_SNOOP_FILE, DEFAULT_SNOOP_FILE ".old");

	if (open_monitor(path) < 0) {
		error("bluetoothd_snoop: start failed");
		return EXIT_FAILURE;
	}

	info("bluetoothd_snoop: started");

	mainloop_run();

	close_monitor();

	info("bluetoothd_snoop: stopped");

	__btd_log_cleanup();

	return EXIT_SUCCESS;
}
