/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011-2014  Intel Corporation
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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 <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/epoll.h>
#include <sys/uio.h>

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

#include "monitor/mainloop.h"
#include "btdev.h"
#include "serial.h"

#define uninitialized_var(x) x = x

struct serial {
	enum serial_type type;
	uint16_t id;
	int fd;
	char path[PATH_MAX];
	struct btdev *btdev;
	uint8_t *pkt_data;
	uint8_t pkt_type;
	uint16_t pkt_expect;
	uint16_t pkt_len;
	uint16_t pkt_offset;
};

static void open_pty(struct serial *serial);

static void serial_destroy(void *user_data)
{
	struct serial *serial = user_data;

	btdev_destroy(serial->btdev);
	serial->btdev = NULL;

	close(serial->fd);
	serial->fd = -1;
}

static void serial_write_callback(const struct iovec *iov, int iovlen,
							void *user_data)
{
	struct serial *serial = user_data;
	ssize_t written;

	written = writev(serial->fd, iov, iovlen);
	if (written < 0)
		return;
}

static void serial_read_callback(int fd, uint32_t events, void *user_data)
{
	struct serial *serial = user_data;
	static uint8_t buf[4096];
	uint8_t *ptr = buf;
	ssize_t len;
	uint16_t count;

	if (events & (EPOLLERR | EPOLLHUP)) {
		mainloop_remove_fd(serial->fd);
		open_pty(serial);
		return;
	}

again:
	len = read(serial->fd, buf + serial->pkt_offset,
			sizeof(buf) - serial->pkt_offset);
	if (len < 0) {
		if (errno == EAGAIN)
			goto again;
		return;
	}

	if (!serial->btdev)
		return;

	count = serial->pkt_offset + len;

	while (count > 0) {
		hci_command_hdr *cmd_hdr;

		if (!serial->pkt_data) {
			serial->pkt_type = ptr[0];

			switch (serial->pkt_type) {
			case HCI_COMMAND_PKT:
				if (count < HCI_COMMAND_HDR_SIZE + 1) {
					serial->pkt_offset += len;
					return;
				}
				cmd_hdr = (hci_command_hdr *) (ptr + 1);
				serial->pkt_expect = HCI_COMMAND_HDR_SIZE +
							cmd_hdr->plen + 1;
				serial->pkt_data = malloc(serial->pkt_expect);
				serial->pkt_len = 0;
				break;
			default:
				printf("packet error\n");
				return;
			}

			serial->pkt_offset = 0;
		}

		if (count >= serial->pkt_expect) {
			memcpy(serial->pkt_data + serial->pkt_len,
						ptr, serial->pkt_expect);
			ptr += serial->pkt_expect;
			count -= serial->pkt_expect;

			btdev_receive_h4(serial->btdev, serial->pkt_data,
					serial->pkt_len + serial->pkt_expect);

			free(serial->pkt_data);
			serial->pkt_data = NULL;
		} else {
			memcpy(serial->pkt_data + serial->pkt_len, ptr, count);
			serial->pkt_len += count;
			serial->pkt_expect -= count;
			count = 0;
		}
	}
}

static void open_pty(struct serial *serial)
{
	enum btdev_type uninitialized_var(type);

	serial->fd = getpt();
	if (serial->fd < 0) {
		perror("Failed to get master pseudo terminal");
		return;
	}

	if (grantpt(serial->fd) < 0) {
		perror("Failed to grant slave pseudo terminal");
		close(serial->fd);
		serial->fd = -1;
		return;
	}

	if (unlockpt(serial->fd) < 0) {
		perror("Failed to unlock slave pseudo terminal");
		close(serial->fd);
		serial->fd = -1;
		return;
	}

	ptsname_r(serial->fd, serial->path, sizeof(serial->path));

	printf("Pseudo terminal at %s\n", serial->path);

	switch (serial->type) {
	case SERIAL_TYPE_BREDRLE:
		type = BTDEV_TYPE_BREDRLE;
		break;
	case SERIAL_TYPE_BREDR:
		type = BTDEV_TYPE_BREDR;
		break;
	case SERIAL_TYPE_LE:
		type = BTDEV_TYPE_LE;
		break;
	case SERIAL_TYPE_AMP:
		type = BTDEV_TYPE_AMP;
		break;
	}

	serial->btdev = btdev_create(type, serial->id);
	if (!serial->btdev) {
		close(serial->fd);
		serial->fd = -1;
		return;
	}

	btdev_set_send_handler(serial->btdev, serial_write_callback, serial);

	if (mainloop_add_fd(serial->fd, EPOLLIN, serial_read_callback,
						serial, serial_destroy) < 0) {
		btdev_destroy(serial->btdev);
		serial->btdev = NULL;
		close(serial->fd);
		serial->fd = -1;
		return;
	}
}

struct serial *serial_open(enum serial_type type)
{
	struct serial *serial;
	enum btdev_type uninitialized_var(dev_type);

	serial = malloc(sizeof(*serial));
	if (!serial)
		return NULL;

	memset(serial, 0, sizeof(*serial));
	serial->type = type;
	serial->id = 0x42;

	open_pty(serial);

	return serial;
}

void serial_close(struct serial *serial)
{
	if (!serial)
		return;

	mainloop_remove_fd(serial->fd);

	free(serial);
}
