/*
 * Copyright (c) 2020 PHYTEC Messtechnik GmbH
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * This file is based on mb.c and mb_util.c from uC/Modbus Stack.
 *
 *                                uC/Modbus
 *                         The Embedded Modbus Stack
 *
 *      Copyright 2003-2020 Silicon Laboratories Inc. www.silabs.com
 *
 *                   SPDX-License-Identifier: APACHE-2.0
 *
 * This software is subject to an open source license and is distributed by
 *  Silicon Laboratories Inc. pursuant to the terms of the Apache License,
 *      Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(modbus_serial, CONFIG_MODBUS_LOG_LEVEL);

#include <kernel.h>
#include <string.h>
#include <sys/byteorder.h>
#include <sys/crc.h>
#include <modbus_internal.h>

static void modbus_serial_tx_on(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	if (cfg->de != NULL) {
		gpio_pin_set(cfg->de->port, cfg->de->pin, 1);
	}

	uart_irq_tx_enable(cfg->dev);
}

static void modbus_serial_tx_off(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	uart_irq_tx_disable(cfg->dev);
	if (cfg->de != NULL) {
		gpio_pin_set(cfg->de->port, cfg->de->pin, 0);
	}
}

static void modbus_serial_rx_on(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	if (cfg->re != NULL) {
		gpio_pin_set(cfg->re->port, cfg->re->pin, 1);
	}

	uart_irq_rx_enable(cfg->dev);
}

static void modbus_serial_rx_off(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	uart_irq_rx_disable(cfg->dev);
	if (cfg->re != NULL) {
		gpio_pin_set(cfg->re->port, cfg->re->pin, 0);
	}
}

#ifdef CONFIG_MODBUS_ASCII_MODE
/* The function calculates an 8-bit Longitudinal Redundancy Check. */
static uint8_t modbus_ascii_get_lrc(uint8_t *src, size_t length)
{
	uint8_t lrc = 0;
	uint8_t tmp;
	uint8_t *pblock = src;

	while (length-- > 0) {
		/* Add the data byte to LRC, increment data pointer. */
		if (hex2bin(pblock, 2, &tmp, sizeof(tmp)) != sizeof(tmp)) {
			return 0;
		}

		lrc += tmp;
		pblock += 2;
	}

	/* Two complement the binary sum */
	lrc = ~lrc + 1;

	return lrc;
}

/* Parses and converts an ASCII mode frame into a Modbus RTU frame. */
static int modbus_ascii_rx_adu(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	uint8_t *pmsg;
	uint8_t *prx_data;
	uint16_t rx_size;
	uint8_t frame_lrc;
	uint8_t calc_lrc;

	rx_size =  cfg->uart_buf_ctr;
	prx_data = &ctx->rx_adu.data[0];

	if (!(rx_size & 0x01)) {
		LOG_WRN("Message should have an odd number of bytes");
		return -EMSGSIZE;
	}

	if (rx_size < MODBUS_ASCII_MIN_MSG_SIZE) {
		LOG_WRN("Frame length error");
		return -EMSGSIZE;
	}

	if ((cfg->uart_buf[0] != MODBUS_ASCII_START_FRAME_CHAR) ||
	    (cfg->uart_buf[rx_size - 2] != MODBUS_ASCII_END_FRAME_CHAR1) ||
	    (cfg->uart_buf[rx_size - 1] != MODBUS_ASCII_END_FRAME_CHAR2)) {
		LOG_WRN("Frame character error");
		return -EMSGSIZE;
	}

	/* Take away for the ':', CR, and LF */
	rx_size -= 3;
	/* Point past the ':' to the address. */
	pmsg = &cfg->uart_buf[1];

	hex2bin(pmsg, 2, &ctx->rx_adu.unit_id, 1);
	pmsg += 2;
	rx_size -= 2;
	hex2bin(pmsg, 2, &ctx->rx_adu.fc, 1);
	pmsg += 2;
	rx_size -= 2;

	/* Get the data from the message */
	ctx->rx_adu.length = 0;
	while (rx_size > 2) {
		hex2bin(pmsg, 2, prx_data, 1);
		prx_data++;
		pmsg += 2;
		rx_size -= 2;
		/* Increment the number of Modbus packets received */
		ctx->rx_adu.length++;
	}

	/* Extract the message's LRC */
	hex2bin(pmsg, 2, &frame_lrc, 1);
	ctx->rx_adu.crc = frame_lrc;

	/*
	 * The LRC is calculated on the ADDR, FC and Data fields,
	 * not the ':', CR/LF and LRC placed in the message
	 * by the sender. We thus need to subtract 5 'ASCII' characters
	 * from the received message to exclude these.
	 */
	calc_lrc = modbus_ascii_get_lrc(&cfg->uart_buf[1],
					(cfg->uart_buf_ctr - 5) / 2);

	if (calc_lrc != frame_lrc) {
		LOG_ERR("Calculated LRC does not match received LRC");
		return -EIO;
	}

	return 0;
}

