/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2001  Qualcomm Incorporated
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-2007  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 <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>

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

#include <glib.h>

#include "notify.h"

#include "hcid.h"
#include "sdpd.h"
#include "dbus-common.h"
#include "dbus-service.h"
#include "dbus-database.h"
#include "dbus-hci.h"

struct hcid_opts hcid;
struct device_opts default_device;
struct device_opts *parser_device;
static struct device_list *device_list = NULL;
static int child_pipe[2];

static inline void init_device_defaults(struct device_opts *device_opts)
{
	memset(device_opts, 0, sizeof(*device_opts));
	device_opts->scan = SCAN_PAGE;
	device_opts->name = g_strdup("BlueZ");
	device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT;
}

struct device_opts *alloc_device_opts(char *ref)
{
	struct device_list *device;

	device = g_try_new(struct device_list, 1);
	if (!device) {
		info("Can't allocate devlist opts buffer: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	device->ref = g_strdup(ref);
	device->next = device_list;
	device_list = device;

	memcpy(&device->opts, &default_device, sizeof(struct device_opts));
	device->opts.name = g_strdup(default_device.name);

	return &device->opts;
}

static void free_device_opts(void)
{
	struct device_list *device, *next;

	g_free(default_device.name);

	for (device = device_list; device; device = next) {
		g_free(device->ref);
		g_free(device->opts.name);
		next = device->next;
		g_free(device);
	}

	device_list = NULL;
}

static inline struct device_opts *find_device_opts(char *ref)
{
	struct device_list *device;

	for (device = device_list; device; device = device->next)
		if (!strcmp(ref, device->ref))
			return &device->opts;

	return NULL;
}

static struct device_opts *get_device_opts(int hdev)
{
	struct device_opts *device_opts = NULL;
	struct hci_dev_info di;

	/* First try to get BD_ADDR based settings ... */
	if (hci_devinfo(hdev, &di) == 0) {
		char addr[18];
		ba2str(&di.bdaddr, addr);
		device_opts = find_device_opts(addr);
	}

	/* ... then try HCI based settings ... */
	if (!device_opts) {
		char ref[8];
		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);
		device_opts = find_device_opts(ref);
	}

	/* ... and last use the default settings. */
	if (!device_opts)
		device_opts = &default_device;

	return device_opts;
}

uint8_t get_startup_mode(int hdev)
{
	struct device_opts *device_opts = NULL;
	struct hci_dev_info di;
	char addr[18];
	int sock;

	if (hdev < 0)
		return SCAN_DISABLED;

	sock = hci_open_dev(hdev);
	if (sock < 0)
		goto no_address;

	if (!hci_devinfo(hdev, &di) < 0) {
		close(sock);
		goto no_address;
	}

	close(sock);

	ba2str(&di.bdaddr, addr);
	device_opts = find_device_opts(addr);

no_address:
	if (!device_opts) {
		char ref[8];
		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);
		device_opts = find_device_opts(ref);
	}

	if (!device_opts)
		device_opts = &default_device;

	return device_opts->scan;
}

int get_discoverable_timeout(int hdev)
{
	struct device_opts *device_opts = NULL;
	struct hci_dev_info di;
	char addr[18];
	int sock, timeout;

	if (hdev < 0)
		return HCID_DEFAULT_DISCOVERABLE_TIMEOUT;

	sock = hci_open_dev(hdev);
	if (sock < 0)
		goto no_address;

	if (!hci_devinfo(hdev, &di) < 0) {
		close(sock);
		goto no_address;
	}

	close(sock);

	if (read_discoverable_timeout(&di.bdaddr, &timeout) == 0)
		return timeout;

	ba2str(&di.bdaddr, addr);
	device_opts = find_device_opts(addr);

no_address:
	if (!device_opts) {
		char ref[8];
		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);
		device_opts = find_device_opts(ref);
	}

	if (!device_opts)
		device_opts = &default_device;

	return device_opts->discovto;
}

/* 
 * Device name expansion 
 *   %d - device id
 */
static char *expand_name(char *dst, int size, char *str, int dev_id)
{
	register int sp, np, olen;
	char *opt, buf[10];

	if (!str && !dst)
		return NULL;

	sp = np = 0;
	while (np < size - 1 && str[sp]) {
		switch (str[sp]) {
		case '%':
			opt = NULL;

			switch (str[sp+1]) {
			case 'd':
				sprintf(buf, "%d", dev_id);
				opt = buf;
				break;

			case 'h':
				opt = hcid.host_name;
				break;

			case '%':
				dst[np++] = str[sp++];
				/* fall through */
			default:
				sp++;
				continue;
			}

			if (opt) {
				/* substitute */
				olen = strlen(opt);
				if (np + olen < size - 1)
					memcpy(dst + np, opt, olen);
				np += olen;
			}
			sp += 2;
			continue;

		case '\\':
			sp++;
			/* fall through */
		default:
			dst[np++] = str[sp++];
			break;
		}
	}
	dst[np] = '\0';
	return dst;
}

