/*
 *
 *  PPP over Bluetooth RFCOMM
 *
 *  Copyright (C) 2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

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


extern int optind, opterr, optopt;
extern char *optarg;


/* IO cancelation */
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;
}


/* Signal functions */
static void sig_hup(int sig)
{
	return;
}

static void sig_term(int sig)
{
	syslog(LOG_INFO, "Closing RFCOMM channel");
	io_cancel();
}


/* Read exactly len bytes (Signal safe)*/
static inline int read_n(int fd, char *buf, int len)
{
	register int t = 0, w;

	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, char *buf, int len)
{
	register int t = 0, w;

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


/* Create the RFCOMM connection */
static int create_connection(bdaddr_t *bdaddr, uint8_t channel)
{
	struct sockaddr_rc remote_addr, local_addr;
	int fd, err;

	if ((fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0)
		return fd;

	memset(&local_addr, 0, sizeof(local_addr));
	local_addr.rc_family = AF_BLUETOOTH;
	bacpy(&local_addr.rc_bdaddr, BDADDR_ANY);
	if ((err = bind(fd, (struct sockaddr *)&local_addr, sizeof(local_addr))) < 0) {
		close(fd);
		return err;
	}

	memset(&remote_addr, 0, sizeof(remote_addr));
	remote_addr.rc_family = AF_BLUETOOTH;
	bacpy(&remote_addr.rc_bdaddr, bdaddr);
	remote_addr.rc_channel = channel;
	if ((err = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr))) < 0) {
		close(fd);
		return err;
	}

	syslog(LOG_INFO, "RFCOMM channel %d connected", channel);

	return fd;
}


/* Process the data from socket and pseudo tty */
static int process_data(int fd)
{
	struct pollfd p[2];
	char buf[1024];
	int err, r;

	p[0].fd = 0;
	p[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
	
	p[1].fd = fd;
	p[1].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;

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

		err = 0;

		if (p[0].revents) {
			if (p[0].revents & (POLLERR | POLLHUP | POLLNVAL))
			  break;
			r = read(0, buf, sizeof(buf));
			if (r < 0) {
				if (errno != EINTR && errno != EAGAIN) {
					err = r;
					break;
				}
			}

			err = write_n(fd, buf, r);
			if (err < 0)
				break;
		}

		if (p[1].revents) {
			if (p[1].revents & (POLLERR | POLLHUP | POLLNVAL))
			  break;
			r = read(fd, buf, sizeof(buf));
			if (r < 0) {
				if (errno != EINTR && errno != EAGAIN) {
					err = r;
					break;
				}
			}

			err = write_n(1, buf, r);
			if (err < 0)
				break;
		}
	}

	return err;
}


static void usage(void)
{
	printf("Usage:\tppporc <bdaddr> [channel]\n");
}


int main(int argc, char** argv)
{
	struct sigaction sa;
	int fd, err, opt;

	bdaddr_t bdaddr;
	uint8_t channel;


	/* Parse command line options */
	while ((opt = getopt(argc, argv, "h")) != EOF) {
		switch(opt) {
		case 'h':
			usage();
			exit(0);
		}
	}

	argc -= optind;
	argv += optind;

	switch (argc) {
	case 1:
		str2ba(argv[0], &bdaddr);
		channel = 1;
		break;
	case 2:
		str2ba(argv[0], &bdaddr);
		channel = atoi(argv[1]);
		break;
	default:
		usage();
		exit(0);
	}


	/* Initialize syslog */
	openlog("ppporc", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
	syslog(LOG_INFO, "PPP over RFCOMM");


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


	syslog(LOG_INFO, "Connecting to %s", argv[0]);

	if ((fd = create_connection(&bdaddr, channel)) < 0) {
		syslog(LOG_ERR, "Can't connect to remote device (%s)", strerror(errno));
		return fd;
	}

	err = process_data(fd);

	close(fd);

	return err;
}