static uint8_t *modbus_ascii_bin2hex(uint8_t value, uint8_t *pbuf)
{
	uint8_t u_nibble = (value >> 4) & 0x0F;
	uint8_t l_nibble = value & 0x0F;

	hex2char(u_nibble, pbuf);
	pbuf++;
	hex2char(l_nibble, pbuf);
	pbuf++;

	return pbuf;
}

static void modbus_ascii_tx_adu(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	uint16_t tx_bytes = 0;
	uint8_t lrc;
	uint8_t *pbuf;

	/* Place the start-of-frame character into output buffer */
	cfg->uart_buf[0] = MODBUS_ASCII_START_FRAME_CHAR;
	tx_bytes = 1;

	pbuf = &cfg->uart_buf[1];
	pbuf = modbus_ascii_bin2hex(ctx->tx_adu.unit_id, pbuf);
	tx_bytes += 2;
	pbuf = modbus_ascii_bin2hex(ctx->tx_adu.fc, pbuf);
	tx_bytes += 2;

	for (int i = 0; i < ctx->tx_adu.length; i++) {
		pbuf = modbus_ascii_bin2hex(ctx->tx_adu.data[i], pbuf);
		tx_bytes += 2;
	}

	/*
	 * Add the LRC checksum in the packet.
	 *
	 * The LRC is calculated on the ADDR, FC and Data fields,
	 * not the ':' which was inserted in the uart_buf[].
	 * Thus we subtract 1 ASCII character from the LRC.
	 * The LRC and CR/LF bytes are not YET in the .uart_buf[].
	 */
	lrc = modbus_ascii_get_lrc(&cfg->uart_buf[1], (tx_bytes - 1) / 2);
	pbuf = modbus_ascii_bin2hex(lrc, pbuf);
	tx_bytes += 2;

	*pbuf++ = MODBUS_ASCII_END_FRAME_CHAR1;
	*pbuf++ = MODBUS_ASCII_END_FRAME_CHAR2;
	tx_bytes += 2;

	/* Update the total number of bytes to send */
	cfg->uart_buf_ctr = tx_bytes;
	cfg->uart_buf_ptr = &cfg->uart_buf[0];

	LOG_DBG("Start frame transmission");
	modbus_serial_rx_off(ctx);
	modbus_serial_tx_on(ctx);
}
#else
static int modbus_ascii_rx_adu(struct modbus_context *ctx)
{
	return 0;
}

static void modbus_ascii_tx_adu(struct modbus_context *ctx)
{
}
#endif

/* Copy Modbus RTU frame and check if the CRC is valid. */
static int modbus_rtu_rx_adu(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	uint16_t calc_crc;
	uint16_t crc_idx;
	uint8_t *data_ptr;

	/* Is the message long enough? */
	if ((cfg->uart_buf_ctr < MODBUS_RTU_MIN_MSG_SIZE) ||
	    (cfg->uart_buf_ctr > CONFIG_MODBUS_BUFFER_SIZE)) {
		LOG_WRN("Frame length error");
		return -EMSGSIZE;
	}

	ctx->rx_adu.unit_id = cfg->uart_buf[0];
	ctx->rx_adu.fc = cfg->uart_buf[1];
	data_ptr = &cfg->uart_buf[2];
	/* Payload length without node address, function code, and CRC */
	ctx->rx_adu.length = cfg->uart_buf_ctr - 4;
	/* CRC index */
	crc_idx = cfg->uart_buf_ctr - sizeof(uint16_t);

	memcpy(ctx->rx_adu.data, data_ptr, ctx->rx_adu.length);

	ctx->rx_adu.crc = sys_get_le16(&cfg->uart_buf[crc_idx]);
	/* Calculate CRC over address, function code, and payload */
	calc_crc = crc16_ansi(&cfg->uart_buf[0],
			      cfg->uart_buf_ctr - sizeof(ctx->rx_adu.crc));

	if (ctx->rx_adu.crc != calc_crc) {
		LOG_WRN("Calculated CRC does not match received CRC");
		return -EIO;
	}

	return 0;
}

