/*! \file soft_uart.c
 *  Software UART implementation. */
/*
 * (C) 2022 by Harald Welte <laforge@gnumonks.org>
 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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.
 *
 */

#include <stdbool.h>
#include <stdint.h>
#include <errno.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/soft_uart.h>

/*! Rx/Tx flow state of a soft-UART */
enum suart_flow_state {
	SUART_FLOW_ST_IDLE,	/*!< waiting for a start bit or Tx data */
	SUART_FLOW_ST_DATA,	/*!< receiving/transmitting data bits */
	SUART_FLOW_ST_PARITY,	/*!< receiving/transmitting parity bits */
	SUART_FLOW_ST_STOP,	/*!< receiving/transmitting stop bits */
};

/*! Internal state of a soft-UART */
struct osmo_soft_uart {
	struct osmo_soft_uart_cfg cfg;
	const char *name;
	struct {
		bool running;
		uint8_t bit_count;
		uint8_t shift_reg;
		struct msgb *msg;
		ubit_t parity_bit; /* 0 (even) / 1 (odd) */
		unsigned int flags;
		unsigned int status;
		struct osmo_timer_list timer;
		enum suart_flow_state flow_state;
	} rx;
	struct {
		bool running;
		uint8_t bit_count;
		uint8_t shift_reg;
		ubit_t parity_bit; /* 0 (even) / 1 (odd) */
		enum suart_flow_state flow_state;
	} tx;
};

/*! Default soft-UART configuration (8-N-1) */
const struct osmo_soft_uart_cfg osmo_soft_uart_default_cfg = {
	.num_data_bits = 8,
	.num_stop_bits = 1,
	.parity_mode = OSMO_SUART_PARITY_NONE,
	.rx_buf_size = 1024,
	.rx_timeout_ms = 100,
};

/*************************************************************************
 * Receiver
 *************************************************************************/

/*! Flush the receive buffer, passing ownership of the msgb to the .rx_cb().
 * \param[in] suart soft-UART instance holding the receive buffer. */
void osmo_soft_uart_flush_rx(struct osmo_soft_uart *suart)
{
	if ((suart->rx.msg && msgb_length(suart->rx.msg)) || suart->rx.flags) {
		osmo_timer_del(&suart->rx.timer);
		if (suart->cfg.rx_cb) {
			suart->cfg.rx_cb(suart->cfg.priv, suart->rx.msg, suart->rx.flags);
			/* call-back has taken ownership of msgb, no need to free() here */
			suart->rx.msg = msgb_alloc_c(suart, suart->cfg.rx_buf_size, "soft_uart_rx");
		} else {
			msgb_reset(suart->rx.msg);
		}
	}
}

/* one character was received; add to receive buffer and notify user, if needed */
static void suart_rx_ch(struct osmo_soft_uart *suart, uint8_t ch)
{
	unsigned int msg_len;

	OSMO_ASSERT(suart->rx.msg);
	msgb_put_u8(suart->rx.msg, ch);
	msg_len = msgb_length(suart->rx.msg);

	if (msg_len >= suart->cfg.rx_buf_size || suart->rx.flags) {
		/* either the buffer is full, or we hit a parity and/or a framing error */
		osmo_soft_uart_flush_rx(suart);
	} else if (msg_len == 1) {
		/* first character in new message: start timer */
		osmo_timer_schedule(&suart->rx.timer, suart->cfg.rx_timeout_ms / 1000,
				    (suart->cfg.rx_timeout_ms % 1000) * 1000);
	}
}

