/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <getopt.h>

#include <sys/socket.h>
#include <sys/poll.h>

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

#include "dund.h"
#include "lib.h"

volatile sig_atomic_t __io_canceled;

/* MS dialup networking support (i.e. CLIENT / CLIENTSERVER thing) */
static int  msdun = 0;

static char *pppd = "/usr/sbin/pppd";
static char *pppd_opts[DUN_MAX_PPP_OPTS] =
	{
		/* First 3 are reserved */
		"", "", "",
		"noauth",
		"noipdefault",
		NULL
	};

static int  detach = 1;
static int  persist;
static int  use_sdp = 1;
static int  encrypt;
static int  master;
static int  search_duration = 10;
static uint use_cache;

static int  channel;

static struct {
	uint     valid;
	char     dst[40];
	bdaddr_t bdaddr;
	int      channel;
} cache;

static bdaddr_t src_addr = *BDADDR_ANY;
static int src_dev = -1;

volatile int terminate;

enum {
	NONE,
	SHOW,
	LISTEN,
	CONNECT,
	KILL
} modes;

static int do_listen(void)
{
	struct sockaddr_rc sa;
	int sk;

	if (!channel)
		channel = DUN_DEFAULT_CHANNEL;

	if (use_sdp)
		dun_sdp_register(channel);

	/* Create RFCOMM socket */
	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	if (sk < 0) {
		syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)",
				strerror(errno), errno);
		return -1;
	}

	sa.rc_family  = AF_BLUETOOTH;
	sa.rc_channel = channel;
	sa.rc_bdaddr  = src_addr;

	if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) {
		syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno);
		return -1;
	}

	listen(sk, 10);

	while (!terminate) {
		int  alen = sizeof(sa), nsk;
		char ba[40];
		char ch[10];

		nsk = accept(sk, (struct sockaddr *) &sa, &alen);
		if (nsk < 0) {
			syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno);
			continue;
		}

		switch (fork()) {
		case 0:
			break;
		case -1:
			syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno);
		default:
			close(nsk);
			continue;
		}

		if (msdun && ms_dun(nsk, 1, msdun) < 0) {
			syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno);
			exit(0);
		}

		ba2str(&sa.rc_bdaddr, ba);
		sprintf(ch, "%d", channel);

		/* Setup environment */
		setenv("DUN_BDADDR",  ba, 1);
		setenv("DUN_CHANNEL", ch, 1);

		if (!dun_open_connection(nsk, pppd, pppd_opts, 0))
			syslog(LOG_INFO, "New connection from %s", ba);

		close(nsk);
		exit(0);
	}

	if (use_sdp)
		dun_sdp_unregister();
	return 0;
}

/* Connect and initiate RFCOMM session
 * Returns:
 *   -1 - critical error (exit persist mode)
 *   1  - non critical error
 *   0  - success
 */
static int create_connection(char *dst, bdaddr_t *bdaddr)
{
	struct sockaddr_rc sa;
	int sk, err = 0, ch;

	if (use_cache && cache.valid && cache.channel) {
		/* Use cached channel */
		ch = cache.channel;

	} else if (!channel) {
		syslog(LOG_INFO, "Searching for %s on %s", "LAP", dst);

		if (dun_sdp_search(&src_addr, bdaddr, &ch) <= 0)
			return 0;
	} else
		ch = channel;
	
	syslog(LOG_INFO, "Connecting to %s channel %d", dst, ch);

	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	if (sk < 0) {
		syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)",
		     strerror(errno), errno);
		return -1;
	}

	sa.rc_family  = AF_BLUETOOTH;
	sa.rc_channel = 0;
	sa.rc_bdaddr  = src_addr;

	if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)))
		syslog(LOG_ERR, "Bind failed. %s(%d)", 
			strerror(errno), errno);

	sa.rc_channel = ch;
	sa.rc_bdaddr  = *bdaddr;

	if (!connect(sk, (struct sockaddr *) &sa, sizeof(sa)) ) {
		syslog(LOG_INFO, "Connection established");

		if (msdun && ms_dun(sk, 0, msdun) < 0) {
			syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno);
			err = 1;
			goto out;
		}

		if (!dun_open_connection(sk, pppd, pppd_opts, (persist > 0)))
			err = 0;
		else
			err = 1;
	} else {
		syslog(LOG_ERR, "Connect to %s failed. %s(%d)",
				dst, strerror(errno), errno);
		err = 1;
	}