static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data)
{
	int status, fd = g_io_channel_unix_get_fd(io);
	pid_t child_pid;
	
	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) {
		error("child_exit: unable to read child pid from pipe");
		return TRUE;
	}

	if (waitpid(child_pid, &status, 0) != child_pid)
		error("waitpid(%d) failed", child_pid);
	else
		debug("child %d exited", child_pid);

	return TRUE;
}

static void at_child_exit(void)
{
	pid_t pid = getpid();

	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid))
		error("unable to write to child pipe");
}

static void configure_device(int dev_id)
{
	struct device_opts *device_opts;
	struct hci_dev_req dr;
	struct hci_dev_info di;
	char mode[14];
	int dd;

	device_opts = get_device_opts(dev_id);

	if (hci_devinfo(dev_id, &di) < 0)
		return;

	if (hci_test_bit(HCI_RAW, &di.flags))
		return;

	/* Set default discoverable timeout if not set */
	if (!(device_opts->flags & (1 << HCID_SET_DISCOVTO)))
		device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT;

	/* Set scan mode */
	if (read_device_mode(&di.bdaddr, mode, sizeof(mode)) == 0) {
		if (!strcmp(mode, MODE_OFF) && hcid.offmode == HCID_OFFMODE_NOSCAN)
			device_opts->scan = SCAN_DISABLED;
		else if (!strcmp(mode, MODE_CONNECTABLE))
			device_opts->scan = SCAN_PAGE;
		else if (!strcmp(mode, MODE_DISCOVERABLE)) {
			/* Set discoverable only if timeout is 0 */
			if (!get_discoverable_timeout(dev_id))
				device_opts->scan = SCAN_PAGE | SCAN_INQUIRY;
			else
				device_opts->scan = SCAN_PAGE;
		}
	}

	/* Do configuration in the separate process */
	switch (fork()) {
		case 0:
			atexit(at_child_exit);
			break;
		case -1:
			error("Fork failed. Can't init device hci%d: %s (%d)",
						dev_id, strerror(errno), errno);
		default:
			return;
	}

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		error("Can't open device hci%d: %s (%d)",
						dev_id, strerror(errno), errno);
		exit(1);
	}

	memset(&dr, 0, sizeof(dr));
	dr.dev_id = dev_id;

	/* Set packet type */
	if ((device_opts->flags & (1 << HCID_SET_PTYPE))) {
		dr.dev_opt = device_opts->pkt_type;
		if (ioctl(dd, HCISETPTYPE, (unsigned long) &dr) < 0) {
			error("Can't set packet type on hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		}
	}

	/* Set link mode */
	if ((device_opts->flags & (1 << HCID_SET_LM))) {
		dr.dev_opt = device_opts->link_mode;
		if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) {
			error("Can't set link mode on hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		}
	}

	/* Set link policy */
	if ((device_opts->flags & (1 << HCID_SET_LP))) {
		dr.dev_opt = device_opts->link_policy;
		if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0) {
			error("Can't set link policy on hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		}
	}

	/* Set device name */
	if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) {
		change_local_name_cp cp;
		write_ext_inquiry_response_cp ip;
		char name[249];
		uint8_t len;

		memset(name, 0, sizeof(name));
		if (read_local_name(&di.bdaddr, name) < 0) {
			memset(cp.name, 0, sizeof(cp.name));
			expand_name((char *) cp.name, sizeof(cp.name),
						device_opts->name, dev_id);
		} else
			memcpy(cp.name, name, sizeof(cp.name));

		ip.fec = 0x00;
		memset(ip.data, 0, sizeof(ip.data));
		len = strlen((char *) cp.name);
		if (len > 48) {
			len = 48;
			ip.data[1] = 0x08;
		} else
			ip.data[1] = 0x09;
		ip.data[0] = len + 1;
		memcpy(ip.data + 2, cp.name, len);

		hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
					CHANGE_LOCAL_NAME_CP_SIZE, &cp);

		if (di.features[6] & LMP_EXT_INQ)
			hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_EXT_INQUIRY_RESPONSE,
					WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &ip);
	}

	/* Set device class */
	if ((device_opts->flags & (1 << HCID_SET_CLASS))) {
		write_class_of_dev_cp cp;
		uint32_t class;
		uint8_t cls[3];

		if (read_local_class(&di.bdaddr, cls) < 0) {
			class = htobl(device_opts->class);
			memcpy(cp.dev_class, &class, 3);
		} else
			memcpy(cp.dev_class, cls, 3);

		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
					WRITE_CLASS_OF_DEV_CP_SIZE, &cp);
	}

	/* Set page timeout */
	if ((device_opts->flags & (1 << HCID_SET_PAGETO))) {
		write_page_timeout_cp cp;

		cp.timeout = htobs(device_opts->pageto);
		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT,
					WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
	}

	/* Set voice setting */
	if ((device_opts->flags & (1 << HCID_SET_VOICE))) {
		write_voice_setting_cp cp;

		cp.voice_setting = htobl(device_opts->voice);
		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING,
					WRITE_VOICE_SETTING_CP_SIZE, &cp);
	}

	exit(0);
}