/* receive a single bit */
static inline void osmo_uart_rx_bit(struct osmo_soft_uart *suart, const ubit_t bit)
{
	switch (suart->rx.flow_state) {
	case SUART_FLOW_ST_IDLE:
		if (bit == 0) { /* start bit condition */
			suart->rx.flow_state = SUART_FLOW_ST_DATA;
			suart->rx.flags = 0x00;
			suart->rx.shift_reg = 0;
			suart->rx.bit_count = 0;
			suart->rx.parity_bit = 0;
		}
		break;
	case SUART_FLOW_ST_DATA:
		suart->rx.bit_count++;
		suart->rx.shift_reg >>= 1;
		if (bit != 0) {
			suart->rx.parity_bit = !suart->rx.parity_bit; /* flip */
			suart->rx.shift_reg |= 0x80;
		}
		if (suart->rx.bit_count >= suart->cfg.num_data_bits) {
			/* we have accumulated enough data bits */
			if (suart->cfg.parity_mode != OSMO_SUART_PARITY_NONE)
				suart->rx.flow_state = SUART_FLOW_ST_PARITY;
			else
				suart->rx.flow_state = SUART_FLOW_ST_STOP;
			/* align the register if needed */
			if (suart->cfg.num_data_bits < 8)
				suart->rx.shift_reg >>= (8 - suart->cfg.num_data_bits);
		}
		break;
	case SUART_FLOW_ST_PARITY:
		switch (suart->cfg.parity_mode) {
		case OSMO_SUART_PARITY_EVEN:
			/* number of 1-bits (in both data and parity) shall be even */
			if (suart->rx.parity_bit != bit)
				suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
			break;
		case OSMO_SUART_PARITY_ODD:
			/* number of 1-bits (in both data and parity) shall be odd */
			if (suart->rx.parity_bit == bit)
				suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
			break;
		case OSMO_SUART_PARITY_MARK:
			/* parity bit must always be 1 */
			if (bit != 1)
				suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
			break;
		case OSMO_SUART_PARITY_SPACE:
			/* parity bit must always be 0 */
			if (bit != 0)
				suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
			break;
		case OSMO_SUART_PARITY_NONE: /* shall not happen */
		default:
			OSMO_ASSERT(0);
		}

		suart->rx.flow_state = SUART_FLOW_ST_STOP;
		break;
	case SUART_FLOW_ST_STOP:
		suart->rx.bit_count++;
		if (bit != 1)
			suart->rx.flags |= OSMO_SUART_F_FRAMING_ERROR;

		if (suart->rx.bit_count >= (suart->cfg.num_data_bits + suart->cfg.num_stop_bits)) {
			/* we have accumulated enough stop bits */
			suart_rx_ch(suart, suart->rx.shift_reg);
			suart->rx.flow_state = SUART_FLOW_ST_IDLE;
		}
		break;
	}
}

/* receive timer expiration: flush rx-buffer to user call-back */
static void suart_rx_timer_cb(void *data)
{
	struct osmo_soft_uart *suart = data;
	osmo_soft_uart_flush_rx(suart);
}

/*! Feed a number of unpacked bits into the soft-UART receiver.
 * \param[in] suart soft-UART instance to feed bits into.
 * \param[in] ubits pointer to the unpacked bits.
 * \param[in] n_ubits number of unpacked bits to be fed.
 * \returns 0 on success; negative on error.
 *          -EAGAIN indicates that the receiver is disabled. */
int osmo_soft_uart_rx_ubits(struct osmo_soft_uart *suart, const ubit_t *ubits, size_t n_ubits)
{
	if (!suart->rx.running)
		return -EAGAIN;
	for (size_t i = 0; i < n_ubits; i++)
		osmo_uart_rx_bit(suart, ubits[i]);
	return 0;
}

/*************************************************************************
 * Transmitter
 *************************************************************************/

