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

/*
 * This file is based on mbm_core.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 <string.h>
#include <zephyr/sys/byteorder.h>
#include <modbus_internal.h>

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

static int mbc_validate_response_fc(struct modbus_context *ctx,
				    const uint8_t unit_id,
				    uint8_t fc)
{
	uint8_t resp_fc = ctx->rx_adu.fc;
	uint8_t excep_code = ctx->rx_adu.data[0];
	const uint8_t excep_bit = BIT(7);
	const uint8_t excep_mask = BIT_MASK(7);

	if (unit_id != ctx->rx_adu.unit_id) {
		return -EIO;
	}

	if (fc != (resp_fc & excep_mask)) {
		return -EIO;
	}

	if (resp_fc & excep_bit) {
		if (excep_code > MODBUS_EXC_NONE) {
			return excep_code;
		}

		return -EIO;
	}

	return 0;
}

static int mbc_validate_fc03fp_response(struct modbus_context *ctx, float *ptbl)
{
	size_t resp_byte_cnt;
	size_t req_byte_cnt;
	uint16_t req_qty;
	uint8_t *resp_data;

	resp_byte_cnt = ctx->rx_adu.data[0];
	resp_data = &ctx->rx_adu.data[1];
	req_qty = sys_get_be16(&ctx->tx_adu.data[2]);
	req_byte_cnt = req_qty * sizeof(float);

	if (req_byte_cnt != resp_byte_cnt) {
		LOG_ERR("Mismatch in the number of registers");
		return -EINVAL;
	}

	for (uint16_t i = 0; i < req_qty; i++) {
		uint32_t reg_val = sys_get_be32(resp_data);

		memcpy(&ptbl[i], &reg_val, sizeof(float));
		resp_data += sizeof(uint32_t);
	}

	return 0;
}

static int mbc_validate_rd_response(struct modbus_context *ctx,
				    const uint8_t unit_id,
				    uint8_t fc,
				    uint8_t *data)
{
	int err;
	size_t resp_byte_cnt;
	size_t req_byte_cnt;
	uint16_t req_qty;
	uint16_t req_addr;
	uint8_t *resp_data;
	uint16_t *data_p16 = (uint16_t *)data;

	if (data == NULL) {
		return -EINVAL;
	}

	resp_byte_cnt = ctx->rx_adu.data[0];
	resp_data = &ctx->rx_adu.data[1];
	req_qty = sys_get_be16(&ctx->tx_adu.data[2]);
	req_addr = sys_get_be16(&ctx->tx_adu.data[0]);

	if ((resp_byte_cnt + 1) > sizeof(ctx->rx_adu.data)) {
		LOG_ERR("Byte count exceeds buffer length");
		return -EINVAL;
	}

	switch (fc) {
	case MODBUS_FC01_COIL_RD:
	case MODBUS_FC02_DI_RD:
		req_byte_cnt = ((req_qty - 1) / 8) + 1;
		if (req_byte_cnt != resp_byte_cnt) {
			LOG_ERR("Mismatch in the number of coils or inputs");
			err = -EINVAL;
		} else {
			for (uint8_t i = 0; i < resp_byte_cnt; i++) {
				data[i] = resp_data[i];
			}

			err = 0;
		}
		break;

	case MODBUS_FC03_HOLDING_REG_RD:
		if (IS_ENABLED(CONFIG_MODBUS_FP_EXTENSIONS) &&
		    (req_addr >= MODBUS_FP_EXTENSIONS_ADDR)) {
			err = mbc_validate_fc03fp_response(ctx, (float *)data);
			break;
		}
		__fallthrough;
	case MODBUS_FC04_IN_REG_RD:
		req_byte_cnt = req_qty * sizeof(uint16_t);
		if (req_byte_cnt != resp_byte_cnt) {
			LOG_ERR("Mismatch in the number of registers");
			err = -EINVAL;
		} else {
			for (uint16_t i = 0; i < req_qty; i++) {
				data_p16[i] = sys_get_be16(resp_data);
				resp_data += sizeof(uint16_t);
			}

			err = 0;
		}
		break;

	default:
		LOG_ERR("Validation not implemented for FC 0x%02x", fc);
		err = -ENOTSUP;
	}

	return err;
}

static int mbc_validate_fc08_response(struct modbus_context *ctx,
				      const uint8_t unit_id,
				      uint16_t *data)
{
	int err;
	uint16_t resp_sfunc;
	uint16_t resp_data;
	uint16_t req_sfunc;
	uint16_t req_data;

	if (data == NULL) {
		return -EINVAL;
	}

	req_sfunc = sys_get_be16(&ctx->tx_adu.data[0]);
	req_data = sys_get_be16(&ctx->tx_adu.data[2]);
	resp_sfunc = sys_get_be16(&ctx->rx_adu.data[0]);
	resp_data = sys_get_be16(&ctx->rx_adu.data[2]);

	if (req_sfunc != resp_sfunc) {
		LOG_ERR("Mismatch in the sub-function code");
		return -EINVAL;
	}

	switch (resp_sfunc) {
	case MODBUS_FC08_SUBF_QUERY:
	case MODBUS_FC08_SUBF_CLR_CTR:
		if (req_data != resp_data) {
			LOG_ERR("Request and response data are different");
			err = -EINVAL;
		} else {
			*data = resp_data;
			err = 0;
		}
		break;

	case MODBUS_FC08_SUBF_BUS_MSG_CTR:
	case MODBUS_FC08_SUBF_BUS_CRC_CTR:
	case MODBUS_FC08_SUBF_BUS_EXCEPT_CTR:
	case MODBUS_FC08_SUBF_SERVER_MSG_CTR:
	case MODBUS_FC08_SUBF_SERVER_NO_RESP_CTR:
		*data = resp_data;
		err = 0;
		break;

	default:
		err = -EINVAL;
	}

	return err;
}

static int mbc_validate_wr_response(struct modbus_context *ctx,
				    const uint8_t unit_id,
				    uint8_t fc)
{
	int err;
	uint16_t req_addr;
	uint16_t req_value;
	uint16_t resp_addr;
	uint16_t resp_value;

	req_addr = sys_get_be16(&ctx->tx_adu.data[0]);
	req_value = sys_get_be16(&ctx->tx_adu.data[2]);
	resp_addr = sys_get_be16(&ctx->rx_adu.data[0]);
	resp_value = sys_get_be16(&ctx->rx_adu.data[2]);

	switch (fc) {
	case MODBUS_FC05_COIL_WR:
	case MODBUS_FC06_HOLDING_REG_WR:
	case MODBUS_FC15_COILS_WR:
	case MODBUS_FC16_HOLDING_REGS_WR:
		if (req_addr != resp_addr || req_value != resp_value) {
			err = ENXIO;
		} else {
			err = 0;
		}
		break;

	default:
		LOG_ERR("Validation not implemented for FC 0x%02x", fc);
		err = -ENOTSUP;
	}

	return err;
}

static int mbc_send_cmd(struct modbus_context *ctx, const uint8_t unit_id,
			uint8_t fc, void *data)
{
	int err;

	ctx->tx_adu.unit_id = unit_id;
	ctx->tx_adu.fc = fc;

	err = modbus_tx_wait_rx_adu(ctx);
	if (err != 0) {
		return err;
	}

	err = mbc_validate_response_fc(ctx, unit_id, fc);
	if (err < 0) {
		LOG_ERR("Failed to validate unit ID or function code");
		return err;
	} else if (err > 0) {
		LOG_INF("Modbus FC %u, error code %u", fc, err);
		return err;
	}

	switch (fc) {
	case MODBUS_FC01_COIL_RD:
	case MODBUS_FC02_DI_RD:
	case MODBUS_FC03_HOLDING_REG_RD:
	case MODBUS_FC04_IN_REG_RD:
		err = mbc_validate_rd_response(ctx, unit_id, fc, data);
		break;

	case MODBUS_FC08_DIAGNOSTICS:
		err = mbc_validate_fc08_response(ctx, unit_id, data);
		break;

	case MODBUS_FC05_COIL_WR:
	case MODBUS_FC06_HOLDING_REG_WR:
	case MODBUS_FC15_COILS_WR:
	case MODBUS_FC16_HOLDING_REGS_WR:
		err = mbc_validate_wr_response(ctx, unit_id, fc);
		break;

	default:
		LOG_ERR("FC 0x%02x not implemented", fc);
		err = -ENOTSUP;
	}

	return err;
}

int modbus_read_coils(const int iface,
		      const uint8_t unit_id,
		      const uint16_t start_addr,
		      uint8_t *const coil_tbl,
		      const uint16_t num_coils)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(num_coils, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC01_COIL_RD, coil_tbl);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_read_dinputs(const int iface,
			const uint8_t unit_id,
			const uint16_t start_addr,
			uint8_t *const di_tbl,
			const uint16_t num_di)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(num_di, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC02_DI_RD, di_tbl);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_read_holding_regs(const int iface,
			     const uint8_t unit_id,
			     const uint16_t start_addr,
			     uint16_t *const reg_buf,
			     const uint16_t num_regs)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(num_regs, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC03_HOLDING_REG_RD, reg_buf);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}


#ifdef CONFIG_MODBUS_FP_EXTENSIONS
int modbus_read_holding_regs_fp(const int iface,
			       const uint8_t unit_id,
			       const uint16_t start_addr,
			       float *const reg_buf,
			       const uint16_t num_regs)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(num_regs, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC03_HOLDING_REG_RD, reg_buf);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}
#endif

int modbus_read_input_regs(const int iface,
			   const uint8_t unit_id,
			   const uint16_t start_addr,
			   uint16_t *const reg_buf,
			   const uint16_t num_regs)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(num_regs, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC04_IN_REG_RD, reg_buf);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_write_coil(const int iface,
		      const uint8_t unit_id,
		      const uint16_t coil_addr,
		      const bool coil_state)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;
	uint16_t coil_val;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	if (coil_state == false) {
		coil_val = MODBUS_COIL_OFF_CODE;
	} else {
		coil_val = MODBUS_COIL_ON_CODE;
	}

	ctx->tx_adu.length = 4;
	sys_put_be16(coil_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(coil_val, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC05_COIL_WR, NULL);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_write_holding_reg(const int iface,
			     const uint8_t unit_id,
			     const uint16_t start_addr,
			     const uint16_t reg_val)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	sys_put_be16(reg_val, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC06_HOLDING_REG_WR, NULL);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_request_diagnostic(const int iface,
			      const uint8_t unit_id,
			      const uint16_t sfunc,
			      const uint16_t data,
			      uint16_t *const data_out)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	ctx->tx_adu.length = 4;
	sys_put_be16(sfunc, &ctx->tx_adu.data[0]);
	sys_put_be16(data, &ctx->tx_adu.data[2]);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC08_DIAGNOSTICS, data_out);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_write_coils(const int iface,
		       const uint8_t unit_id,
		       const uint16_t start_addr,
		       uint8_t *const coil_tbl,
		       const uint16_t num_coils)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	size_t length = 0;
	uint8_t *data_ptr;
	size_t num_bytes;
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	length += sizeof(start_addr);
	sys_put_be16(num_coils, &ctx->tx_adu.data[2]);
	length += sizeof(num_coils);

	num_bytes = (uint8_t)(((num_coils - 1) / 8) + 1);
	ctx->tx_adu.data[4] = num_bytes;
	length += num_bytes + 1;

	if (length > sizeof(ctx->tx_adu.data)) {
		LOG_ERR("Length of data buffer is not sufficient");
		k_mutex_unlock(&ctx->iface_lock);
		return -ENOBUFS;
	}

	ctx->tx_adu.length = length;
	data_ptr = &ctx->tx_adu.data[5];

	memcpy(data_ptr, coil_tbl, num_bytes);

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC15_COILS_WR, NULL);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

int modbus_write_holding_regs(const int iface,
			      const uint8_t unit_id,
			      const uint16_t start_addr,
			      uint16_t *const reg_buf,
			      const uint16_t num_regs)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	size_t length = 0;
	uint8_t *data_ptr;
	size_t num_bytes;
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	length += sizeof(start_addr);
	sys_put_be16(num_regs, &ctx->tx_adu.data[2]);
	length += sizeof(num_regs);

	num_bytes = num_regs * sizeof(uint16_t);
	ctx->tx_adu.data[4] = num_bytes;
	length += num_bytes + 1;

	if (length > sizeof(ctx->tx_adu.data)) {
		LOG_ERR("Length of data buffer is not sufficient");
		k_mutex_unlock(&ctx->iface_lock);
		return -ENOBUFS;
	}

	ctx->tx_adu.length = length;
	data_ptr = &ctx->tx_adu.data[5];

	for (uint16_t i = 0; i < num_regs; i++) {
		sys_put_be16(reg_buf[i], data_ptr);
		data_ptr += sizeof(uint16_t);
	}

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC16_HOLDING_REGS_WR, NULL);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}

#ifdef CONFIG_MODBUS_FP_EXTENSIONS
int modbus_write_holding_regs_fp(const int iface,
				 const uint8_t unit_id,
				 const uint16_t start_addr,
				 float *const reg_buf,
				 const uint16_t num_regs)
{
	struct modbus_context *ctx = modbus_get_context(iface);
	size_t length = 0;
	uint8_t *data_ptr;
	size_t num_bytes;
	int err;

	if (ctx == NULL) {
		return -ENODEV;
	}

	k_mutex_lock(&ctx->iface_lock, K_FOREVER);

	sys_put_be16(start_addr, &ctx->tx_adu.data[0]);
	length += sizeof(start_addr);
	sys_put_be16(num_regs, &ctx->tx_adu.data[2]);
	length += sizeof(num_regs);

	num_bytes = num_regs * sizeof(float);
	ctx->tx_adu.data[4] = num_bytes;
	length += num_bytes + 1;

	if (length > sizeof(ctx->tx_adu.data)) {
		LOG_ERR("Length of data buffer is not sufficient");
		k_mutex_unlock(&ctx->iface_lock);
		return -ENOBUFS;
	}

	ctx->tx_adu.length = length;
	data_ptr = &ctx->tx_adu.data[5];

	for (uint16_t i = 0; i < num_regs; i++) {
		uint32_t reg_val;

		memcpy(&reg_val, &reg_buf[i], sizeof(reg_val));
		sys_put_be32(reg_val, data_ptr);
		data_ptr += sizeof(uint32_t);
	}

	err = mbc_send_cmd(ctx, unit_id, MODBUS_FC16_HOLDING_REGS_WR, NULL);
	k_mutex_unlock(&ctx->iface_lock);

	return err;
}
#endif