static void rtu_tx_adu(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	uint16_t tx_bytes = 0;
	uint8_t *data_ptr;

	cfg->uart_buf[0] = ctx->tx_adu.unit_id;
	cfg->uart_buf[1] = ctx->tx_adu.fc;
	tx_bytes = 2 + ctx->tx_adu.length;
	data_ptr = &cfg->uart_buf[2];

	memcpy(data_ptr, ctx->tx_adu.data, ctx->tx_adu.length);

	ctx->tx_adu.crc = crc16_ansi(&cfg->uart_buf[0], ctx->tx_adu.length + 2);
	sys_put_le16(ctx->tx_adu.crc,
		     &cfg->uart_buf[ctx->tx_adu.length + 2]);
	tx_bytes += 2;

	cfg->uart_buf_ctr = tx_bytes;
	cfg->uart_buf_ptr = &cfg->uart_buf[0];

	LOG_HEXDUMP_DBG(cfg->uart_buf, cfg->uart_buf_ctr, "uart_buf");
	LOG_DBG("Start frame transmission");
	modbus_serial_rx_off(ctx);
	modbus_serial_tx_on(ctx);
}

/*
 * A byte has been received from a serial port. We just store it in the buffer
 * for processing when a complete packet has been received.
 */
static void cb_handler_rx(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	if ((ctx->mode == MODBUS_MODE_ASCII) &&
	    IS_ENABLED(CONFIG_MODBUS_ASCII_MODE)) {
		uint8_t c;

		if (uart_fifo_read(cfg->dev, &c, 1) != 1) {
			LOG_ERR("Failed to read UART");
			return;
		}

		if (c == MODBUS_ASCII_START_FRAME_CHAR) {
			/* Restart a new frame */
			cfg->uart_buf_ptr = &cfg->uart_buf[0];
			cfg->uart_buf_ctr = 0;
		}

		if (cfg->uart_buf_ctr < CONFIG_MODBUS_BUFFER_SIZE) {
			*cfg->uart_buf_ptr++ = c;
			cfg->uart_buf_ctr++;
		}

		if (c == MODBUS_ASCII_END_FRAME_CHAR2) {
			k_work_submit(&ctx->server_work);
		}

	} else {
		int n;

		/* Restart timer on a new character */
		k_timer_start(&cfg->rtu_timer,
			      K_USEC(cfg->rtu_timeout), K_NO_WAIT);

		n = uart_fifo_read(cfg->dev, cfg->uart_buf_ptr,
				   (CONFIG_MODBUS_BUFFER_SIZE -
				    cfg->uart_buf_ctr));

		cfg->uart_buf_ptr += n;
		cfg->uart_buf_ctr += n;
	}
}

static void cb_handler_tx(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	int n;

	if (cfg->uart_buf_ctr > 0) {
		n = uart_fifo_fill(cfg->dev, cfg->uart_buf_ptr,
				   cfg->uart_buf_ctr);
		cfg->uart_buf_ctr -= n;
		cfg->uart_buf_ptr += n;
		return;
	}

	/* Must wait till the transmission is complete or
	 * RS-485 transceiver could be disabled before all data has
	 * been transmitted and message will be corrupted.
	 */
	if (uart_irq_tx_complete(cfg->dev)) {
		/* Disable transmission */
		cfg->uart_buf_ptr = &cfg->uart_buf[0];
		modbus_serial_tx_off(ctx);
		modbus_serial_rx_on(ctx);
	}
}

static void uart_cb_handler(const struct device *dev, void *app_data)
{
	struct modbus_context *ctx = (struct modbus_context *)app_data;
	struct modbus_serial_config *cfg;

	if (ctx == NULL) {
		LOG_ERR("Modbus hardware is not properly initialized");
		return;
	}

	cfg = ctx->cfg;

	if (uart_irq_update(cfg->dev) && uart_irq_is_pending(cfg->dev)) {

		if (uart_irq_rx_ready(cfg->dev)) {
			cb_handler_rx(ctx);
		}

		if (uart_irq_tx_ready(cfg->dev)) {
			cb_handler_tx(ctx);
		}
	}
}

/* This function is called when the RTU framing timer expires. */
static void rtu_tmr_handler(struct k_timer *t_id)
{
	struct modbus_context *ctx;

	ctx = (struct modbus_context *)k_timer_user_data_get(t_id);

	if (ctx == NULL) {
		LOG_ERR("Failed to get Modbus context");
		return;
	}

	k_work_submit(&ctx->server_work);
}

static int configure_gpio(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;

	if (cfg->de != NULL) {
		if (!device_is_ready(cfg->de->port)) {
			return -ENODEV;
		}

		if (gpio_pin_configure_dt(cfg->de, GPIO_OUTPUT_INACTIVE)) {
			return -EIO;
		}
	}


	if (cfg->re != NULL) {
		if (!device_is_ready(cfg->re->port)) {
			return -ENODEV;
		}

		if (gpio_pin_configure_dt(cfg->re, GPIO_OUTPUT_INACTIVE)) {
			return -EIO;
		}
	}

	return 0;
}

void modbus_serial_rx_disable(struct modbus_context *ctx)
{
	modbus_serial_rx_off(ctx);
}