/* pull a single bit out of the UART transmitter */
static inline ubit_t osmo_uart_tx_bit(struct osmo_soft_uart *suart, struct msgb *msg)
{
	ubit_t tx_bit = 1;

	switch (suart->tx.flow_state) {
	case SUART_FLOW_ST_IDLE:
		if (msg && msgb_length(msg) > 0) { /* if we have pending data */
			suart->tx.shift_reg = msgb_pull_u8(msg);
			suart->tx.flow_state = SUART_FLOW_ST_DATA;
			suart->tx.bit_count = 0;
			suart->tx.parity_bit = 0;
			tx_bit = 0;
		}
		break;
	case SUART_FLOW_ST_DATA:
		tx_bit = suart->tx.shift_reg & 1;
		suart->tx.parity_bit ^= tx_bit;
		suart->tx.shift_reg >>= 1;
		suart->tx.bit_count++;
		if (suart->tx.bit_count >= suart->cfg.num_data_bits) {
			/* we have transmitted all data bits */
			if (suart->cfg.parity_mode != OSMO_SUART_PARITY_NONE)
				suart->tx.flow_state = SUART_FLOW_ST_PARITY;
			else
				suart->tx.flow_state = SUART_FLOW_ST_STOP;
		}
		break;
	case SUART_FLOW_ST_PARITY:
		switch (suart->cfg.parity_mode) {
		case OSMO_SUART_PARITY_EVEN:
			/* number of 1-bits (in both data and parity) shall be even */
			tx_bit = suart->tx.parity_bit;
			break;
		case OSMO_SUART_PARITY_ODD:
			/* number of 1-bits (in both data and parity) shall be odd */
			tx_bit = !suart->tx.parity_bit;
			break;
		case OSMO_SUART_PARITY_MARK:
			/* parity bit must always be 1 */
			tx_bit = 1;
			break;
		case OSMO_SUART_PARITY_SPACE:
			/* parity bit must always be 0 */
			tx_bit = 0;
			break;
		case OSMO_SUART_PARITY_NONE:
		default: /* shall not happen */
			OSMO_ASSERT(0);
		}

		suart->tx.flow_state = SUART_FLOW_ST_STOP;
		break;
	case SUART_FLOW_ST_STOP:
		suart->tx.bit_count++;
		if (suart->tx.bit_count >= (suart->cfg.num_data_bits + suart->cfg.num_stop_bits)) {
			/* we have transmitted all stop bits, we're done */
			suart->tx.flow_state = SUART_FLOW_ST_IDLE;
		}
		break;
	}

	return tx_bit;
}

/*! Pull a number of unpacked bits out of the soft-UART transmitter.
 * \param[in] suart soft-UART instance to pull the bits from.
 * \param[out] ubits pointer to a buffer where to store pulled bits.
 * \param[in] n_ubits number of unpacked bits to be pulled.
 * \returns 0 on success; negative on error.
 *          -EAGAIN indicates that the transmitter is disabled. */
int osmo_soft_uart_tx_ubits(struct osmo_soft_uart *suart, ubit_t *ubits, size_t n_ubits)
{
	const struct osmo_soft_uart_cfg *cfg = &suart->cfg;
	size_t n_frame_bits, n_chars;
	struct msgb *msg = NULL;

	if (OSMO_UNLIKELY(n_ubits == 0))
		return -EINVAL;

	if (!suart->tx.running)
		return -EAGAIN;

	/* calculate UART frame size for the effective config */
	n_frame_bits = 1 + cfg->num_data_bits + cfg->num_stop_bits;
	if (cfg->parity_mode != OSMO_SUART_PARITY_NONE)
		n_frame_bits += 1;

	/* calculate the number of characters we can fit into n_ubits */
	n_chars = n_ubits / n_frame_bits;
	if (n_chars == 0) {
		/* we can transmit at least one character */
		if (suart->tx.flow_state == SUART_FLOW_ST_IDLE)
			n_chars = 1;
	}

	if (n_chars > 0) {
		/* allocate a Tx buffer msgb */
		msg = msgb_alloc_c(suart, n_chars, "soft_uart_tx");
		OSMO_ASSERT(msg != NULL);

		/* call the .tx_cb() to populate the Tx buffer */
		OSMO_ASSERT(cfg->tx_cb != NULL);
		suart->cfg.tx_cb(cfg->priv, msg);
	}

	for (size_t i = 0; i < n_ubits; i++)
		ubits[i] = osmo_uart_tx_bit(suart, msg);
	msgb_free(msg);

	return 0;
}

/*! Set the modem status lines of the given soft-UART.
 * \param[in] suart soft-UART instance to update the modem status.
 * \param[in] status mask of osmo_soft_uart_status.
 * \returns 0 on success; negative on error. */
int osmo_soft_uart_set_status(struct osmo_soft_uart *suart, unsigned int status)
{
	/* FIXME: Tx */
	return 0;
}


/*************************************************************************
 * Management / Initialization
 *************************************************************************/

/*! Allocate a soft-UART instance.
 * \param[in] ctx parent talloc context.
 * \param[in] name name of the soft-UART instance.
 * \param[in] cfg initial configuration of the soft-UART instance.
 * \returns pointer to allocated soft-UART instance; NULL on error. */