out:
	if (use_cache) {
		if (!err) {
			/* Succesesful connection, validate cache */
			strcpy(cache.dst, dst);
			bacpy(&cache.bdaddr, bdaddr);
			cache.channel = ch;
			cache.valid   = use_cache;
		} else {
			cache.channel = 0;
			cache.valid--;
		}
	}

	close(sk);
	return err;
}

/* Search and connect
 * Returns:
 *   -1 - critical error (exit persist mode)
 *   1  - non critical error
 *   0  - success
 */
static int do_connect(void)
{
	inquiry_info *ii;
	int reconnect = 0;
	int i, n, r = 0;

	do {
		if (reconnect)
			sleep(persist);
		reconnect = 1;

		if (cache.valid) {
			/* Use cached bdaddr */
			r = create_connection(cache.dst, &cache.bdaddr);
			if (r < 0) {
				terminate = 1;
				break;
			}
			continue;
		}

		syslog(LOG_INFO, "Inquiring");

		/* FIXME: Should we use non general LAP here ? */

		ii = NULL;
		n  = hci_inquiry(src_dev, search_duration, 10, NULL, &ii, 0);
		if (n < 0) {
			syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno);
			continue;
		}

		for (i = 0; i < n; i++) {
			char dst[40];
			ba2str(&ii[i].bdaddr, dst);
			
			r = create_connection(dst, &ii[i].bdaddr);
			if (r < 0) {
				terminate = 1;
				break;
			}
		}
		free(ii);
	} while (!terminate && persist);

	return r;
}

static void do_show(void)
{
	dun_show_connections();
}

static void do_kill(char *dst)
{
	if (dst) {
		bdaddr_t ba;
		str2ba(dst, &ba);
		dun_kill_connection((void *) &ba);
	} else
		dun_kill_all_connections();
}

void sig_hup(int sig)
{
	return;
}

void sig_term(int sig)
{
	io_cancel();
	terminate = 1;
}

static struct option main_lopts[] = {
	{ "help",     0, 0, 'h' },
	{ "listen",   0, 0, 's' },
	{ "connect",  1, 0, 'c' },
	{ "search",   2, 0, 'Q' },
	{ "kill",     1, 0, 'k' },
	{ "killall",  0, 0, 'K' },
	{ "channel",  1, 0, 'P' },
	{ "source",   1, 0, 'S' },
	{ "nosdp",    0, 0, 'D' },
	{ "list",     0, 0, 'l' },
	{ "show",     0, 0, 'l' },
	{ "nodetach", 0, 0, 'n' },
	{ "persist",  2, 0, 'p' },
	{ "encrypt",  0, 0, 'E' },
	{ "master",   0, 0, 'M' },
	{ "cache",    0, 0, 'C' },
	{ "pppd",     1, 0, 'd' },
	{ "msdun",    2, 0, 'X' },
	{ 0, 0, 0, 0 }
};

static char main_sopts[] = "hsc:k:Kr:S:lnp::DQ::EMP:C::P:X";

