/* OpenBSC BS-11 T-Link interface using POSIX serial port */

/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>

#include <openbsc/select.h>
#include <openbsc/msgb.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
#include <openbsc/rs232.h>

/* adaption layer from GSM 08.59 + 12.21 to RS232 */

struct serial_handle {
	struct bsc_fd fd;
	struct llist_head tx_queue;

	struct msgb *rx_msg;
	unsigned int rxmsg_bytes_missing;

	unsigned int delay_ms;
	struct gsm_bts *bts;
};

/* FIXME: this needs to go */
static struct serial_handle _ser_handle, *ser_handle = &_ser_handle;

#define LAPD_HDR_LEN	10

static int handle_ser_write(struct bsc_fd *bfd);

/* callback from abis_nm */
int _abis_nm_sendmsg(struct msgb *msg)
{
	struct serial_handle *sh = ser_handle;
	u_int8_t *lapd;
	unsigned int len;

	msg->l2h = msg->data;

	/* prepend LAPD header */
	lapd = msgb_push(msg, LAPD_HDR_LEN);

	len = msg->len - 2;

	lapd[0] = (len >> 8) & 0xff;
	lapd[1] = len & 0xff; /* length of bytes startign at lapd[2] */
	lapd[2] = 0x00;
	lapd[3] = 0x07;
	lapd[4] = 0x01;
	lapd[5] = 0x3e;
	lapd[6] = 0x00;
	lapd[7] = 0x00;
	lapd[8] = msg->len - 10; /* length of bytes starting at lapd[10] */
	lapd[9] = lapd[8] ^ 0x38;

	msgb_enqueue(&sh->tx_queue, msg);
	sh->fd.when |= BSC_FD_WRITE;

	/* we try to immediately send */
	handle_ser_write(&sh->fd);

	return 0;
}

/* select.c callback in case we can write to the RS232 */
static int handle_ser_write(struct bsc_fd *bfd)
{
	struct serial_handle *sh = bfd->data;
	struct msgb *msg;
	int written;

	msg = msgb_dequeue(&sh->tx_queue);
	if (!msg) {
		bfd->when &= ~BSC_FD_WRITE;
		return 0;
	}

	DEBUGP(DMI, "RS232 TX: %s\n", hexdump(msg->data, msg->len));

	/* send over serial line */
	written = write(bfd->fd, msg->data, msg->len);
	if (written < msg->len) {
		perror("short write:");
		msgb_free(msg);
		return -1;
	}

	msgb_free(msg);
	usleep(sh->delay_ms*1000);

	return 0;
}

#define SERIAL_ALLOC_SIZE	300

/* select.c callback in case we can read from the RS232 */
static int handle_ser_read(struct bsc_fd *bfd)
{
	struct serial_handle *sh = bfd->data;
	struct msgb *msg;
	int rc = 0;

	if (!sh->rx_msg) {
		sh->rx_msg = msgb_alloc(SERIAL_ALLOC_SIZE);
		sh->rx_msg->l2h = NULL;
		sh->rx_msg->trx = sh->bts->c0;
	}
	msg = sh->rx_msg;

	/* first read two byes to obtain length */
	if (msg->len < 2) {
		rc = read(sh->fd.fd, msg->tail, 2 - msg->len);
		if (rc < 0) {
			perror("ERROR reading from serial port");
			msgb_free(msg);
			return rc;
		}
		msgb_put(msg, rc);

		if (msg->len >= 2) {
			/* parse LAPD payload length */
			if (msg->data[0] != 0)
				fprintf(stderr, "Suspicious header byte 0: 0x%02x\n",
					msg->data[0]);

			sh->rxmsg_bytes_missing = msg->data[0] << 8;
			sh->rxmsg_bytes_missing += msg->data[1];

			if (sh->rxmsg_bytes_missing < LAPD_HDR_LEN -2)
				fprintf(stderr, "Invalid length in hdr: %u\n",
					sh->rxmsg_bytes_missing);
		}
	} else { 
		/* try to read as many of the missing bytes as are available */
		rc = read(sh->fd.fd, msg->tail, sh->rxmsg_bytes_missing);
		if (rc < 0) {
			perror("ERROR reading from serial port");
			msgb_free(msg);
			return rc;
		}
		msgb_put(msg, rc);
		sh->rxmsg_bytes_missing -= rc;

		if (sh->rxmsg_bytes_missing == 0) {
			/* we have one complete message now */
			sh->rx_msg = NULL;

			if (msg->len > LAPD_HDR_LEN)
				msg->l2h = msg->data + LAPD_HDR_LEN;

			DEBUGP(DMI, "RS232 RX: %s\n", hexdump(msg->data, msg->len));
			rc = handle_serial_msg(msg);
		}
	}

	return rc;
}

/* select.c callback */
static int serial_fd_cb(struct bsc_fd *bfd, unsigned int what)
{
	int rc = 0;

	if (what & BSC_FD_READ)
		rc = handle_ser_read(bfd);

	if (rc < 0)
		return rc;

	if (what & BSC_FD_WRITE)
		rc = handle_ser_write(bfd);

	return rc;
}

int rs232_setup(const char *serial_port, unsigned int delay_ms,
		struct gsm_bts *bts)
{
	int rc, serial_fd;
	struct termios tio;

	serial_fd = open(serial_port, O_RDWR);
	if (serial_fd < 0) {
		perror("cannot open serial port:");
		return serial_fd;
	}

	/* set baudrate */
	rc = tcgetattr(serial_fd, &tio);
	if (rc < 0) {
		perror("tcgetattr()");
		return rc;
	}
	cfsetispeed(&tio, B19200);
	cfsetospeed(&tio, B19200);
	tio.c_cflag |=  (CREAD | CLOCAL | CS8);
	tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
	tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	tio.c_iflag |=  (INPCK | ISTRIP);
	tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
	tio.c_oflag &= ~(OPOST);
	rc = tcsetattr(serial_fd, TCSADRAIN, &tio);
	if (rc < 0) {
		perror("tcsetattr()");
		return rc;
	}

	INIT_LLIST_HEAD(&ser_handle->tx_queue);
	ser_handle->fd.fd = serial_fd;
	ser_handle->fd.when = BSC_FD_READ;
	ser_handle->fd.cb = serial_fd_cb;
	ser_handle->fd.data = ser_handle;
	ser_handle->delay_ms = delay_ms;
	ser_handle->bts = bts;
	rc = bsc_register_fd(&ser_handle->fd);
	if (rc < 0) {
		fprintf(stderr, "could not register FD: %s\n",
			strerror(rc));
		return rc;
	}

	return 0;
}