struct osmo_soft_uart *osmo_soft_uart_alloc(void *ctx, const char *name,
					    const struct osmo_soft_uart_cfg *cfg)
{
	struct osmo_soft_uart *suart = talloc_zero(ctx, struct osmo_soft_uart);
	if (!suart)
		return NULL;
	suart->name = talloc_strdup(suart, name);

	OSMO_ASSERT(cfg != NULL);
	suart->cfg = *cfg;

	return suart;
}

/*! Release memory taken by the given soft-UART.
 * \param[in] suart soft-UART instance to be free()d. */
void osmo_soft_uart_free(struct osmo_soft_uart *suart)
{
	if (suart == NULL)
		return;

	osmo_timer_del(&suart->rx.timer);
	msgb_free(suart->rx.msg);

	talloc_free((void *)suart->name);
	talloc_free(suart);
}

/*! Change soft-UART configuration to the user-provided config.
 * \param[in] suart soft-UART instance to be re-configured.
 * \param[in] cfg the user-provided config to be applied.
 * \returns 0 on success; negative on error. */
int osmo_soft_uart_configure(struct osmo_soft_uart *suart, const struct osmo_soft_uart_cfg *cfg)
{
	/* consistency checks on the configuration */
	if (cfg->num_data_bits > 8 || cfg->num_data_bits == 0)
		return -EINVAL;
	if (cfg->num_stop_bits == 0)
		return -EINVAL;
	if (cfg->parity_mode < 0 || cfg->parity_mode >= _OSMO_SUART_PARITY_NUM)
		return -EINVAL;
	if (cfg->rx_buf_size == 0)
		return -EINVAL;

	if (suart->cfg.rx_buf_size > cfg->rx_buf_size ||
	    suart->cfg.rx_timeout_ms > cfg->rx_timeout_ms) {
		osmo_soft_uart_flush_rx(suart);
	}

	suart->cfg = *cfg;

	osmo_timer_setup(&suart->rx.timer, suart_rx_timer_cb, suart);

	return 0;
}

/*! Get a name for the given soft-UART instance.
 * \param[in] suart soft-UART instance to get the name from.
 * \returns name of the given soft-UART instance. */
const char *osmo_soft_uart_get_name(const struct osmo_soft_uart *suart)
{
	return suart->name;
}

/*! Set a new name for the given soft-UART instance.
 * \param[in] suart soft-UART instance to set the name for.
 * \param[in] name the new name. */
void osmo_soft_uart_set_name(struct osmo_soft_uart *suart, const char *name)
{
	osmo_talloc_replace_string(suart, (char **)&suart->name, name);
}

/*! Enable/disable receiver of the given soft-UART.
 * \param[in] suart soft-UART instance to be re-configured.
 * \param[in] enable enable/disable state of the receiver.
 * \returns 0 on success; negative on error. */
int osmo_soft_uart_set_rx(struct osmo_soft_uart *suart, bool enable)
{
	if (!enable && suart->rx.running) {
		osmo_soft_uart_flush_rx(suart);
		suart->rx.running = false;
		suart->rx.flow_state = SUART_FLOW_ST_IDLE;
	} else if (enable && !suart->rx.running) {
		if (!suart->rx.msg)
			suart->rx.msg = msgb_alloc_c(suart, suart->cfg.rx_buf_size, "soft_uart rx");
		suart->rx.running = true;
		suart->rx.flow_state = SUART_FLOW_ST_IDLE;
	}

	return 0;
}

/*! Enable/disable transmitter of the given soft-UART.
 * \param[in] suart soft-UART instance to be re-configured.
 * \param[in] enable enable/disable state of the transmitter.
 * \returns 0 on success; negative on error. */
int osmo_soft_uart_set_tx(struct osmo_soft_uart *suart, bool enable)
{
	if (!enable && suart->tx.running) {
		suart->tx.running = false;
		suart->tx.flow_state = SUART_FLOW_ST_IDLE;
	} else if (enable && !suart->tx.running) {
		suart->tx.running = true;
		suart->tx.flow_state = SUART_FLOW_ST_IDLE;
	}

	return 0;
}