static char main_help[] = 
	"LAP (LAN Access over PPP) daemon version " VERSION " \n"
	"Usage:\n"
	"\tdund <options> [pppd options]\n"
	"Options:\n"
	"\t--show --list -l          Show active LAP connections\n"
	"\t--listen -s               Listen for LAP connections\n"
	"\t--connect -c <bdaddr>     Create LAP connection\n"
	"\t--search -Q[duration]     Search and connect\n"
	"\t--kill -k <bdaddr>        Kill LAP connection\n"
	"\t--killall -K              Kill all LAP connections\n"
	"\t--channel -P <channel>    RFCOMM channel\n"
	"\t--source -S <bdaddr>      Source bdaddr\n"
	"\t--nosdp -D                Disable SDP\n"
	"\t--nodetach -n             Do not become a daemon\n"
	"\t--persist -p[interval]    Persist mode\n"
	"\t--pppd -d <pppd>          Location of the PPP daemon (pppd)\n"
	"\t--msdun -X[timeo]         Enable Microsoft dialup networking support\n"
	"\t--cache -C[valid]         Enable addess cache\n";

int main(int argc, char **argv)
{
	char *dst = NULL, *src = NULL;
	struct sigaction sa;
	int mode = NONE;
	int opt;

	while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) {
		switch(opt) {
		case 'l':
			mode = SHOW;
			detach = 0;
			break;

		case 's':
			mode = LISTEN;
			break;

		case 'c':
			mode = CONNECT;
			dst  = strdup(optarg);
			break;

		case 'Q':
			mode = CONNECT;
			dst  = NULL;
			if (optarg)
				search_duration = atoi(optarg);
			break;

		case 'k':
			mode = KILL;
			detach = 0;
			dst  = strdup(optarg);
			break;

		case 'K':
			mode = KILL;
			detach = 0;
			dst  = NULL;
			break;

		case 'P':
			channel = atoi(optarg);
			break;

		case 'S':
			src = strdup(optarg);
			break;

		case 'D':
			use_sdp = 0;
			break;

		case 'E':
			encrypt = 1;
			break;

		case 'M':
			master = 1;
			break;

		case 'n':
			detach = 0;
			break;

		case 'p':
			if (optarg)
				persist = atoi(optarg);
			else
				persist = 5;
			break;

		case 'C':
			if (optarg)
				use_cache = atoi(optarg);
			else
				use_cache = 2;
			break;

		case 'd':
			pppd  = strdup(optarg);
			break;

		case 'X':
			if (optarg)
				msdun = atoi(optarg);
			else
				msdun = 10;
			break;

		case 'h':
		default:
			printf(main_help);
			exit(0);
		}
	}

	argc -= optind;
	argv += optind;

	/* The rest is pppd options */
	if (argc > 0) {
		for (opt = 3; argc && opt < DUN_MAX_PPP_OPTS; argc--, opt++)
			pppd_opts[opt] = *argv++;
		pppd_opts[opt] = NULL;
	}

	io_init();

	if (dun_init())
		return -1;

	/* Check non daemon modes first */
	switch (mode) {
	case SHOW:
		do_show();
		return 0;

	case KILL:
		do_kill(dst);
		return 0;

	case NONE:
		printf(main_help);
		return 0;
	}

	/* Initialize signals */
	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);

	if (detach) {
		int fd;

		if (fork()) exit(0);

		/* Direct stdin,stdout,stderr to '/dev/null' */
		fd = open("/dev/null", O_RDWR);
		dup2(fd, 0); dup2(fd, 1); dup2(fd, 2);
		close(fd);
		
		setsid();
		chdir("/");
	}

	openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
	syslog(LOG_INFO, "Bluetooth DUN daemon");

	if (src) {
		src_dev = hci_devid(src);
		if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) {
			syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno);
			return -1;
		}
	}

	if (dst) {
		strncpy(cache.dst, dst, sizeof(cache.dst) - 1);
		str2ba(dst, &cache.bdaddr);

		/* Disable cache invalidation */
		use_cache = cache.valid = ~0;
	}

	switch (mode) {
	case CONNECT:
		do_connect();
		break;

	case LISTEN:
		do_listen();
		break;
	}

	return 0;
}