void modbus_serial_rx_enable(struct modbus_context *ctx)
{
	modbus_serial_rx_on(ctx);
}

int modbus_serial_rx_adu(struct modbus_context *ctx)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	int rc = 0;

	switch (ctx->mode) {
	case MODBUS_MODE_RTU:
		rc = modbus_rtu_rx_adu(ctx);
		break;
	case MODBUS_MODE_ASCII:
		if (!IS_ENABLED(CONFIG_MODBUS_ASCII_MODE)) {
			return -ENOTSUP;
		}

		rc = modbus_ascii_rx_adu(ctx);
		break;
	default:
		LOG_ERR("Unsupported MODBUS mode");
		return -ENOTSUP;
	}

	cfg->uart_buf_ctr = 0;
	cfg->uart_buf_ptr = &cfg->uart_buf[0];

	return rc;
}

int modbus_serial_tx_adu(struct modbus_context *ctx)
{
	switch (ctx->mode) {
	case MODBUS_MODE_RTU:
		rtu_tx_adu(ctx);
		return 0;
	case MODBUS_MODE_ASCII:
		if (IS_ENABLED(CONFIG_MODBUS_ASCII_MODE)) {
			modbus_ascii_tx_adu(ctx);
			return 0;
		}
	default:
		break;
	}

	return -ENOTSUP;
}

int modbus_serial_init(struct modbus_context *ctx,
		       struct modbus_iface_param param)
{
	struct modbus_serial_config *cfg = ctx->cfg;
	const uint32_t if_delay_max = 3500000;
	const uint32_t numof_bits = 11;
	struct uart_config uart_cfg;

	switch (param.mode) {
	case MODBUS_MODE_RTU:
	case MODBUS_MODE_ASCII:
		ctx->mode = param.mode;
		break;
	default:
		return -ENOTSUP;
	}

	cfg->dev = device_get_binding(cfg->dev_name);
	if (cfg->dev == NULL) {
		LOG_ERR("Failed to get UART device %s",
			log_strdup(cfg->dev_name));
		return -ENODEV;
	}

	uart_cfg.baudrate = param.serial.baud,
	uart_cfg.flow_ctrl = UART_CFG_FLOW_CTRL_NONE;

	if (ctx->mode == MODBUS_MODE_ASCII) {
		uart_cfg.data_bits = UART_CFG_DATA_BITS_7;
	} else {
		uart_cfg.data_bits = UART_CFG_DATA_BITS_8;
	}

	switch (param.serial.parity) {
	case UART_CFG_PARITY_ODD:
	case UART_CFG_PARITY_EVEN:
		uart_cfg.parity = param.serial.parity;
		uart_cfg.stop_bits = UART_CFG_STOP_BITS_1;
		break;
	case UART_CFG_PARITY_NONE:
		/* Use of no parity requires 2 stop bits */
		uart_cfg.parity = param.serial.parity;
		uart_cfg.stop_bits = UART_CFG_STOP_BITS_2;
		break;
	default:
		return -EINVAL;
	}

	if (ctx->client) {
		/* Allow custom stop bit settings only in client mode */
		switch (param.serial.stop_bits_client) {
		case UART_CFG_STOP_BITS_0_5:
		case UART_CFG_STOP_BITS_1:
		case UART_CFG_STOP_BITS_1_5:
		case UART_CFG_STOP_BITS_2:
			uart_cfg.stop_bits = param.serial.stop_bits_client;
			break;
		default:
			return -EINVAL;
		}
	}

	if (uart_configure(cfg->dev, &uart_cfg) != 0) {
		LOG_ERR("Failed to configure UART");
		return -EINVAL;
	}

	if (param.serial.baud <= 38400) {
		cfg->rtu_timeout = (numof_bits * if_delay_max) /
				   param.serial.baud;
	} else {
		cfg->rtu_timeout = (numof_bits * if_delay_max) / 38400;
	}

	if (configure_gpio(ctx) != 0) {
		return -EIO;
	}

	cfg->uart_buf_ctr = 0;
	cfg->uart_buf_ptr = &cfg->uart_buf[0];

	uart_irq_callback_user_data_set(cfg->dev, uart_cb_handler, ctx);
	k_timer_init(&cfg->rtu_timer, rtu_tmr_handler, NULL);
	k_timer_user_data_set(&cfg->rtu_timer, ctx);

	modbus_serial_rx_on(ctx);
	LOG_INF("RTU timeout %u us", cfg->rtu_timeout);

	return 0;
}

void modbus_serial_disable(struct modbus_context *ctx)
{
	modbus_serial_tx_off(ctx);
	modbus_serial_rx_off(ctx);
	k_timer_stop(&ctx->cfg->rtu_timer);
}