static void init_device(int dev_id)
{
	struct hci_dev_info di;
	int dd;

	/* Do initialization in the separate process */
	switch (fork()) {
		case 0:
			atexit(at_child_exit);
			break;
		case -1:
			error("Fork failed. Can't init device hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		default:
			return;
	}

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		error("Can't open device hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		exit(1);
	}

	/* Start HCI device */
	if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
		error("Can't init device hci%d: %s (%d)",
					dev_id, strerror(errno), errno);
		exit(1);
	}

	if (hci_devinfo(dev_id, &di) < 0)
		exit(1);

	if (hci_test_bit(HCI_RAW, &di.flags))
		exit(0);

	if (hcid.offmode == HCID_OFFMODE_DEVDOWN) {
		char mode[16];

		if (read_device_mode(&di.bdaddr, mode, sizeof(mode)) == 0 &&
						strcmp(mode, MODE_OFF) == 0) {
			ioctl(dd, HCIDEVDOWN, dev_id);
			exit(0);
		}
	}

	hci_close_dev(dd);

	exit(0);
}

static void device_devreg_setup(int dev_id)
{
	if (hcid.auto_init)
		init_device(dev_id);
	hcid_dbus_register_device(dev_id);
}

static void device_devup_setup(int dev_id)
{
	add_device(dev_id);
	if (hcid.auto_init)
		configure_device(dev_id);
	if (hcid.security)
		start_security_manager(dev_id);
	start_device(dev_id);
	hcid_dbus_start_device(dev_id);
}

static void init_all_devices(int ctl)
{
	struct hci_dev_list_req *dl;
	struct hci_dev_req *dr;
	int i;

	dl = g_try_malloc0(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t));
	if (!dl) {
		info("Can't allocate devlist buffer: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	dl->dev_num = HCI_MAX_DEV;
	dr = dl->dev_req;

	if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {
		info("Can't get device list: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	for (i = 0; i < dl->dev_num; i++, dr++) {
		info("HCI dev %d registered", dr->dev_id);
		device_devreg_setup(dr->dev_id);
		if (hci_test_bit(HCI_UP, &dr->dev_opt)) {
			info("HCI dev %d already up", dr->dev_id);
			device_devup_setup(dr->dev_id);
		}
	}

	g_free(dl);
}

static void init_defaults(void)
{
	hcid.auto_init = 1;
	hcid.security  = HCID_SEC_AUTO;

	init_device_defaults(&default_device);
}

static inline void device_event(GIOChannel *chan, evt_stack_internal *si)
{
	evt_si_device *sd = (void *) &si->data;

	switch (sd->event) {
	case HCI_DEV_REG:
		info("HCI dev %d registered", sd->dev_id);
		device_devreg_setup(sd->dev_id);
		break;

	case HCI_DEV_UNREG:
		info("HCI dev %d unregistered", sd->dev_id);
		hcid_dbus_unregister_device(sd->dev_id);
		remove_device(sd->dev_id);
		break;

	case HCI_DEV_UP:
		info("HCI dev %d up", sd->dev_id);
		device_devup_setup(sd->dev_id);
		break;

	case HCI_DEV_DOWN:
		info("HCI dev %d down", sd->dev_id);
		hcid_dbus_stop_device(sd->dev_id);
		if (hcid.security)
			stop_security_manager(sd->dev_id);
		stop_device(sd->dev_id);
		break;
	}
}

static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr;
	evt_stack_internal *si;
	hci_event_hdr *eh;
	int type;
	size_t 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;

		error("Read from control socket failed: %s (%d)",
							strerror(errno), errno);
		return FALSE;
	}

	type = *ptr++;

	if (type != HCI_EVENT_PKT)
		return TRUE;

	eh = (hci_event_hdr *) ptr;
	if (eh->evt != EVT_STACK_INTERNAL)
		return TRUE;

	ptr += HCI_EVENT_HDR_SIZE;

	si = (evt_stack_internal *) ptr;
	switch (si->type) {
	case EVT_SI_DEVICE:
		device_event(chan, si);
		break;
	}

	return TRUE;
}

