/*
 *
 *  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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <dirent.h>
#include <ctype.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include <netinet/in.h>

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

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

#define PROC_BASE  "/proc"

static int for_each_port(int (*func)(struct rfcomm_dev_info *, unsigned long), unsigned long arg)
{
	struct rfcomm_dev_list_req *dl;
	struct rfcomm_dev_info *di;
	long r = 0;
	int  sk, i;

	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
	if (sk < 0 ) {
		perror("Can't open RFCOMM control socket");
		exit(1);
	}

	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di));
	if (!dl) {
		perror("Can't allocate request memory");
		close(sk);
		exit(1);
	}

	dl->dev_num = RFCOMM_MAX_DEV;
	di = dl->dev_info;

	if (ioctl(sk, RFCOMMGETDEVLIST, (void *) dl) < 0) {
		perror("Can't get device list");
		exit(1);
	}

	for (i = 0; i < dl->dev_num; i++) {
		r = func(di + i, arg);
		if (r) break;
	}

	close(sk);
	return r;
}

static int uses_rfcomm(char *path, char *dev)
{
	struct dirent *de;
	DIR   *dir;

	dir = opendir(path);
	if (!dir)
		return 0;
	chdir(path);

	while ((de = readdir(dir)) != NULL) {
		char link[PATH_MAX + 1];
		int  len = readlink(de->d_name, link, sizeof(link));
		if (len > 0) {
			link[len] = 0;
			if (strstr(link, dev))
				return 1;
		}
	}
	closedir(dir);
	return 0;
}

static int find_pppd(int id, pid_t *pid)
{
	struct dirent *de;
	char  path[PATH_MAX + 1];
	char  dev[10];
	int   empty = 1;
	DIR   *dir;

	dir = opendir(PROC_BASE);
	if (!dir) {
		perror(PROC_BASE);
		return -1;
	}

	sprintf(dev, "rfcomm%d", id);

	*pid = 0;
	while ((de = readdir(dir)) != NULL) {
		empty = 0;
		if (isdigit(de->d_name[0])) {
			sprintf(path, "%s/%s/fd", PROC_BASE, de->d_name);
			if (uses_rfcomm(path, dev)) {
				*pid = atoi(de->d_name);
				break;
			}
		}
	}
	closedir(dir);

	if (empty)
		fprintf(stderr, "%s is empty (not mounted ?)\n", PROC_BASE);

	return *pid != 0;
}

static int dun_exec(char *tty, char *prog, char **args)
{
	int pid = fork();
	int fd;
	
	switch (pid) {
	case -1:
		return -1;

	case 0:
		break;

	default:
		return pid;
	}

	setsid();

	/* Close all FDs */
	for (fd=3; fd < 20; fd++)
		close(fd);

	execvp(prog, args);
	exit(1);
}

static int dun_create_tty(int sk, char *tty, int size)
{
	struct sockaddr_rc sa;
	struct stat st;
	int id, alen, try = 3;

	struct rfcomm_dev_req req = {
		flags:   (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP),
		dev_id:  -1
	};

	alen = sizeof(sa);
	if (getpeername(sk, (struct sockaddr *) &sa, &alen) < 0)
		return -1;
	bacpy(&req.dst, &sa.rc_bdaddr);

	alen = sizeof(sa);
	if (getsockname(sk, (struct sockaddr *) &sa, &alen) < 0)
		return -1;
	bacpy(&req.src, &sa.rc_bdaddr);
	req.channel = sa.rc_channel;

	id = ioctl(sk, RFCOMMCREATEDEV, &req);
	if (id < 0)
		return id;

	snprintf(tty, size, "/dev/rfcomm%d", id);
	while (stat(tty, &st) < 0) {
		snprintf(tty, size, "/dev/bluetooth/rfcomm/%d", id);
		if (stat(tty, &st) < 0) {
			snprintf(tty, size, "/dev/rfcomm%d", id);
			if (try--) {
				sleep(1);
				continue;
			}

			memset(&req, 0, sizeof(req));
			req.dev_id = id;
			ioctl(sk, RFCOMMRELEASEDEV, &req);

			return -1;
		}
	}

	return id;
}

int dun_init(void)
{
	return 0;
}

int dun_cleanup(void)
{
	return 0;
}

static int show_conn(struct rfcomm_dev_info *di, unsigned long arg)
{
	pid_t pid;
	
	if (di->state == BT_CONNECTED &&
		(di->flags & (1<<RFCOMM_REUSE_DLC)) &&
		(di->flags & (1<<RFCOMM_TTY_ATTACHED)) &&
		(di->flags & (1<<RFCOMM_RELEASE_ONHUP))) {

		if (find_pppd(di->id, &pid)) {
			char dst[18];
			ba2str(&di->dst, dst);

			printf("rfcomm%d: %s channel %d pppd pid %d\n",
					di->id, dst, di->channel, pid);
		}
	}
	return 0;
}

static int kill_conn(struct rfcomm_dev_info *di, unsigned long arg)
{
	bdaddr_t *dst = (bdaddr_t *) arg;
	pid_t pid;

	if (di->state == BT_CONNECTED &&
		(di->flags & (1<<RFCOMM_REUSE_DLC)) &&
		(di->flags & (1<<RFCOMM_TTY_ATTACHED)) &&
		(di->flags & (1<<RFCOMM_RELEASE_ONHUP))) {

		if (dst && bacmp(&di->dst, dst))
			return 0;

		if (find_pppd(di->id, &pid)) {
			if (kill(pid, SIGINT) < 0)
				perror("Kill");

			if (!dst)
				return 0;
			return 1;
		}
	}
	return 0;
}

int dun_show_connections(void)
{
	for_each_port(show_conn, 0);
	return 0;
}

int dun_kill_connection(uint8_t *dst)
{
	for_each_port(kill_conn, (unsigned long) dst);
	return 0;
}

int dun_kill_all_connections(void)
{
	for_each_port(kill_conn, 0);
	return 0;
}

int dun_open_connection(int sk, char *pppd, char **args, int wait)
{
	char tty[100];
	int  pid;

	if (dun_create_tty(sk, tty, sizeof(tty) - 1) < 0) {
		syslog(LOG_ERR, "RFCOMM TTY creation failed. %s(%d)", strerror(errno), errno);
		return -1;
	}

	args[0] = "pppd";
	args[1] = tty;
	args[2] = "nodetach";

	pid = dun_exec(tty, pppd, args);
	if (pid < 0) {
		syslog(LOG_ERR, "Exec failed. %s(%d)", strerror(errno), errno);
		return -1;
	}

	if (wait) {
		int status;
		waitpid(pid, &status, 0);
		/* FIXME: Check for waitpid errors */
	}

	return 0;
}
