/* T-Link interface using POSIX serial port */

/* (C) 2008-2011 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * Authors:	Harald Welte <laforge@gnumonks.org>
 *		Pablo Neira Ayuso <pablo@gnumonks.org>
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

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

#include <osmocom/core/select.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/abis/e1_input.h>

static void *tall_rs232_ctx;

struct serial_handle {
	struct e1inp_line	*line;

	struct msgb		*rx_msg;
	unsigned int		rxmsg_bytes_missing;

	unsigned int		delay_ms;
};

#define CRAPD_HDR_LEN	10

static int handle_ser_write(struct osmo_fd *bfd);

static void rs232_build_msg(struct msgb *msg)
{
	uint8_t *crapd;
	unsigned int len;

	msg->l2h = msg->data;

	/* prepend CRAPD header */
	crapd = msgb_push(msg, CRAPD_HDR_LEN);

	len = msg->len - 2;

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

/* select.c callback in case we can write to the rs232 */
static int handle_ser_write(struct osmo_fd *bfd)
{
	struct serial_handle *sh = bfd->data;
	struct e1inp_ts *e1i_ts = &sh->line->ts[0];
	struct e1inp_sign_link *sign_link;
	struct msgb *msg;
	int written;

	bfd->when &= ~OSMO_FD_WRITE;

	/* get the next msg for this timeslot */
	msg = e1inp_tx_ts(e1i_ts, &sign_link);
	if (!msg) {
		/* no message after tx delay timer */
		return 0;
	}
	LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "rs232 TX: %s\n", osmo_hexdump(msg->data, msg->len));

	rs232_build_msg(msg);

	/* send over serial line */
	written = write(bfd->fd, msg->data, msg->len);
	if (written < msg->len) {
		LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "rs232: short write\n");
		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 osmo_fd *bfd)
{
	struct serial_handle *sh = bfd->data;
	struct e1inp_ts *e1i_ts = &sh->line->ts[0];
	struct msgb *msg;
	int rc = 0;

	if (!sh->rx_msg) {
		sh->rx_msg = msgb_alloc(SERIAL_ALLOC_SIZE, "rs232 Rx");
		sh->rx_msg->l2h = NULL;
	}
	msg = sh->rx_msg;

	/* first read two byes to obtain length */
	if (msg->len < 2) {
		rc = read(bfd->fd, msg->tail, 2 - msg->len);
		if (rc < 0) {
			LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "rs232: error reading from "
				"serial port: %s\n", strerror(errno));
			msgb_free(msg);
			return rc;
		}
		msgb_put(msg, rc);

		if (msg->len >= 2) {
			/* parse CRAPD payload length */
			if (msg->data[0] != 0) {
				LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "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 < CRAPD_HDR_LEN -2) {
				LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "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(bfd->fd, msg->tail, sh->rxmsg_bytes_missing);
		if (rc < 0) {
			LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "rs232: error reading from serial port: %s",
				strerror(errno));
			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 > CRAPD_HDR_LEN)
				msg->l2h = msg->data + CRAPD_HDR_LEN;

			LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "rs232 RX: %s", osmo_hexdump(msg->data, msg->len));

			/* don't use e1inp_tx_ts() here, this header does not
			 * contain any SAPI and TEI values. */
			if (!e1i_ts->line->ops->sign_link) {
				LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "rs232: no callback set, skipping message.\n");
				return -EINVAL;
			}
			e1i_ts->line->ops->sign_link(msg);
		}
	}

	return rc;
}

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

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

	if (rc < 0)
		return rc;

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

	return rc;
}

static int rs232_want_write(struct e1inp_ts *e1i_ts)
{
	e1i_ts->driver.rs232.fd.when |= OSMO_FD_WRITE;

	return 0;
}

static int
rs232_setup(struct e1inp_line *line, const char *serial_port, unsigned int delay_ms)
{
	int rc;
	struct osmo_fd *bfd = &line->ts[0].driver.rs232.fd;
	struct serial_handle *ser_handle;
	struct termios tio;

	rc = open(serial_port, O_RDWR);
	if (rc < 0) {
		LOGPIL(line, DLMI, LOGL_ERROR, "rs232: cannot open serial port: %s", strerror(errno));
		return rc;
	}
	bfd->fd = rc;

	/* set baudrate */
	rc = tcgetattr(bfd->fd, &tio);
	if (rc < 0) {
		LOGPIL(line, DLMI, LOGL_ERROR, "rs232: tcgetattr says: %s", strerror(errno));
		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(bfd->fd, TCSADRAIN, &tio);
	if (rc < 0) {
		LOGPIL(line, DLMI, LOGL_ERROR, "rs232: tcsetattr says: %s", strerror(errno));
		return rc;
	}

	ser_handle = talloc_zero(tall_rs232_ctx, struct serial_handle);
	if (ser_handle == NULL) {
		close(bfd->fd);
		LOGPIL(line, DLMI, LOGL_ERROR, "rs232: cannot allocate memory for serial handler\n");
		return -ENOMEM;
	}
	ser_handle->line = line;
	ser_handle->delay_ms = delay_ms;

	bfd->when = OSMO_FD_READ;
	bfd->cb = serial_fd_cb;
	bfd->data = ser_handle;

	rc = osmo_fd_register(bfd);
	if (rc < 0) {
		close(bfd->fd);
		LOGPIL(line, DLMI, LOGL_ERROR, "rs232: could not register FD: %s\n", strerror(-rc));
		return rc;
	}

	return 0;
}

static int rs232_line_update(struct e1inp_line *line);

static struct e1inp_driver rs232_driver = {
	.name		= "rs232",
	.want_write	= rs232_want_write,
	.line_update	= rs232_line_update,
};

static int rs232_line_update(struct e1inp_line *line)
{
	if (line->driver != &rs232_driver)
		return -EINVAL;

	return rs232_setup(line, line->ops->cfg.rs232.port,
				 line->ops->cfg.rs232.delay);
}

int e1inp_rs232_init(void)
{
	return e1inp_driver_register(&rs232_driver);
}