static GMainLoop *event_loop;

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

static void sig_hup(int sig)
{
	info("Reloading config file");

	free_device_opts();

	init_defaults();

	if (read_config(hcid.config_file) < 0)
		error("Config reload failed");

	init_security_data();

	init_all_devices(hcid.sock);
}

static void sig_debug(int sig)
{
	toggle_debug();
}

static void usage(void)
{
	printf("hcid - HCI daemon ver %s\n", VERSION);
	printf("Usage: \n");
	printf("\thcid [-n] [-d] [-s] [-f config file]\n");
}

int main(int argc, char *argv[])
{
	struct sockaddr_hci addr;
	struct hci_filter flt;
	struct sigaction sa;
	GIOChannel *ctl_io, *child_io;
	int opt, daemonize = 1, debug = 0, sdp = 0, experimental = 0;

	/* Default HCId settings */
	memset(&hcid, 0, sizeof(hcid));
	hcid.auto_init   = 1;
	hcid.config_file = HCID_CONFIG_FILE;
	hcid.security    = HCID_SEC_AUTO;
	hcid.pairing     = HCID_PAIRING_MULTI;
	hcid.offmode     = HCID_OFFMODE_NOSCAN;

	if (gethostname(hcid.host_name, sizeof(hcid.host_name) - 1) < 0)
		strcpy(hcid.host_name, "noname");

	strcpy((char *) hcid.pin_code, "BlueZ");
	hcid.pin_len = 5;

	init_defaults();

	while ((opt = getopt(argc, argv, "ndsxf:")) != EOF) {
		switch (opt) {
		case 'n':
			daemonize = 0;
			break;

		case 'd':
			debug = 1;
			break;

		case 's':
			sdp = 1;
			break;

		case 'x':
			experimental = 1;
			break;

		case 'f':
			hcid.config_file = g_strdup(optarg);
			break;

		default:
			usage();
			exit(1);
		}
	}

	if (daemonize && daemon(0, 0)) {
		error("Can't daemonize: %s (%d)", strerror(errno), errno);
		exit(1);
	}

	umask(0077);

	start_logging("hcid", "Bluetooth HCI daemon");

	memset(&sa, 0, sizeof(sa));
	sa.sa_flags = SA_NOCLDSTOP;
	sa.sa_handler = sig_term;
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT,  &sa, NULL);
	sa.sa_handler = sig_hup;
	sigaction(SIGHUP, &sa, NULL);

	sa.sa_handler = sig_debug;
	sigaction(SIGUSR2, &sa, NULL);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, NULL);

	if (debug) {
		info("Enabling debug information");
		enable_debug();
	}

	/* Create and bind HCI socket */
	if ((hcid.sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
		error("Can't open HCI socket: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	/* Set filter */
	hci_filter_clear(&flt);
	hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
	hci_filter_set_event(EVT_STACK_INTERNAL, &flt);
	if (setsockopt(hcid.sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
		error("Can't set filter: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	addr.hci_family = AF_BLUETOOTH;
	addr.hci_dev = HCI_DEV_NONE;
	if (bind(hcid.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		error("Can't bind HCI socket: %s (%d)",
							strerror(errno), errno);
		exit(1);
	}

	if (read_config(hcid.config_file) < 0)
		error("Config load failed");

	if (pipe(child_pipe) < 0) {
		error("pipe(): %s (%d)", strerror(errno), errno);
		exit(1);
	}

	child_io = g_io_channel_unix_new(child_pipe[0]);
	g_io_channel_set_close_on_unref(child_io, TRUE);
	g_io_add_watch(child_io,
			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
			child_exit, NULL);
	g_io_channel_unref(child_io);

	init_devices();

	if (hcid_dbus_init() < 0) {
		error("Unable to get on D-Bus");
		exit(1);
	}

	if (experimental)
		hcid_dbus_set_experimental();

	init_security_data();

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

	ctl_io = g_io_channel_unix_new(hcid.sock);
	g_io_channel_set_close_on_unref(ctl_io, TRUE);

	g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL);

	g_io_channel_unref(ctl_io);

	/* Initialize already connected devices */
	init_all_devices(hcid.sock);

	if (sdp) {
		set_sdp_server_enable();
		start_sdp_server(0, hcid.deviceid, SDP_SERVER_COMPAT);
	}

	notify_init();

	init_services(CONFIGDIR);

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

	if (sdp)
		stop_sdp_server();

	free_device_opts();

	hcid_dbus_exit();

	notify_close();

	cleanup_sdp_session();

	g_main_loop_unref(event_loop);

	info("Exit");

	stop_logging();

	return 0;
}
