/*
 * Copyright (c) 2019 Alexander Wachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "isotp_internal.h"
#include <zephyr/net/buf.h>
#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/sys/util.h>
#include <zephyr/logging/log.h>
#include <zephyr/timeout_q.h>

LOG_MODULE_REGISTER(isotp, CONFIG_ISOTP_LOG_LEVEL);

#ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS
K_MEM_SLAB_DEFINE(ctx_slab, sizeof(struct isotp_send_ctx),
		  CONFIG_ISOTP_TX_CONTEXT_BUF_COUNT, 4);
#endif

static void receive_pool_free(struct net_buf *buf);
static void receive_ff_sf_pool_free(struct net_buf *buf);

NET_BUF_POOL_DEFINE(isotp_rx_pool, CONFIG_ISOTP_RX_BUF_COUNT,
		    CONFIG_ISOTP_RX_BUF_SIZE, sizeof(uint32_t),
		    receive_pool_free);

NET_BUF_POOL_DEFINE(isotp_rx_sf_ff_pool, CONFIG_ISOTP_RX_SF_FF_BUF_COUNT,
		    ISOTP_CAN_DL, sizeof(uint32_t), receive_ff_sf_pool_free);

static struct isotp_global_ctx global_ctx = {
	.alloc_list = SYS_SLIST_STATIC_INIT(&global_ctx.alloc_list),
	.ff_sf_alloc_list = SYS_SLIST_STATIC_INIT(&global_ctx.ff_sf_alloc_list)
};

#ifdef CONFIG_ISOTP_USE_TX_BUF
NET_BUF_POOL_VAR_DEFINE(isotp_tx_pool, CONFIG_ISOTP_TX_BUF_COUNT,
			CONFIG_ISOTP_BUF_TX_DATA_POOL_SIZE, 0, NULL);
#endif

static void receive_state_machine(struct isotp_recv_ctx *ctx);

/*
 * Wake every context that is waiting for a buffer
 */
static void receive_pool_free(struct net_buf *buf)
{
	struct isotp_recv_ctx *ctx;
	sys_snode_t *ctx_node;

	net_buf_destroy(buf);

	SYS_SLIST_FOR_EACH_NODE(&global_ctx.alloc_list, ctx_node) {
		ctx = CONTAINER_OF(ctx_node, struct isotp_recv_ctx, alloc_node);
		k_work_submit(&ctx->work);
	}
}

static void receive_ff_sf_pool_free(struct net_buf *buf)
{
	struct isotp_recv_ctx *ctx;
	sys_snode_t *ctx_node;

	net_buf_destroy(buf);

	SYS_SLIST_FOR_EACH_NODE(&global_ctx.ff_sf_alloc_list, ctx_node) {
		ctx = CONTAINER_OF(ctx_node, struct isotp_recv_ctx, alloc_node);
		k_work_submit(&ctx->work);
	}
}

static inline void receive_report_error(struct isotp_recv_ctx *ctx, int err)
{
	ctx->state = ISOTP_RX_STATE_ERR;
	ctx->error_nr = err;
}

static void receive_can_tx(const struct device *dev, int error, void *arg)
{
	struct isotp_recv_ctx *ctx = (struct isotp_recv_ctx *)arg;

	ARG_UNUSED(dev);

	if (error != 0) {
		LOG_ERR("Error sending FC frame (%d)", error);
		receive_report_error(ctx, ISOTP_N_ERROR);
		k_work_submit(&ctx->work);
	}
}

static inline uint32_t receive_get_ff_length(struct net_buf *buf)
{
	uint32_t len;
	uint8_t pci = net_buf_pull_u8(buf);

	len = ((pci & ISOTP_PCI_FF_DL_UPPER_MASK) << 8) | net_buf_pull_u8(buf);

	/* Jumbo packet (32 bit length)*/
	if (!len) {
		len = net_buf_pull_be32(buf);
	}

	return len;
}

static inline uint32_t receive_get_sf_length(struct net_buf *buf)
{
	uint8_t len = net_buf_pull_u8(buf) & ISOTP_PCI_SF_DL_MASK;

	/* Single frames > 16 bytes (CAN-FD only) */
	if (IS_ENABLED(ISOTP_USE_CAN_FD) && !len) {
		len = net_buf_pull_u8(buf);
	}

	return len;
}

static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs)
{
	struct can_frame frame = {
		.id_type = ctx->tx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->tx_addr.ext_id
	};
	uint8_t *data = frame.data;
	uint8_t payload_len;
	int ret;

	__ASSERT_NO_MSG(!(fs & ISOTP_PCI_TYPE_MASK));

	if (ctx->tx_addr.use_ext_addr) {
		*data++ = ctx->tx_addr.ext_addr;
	}

	*data++ = ISOTP_PCI_TYPE_FC | fs;
	*data++ = ctx->opts.bs;
	*data++ = ctx->opts.stmin;
	payload_len = data - frame.data;

#if defined(CONFIG_ISOTP_REQUIRE_RX_PADDING) || \
				defined(CONFIG_ISOTP_ENABLE_TX_PADDING)
	/* AUTOSAR requirement SWS_CanTp_00347 */
	memset(&frame.data[payload_len], 0xCC, ISOTP_CAN_DL - payload_len);
	frame.dlc = ISOTP_CAN_DL;
#else
	frame.dlc = payload_len;
#endif

	ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A),
		       receive_can_tx, ctx);
	if (ret) {
		LOG_ERR("Can't send FC, (%d)", ret);
		receive_report_error(ctx, ISOTP_N_TIMEOUT_A);
		receive_state_machine(ctx);
	}
}

static inline struct net_buf *receive_alloc_buffer_chain(uint32_t len)
{
	struct net_buf *buf, *frag, *last;
	uint32_t remaining_len;

	LOG_DBG("Allocate %d bytes ", len);
	buf = net_buf_alloc_fixed(&isotp_rx_pool, K_NO_WAIT);
	if (!buf) {
		return NULL;
	}

	if (len <= CONFIG_ISOTP_RX_BUF_SIZE) {
		return buf;
	}

	remaining_len = len - CONFIG_ISOTP_RX_BUF_SIZE;
	last = buf;
	while (remaining_len) {
		frag = net_buf_alloc_fixed(&isotp_rx_pool, K_NO_WAIT);
		if (!frag) {
			net_buf_unref(buf);
			return NULL;
		}

		net_buf_frag_insert(last, frag);
		last = frag;
		remaining_len = remaining_len > CONFIG_ISOTP_RX_BUF_SIZE ?
				remaining_len - CONFIG_ISOTP_RX_BUF_SIZE : 0;
	}

	return buf;
}

static void receive_timeout_handler(struct _timeout *to)
{
	struct isotp_recv_ctx *ctx = CONTAINER_OF(to, struct isotp_recv_ctx,
						  timeout);

	switch (ctx->state) {
	case ISOTP_RX_STATE_WAIT_CF:
		LOG_ERR("Timeout while waiting for CF");
		receive_report_error(ctx, ISOTP_N_TIMEOUT_CR);
		break;

	case ISOTP_RX_STATE_TRY_ALLOC:
		ctx->state = ISOTP_RX_STATE_SEND_WAIT;
		break;
	}

	k_work_submit(&ctx->work);
}

static int receive_alloc_buffer(struct isotp_recv_ctx *ctx)
{
	struct net_buf *buf = NULL;

	if (ctx->opts.bs == 0) {
		/* Alloc all buffers because we can't wait during reception */
		buf = receive_alloc_buffer_chain(ctx->length);
	} else {
		buf = receive_alloc_buffer_chain(ctx->opts.bs *
						 (ISOTP_CAN_DL - 1));
	}

	if (!buf) {
		z_add_timeout(&ctx->timeout, receive_timeout_handler,
			      K_MSEC(ISOTP_ALLOC_TIMEOUT));

		if (ctx->wft == ISOTP_WFT_FIRST) {
			LOG_DBG("Allocation failed. Append to alloc list");
			ctx->wft = 0;
			sys_slist_append(&global_ctx.alloc_list,
					 &ctx->alloc_node);
		} else {
			LOG_DBG("Allocation failed. Send WAIT frame");
			ctx->state = ISOTP_RX_STATE_SEND_WAIT;
			receive_state_machine(ctx);
		}

		return -1;
	}

	if (ctx->state == ISOTP_RX_STATE_TRY_ALLOC) {
		z_abort_timeout(&ctx->timeout);
		ctx->wft = ISOTP_WFT_FIRST;
		sys_slist_find_and_remove(&global_ctx.alloc_list,
					  &ctx->alloc_node);
	}

	if (ctx->opts.bs != 0) {
		ctx->buf = buf;
	} else {
		net_buf_frag_insert(ctx->buf, buf);
	}

	ctx->act_frag = buf;
	return 0;
}

static void receive_state_machine(struct isotp_recv_ctx *ctx)
{
	int ret;
	uint32_t *ud_rem_len;

	switch (ctx->state) {
	case ISOTP_RX_STATE_PROCESS_SF:
		ctx->length = receive_get_sf_length(ctx->buf);
		ud_rem_len = net_buf_user_data(ctx->buf);
		*ud_rem_len = 0;
		LOG_DBG("SM process SF of length %d", ctx->length);
		net_buf_put(&ctx->fifo, ctx->buf);
		ctx->state = ISOTP_RX_STATE_RECYCLE;
		receive_state_machine(ctx);
		break;

	case ISOTP_RX_STATE_PROCESS_FF:
		ctx->length = receive_get_ff_length(ctx->buf);
		LOG_DBG("SM process FF. Length: %d", ctx->length);
		ctx->length -= ctx->buf->len;
		if (ctx->opts.bs == 0 &&
		    ctx->length > CONFIG_ISOTP_RX_BUF_COUNT *
		    CONFIG_ISOTP_RX_BUF_SIZE) {
			LOG_ERR("Pkt length is %d but buffer has only %d bytes",
				ctx->length,
				CONFIG_ISOTP_RX_BUF_COUNT *
				CONFIG_ISOTP_RX_BUF_SIZE);
			receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW);
			receive_state_machine(ctx);
			break;
		}

		if (ctx->opts.bs) {
			ctx->bs = ctx->opts.bs;
			ud_rem_len = net_buf_user_data(ctx->buf);
			*ud_rem_len = ctx->length;
			net_buf_put(&ctx->fifo, ctx->buf);
		}

		ctx->wft = ISOTP_WFT_FIRST;
		ctx->state = ISOTP_RX_STATE_TRY_ALLOC;
		__fallthrough;
	case ISOTP_RX_STATE_TRY_ALLOC:
		LOG_DBG("SM try to allocate");
		z_abort_timeout(&ctx->timeout);
		ret = receive_alloc_buffer(ctx);
		if (ret) {
			LOG_DBG("SM allocation failed. Wait for free buffer");
			break;
		}

		ctx->state = ISOTP_RX_STATE_SEND_FC;
		__fallthrough;
	case ISOTP_RX_STATE_SEND_FC:
		LOG_DBG("SM send CTS FC frame");
		receive_send_fc(ctx, ISOTP_PCI_FS_CTS);
		z_add_timeout(&ctx->timeout, receive_timeout_handler,
			      K_MSEC(ISOTP_CR));
		ctx->state = ISOTP_RX_STATE_WAIT_CF;
		break;

	case ISOTP_RX_STATE_SEND_WAIT:
		if (++ctx->wft < CONFIG_ISOTP_WFTMAX) {
			LOG_DBG("Send wait frame number %d", ctx->wft);
			receive_send_fc(ctx, ISOTP_PCI_FS_WAIT);
			z_add_timeout(&ctx->timeout, receive_timeout_handler,
				      K_MSEC(ISOTP_ALLOC_TIMEOUT));
			ctx->state = ISOTP_RX_STATE_TRY_ALLOC;
			break;
		}

		sys_slist_find_and_remove(&global_ctx.alloc_list,
					  &ctx->alloc_node);
		LOG_ERR("Sent %d wait frames. Giving up to alloc now",
			ctx->wft);
		receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW);
		__fallthrough;
	case ISOTP_RX_STATE_ERR:
		LOG_DBG("SM ERR state. err nr: %d", ctx->error_nr);
		z_abort_timeout(&ctx->timeout);

		if (ctx->error_nr == ISOTP_N_BUFFER_OVERFLW) {
			receive_send_fc(ctx, ISOTP_PCI_FS_OVFLW);
		}

		k_fifo_cancel_wait(&ctx->fifo);
		net_buf_unref(ctx->buf);
		ctx->buf = NULL;
		ctx->state = ISOTP_RX_STATE_RECYCLE;
		__fallthrough;
	case ISOTP_RX_STATE_RECYCLE:
		LOG_DBG("SM recycle context for next message");
		ctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, K_NO_WAIT);
		if (!ctx->buf) {
			LOG_DBG("No free context. Append to waiters list");
			sys_slist_append(&global_ctx.ff_sf_alloc_list,
					 &ctx->alloc_node);
			break;
		}

		sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list,
					  &ctx->alloc_node);
		ctx->state = ISOTP_RX_STATE_WAIT_FF_SF;
		__fallthrough;
	case ISOTP_RX_STATE_UNBOUND:
		break;

	default:
		break;
	}
}

static void receive_work_handler(struct k_work *item)
{
	struct isotp_recv_ctx *ctx = CONTAINER_OF(item, struct isotp_recv_ctx,
						  work);

	receive_state_machine(ctx);
}

static void process_ff_sf(struct isotp_recv_ctx *ctx, struct can_frame *frame)
{
	int index = 0;
	uint8_t payload_len;
	uint32_t rx_sa;		/* ISO-TP fixed source address (if used) */

	if (ctx->rx_addr.use_ext_addr) {
		if (frame->data[index++] != ctx->rx_addr.ext_addr) {
			return;
		}
	}

	if (ctx->rx_addr.use_fixed_addr) {
		/* store actual CAN ID used by the sender */
		ctx->rx_addr.ext_id = frame->id;
		/* replace TX target address with RX source address */
		rx_sa = (frame->id & ISOTP_FIXED_ADDR_SA_MASK) >>
		     ISOTP_FIXED_ADDR_SA_POS;
		ctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_TA_MASK);
		ctx->tx_addr.ext_id |= rx_sa << ISOTP_FIXED_ADDR_TA_POS;
		/* use same priority for TX as in received message */
		ctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_PRIO_MASK);
		ctx->tx_addr.ext_id |= frame->id & ISOTP_FIXED_ADDR_PRIO_MASK;
	}

	switch (frame->data[index] & ISOTP_PCI_TYPE_MASK) {
	case ISOTP_PCI_TYPE_FF:
		LOG_DBG("Got FF IRQ");
		if (frame->dlc != ISOTP_CAN_DL) {
			LOG_INF("FF DLC invalid. Ignore");
			return;
		}

		payload_len = ISOTP_CAN_DL;
		ctx->state = ISOTP_RX_STATE_PROCESS_FF;
		ctx->sn_expected = 1;
		break;

	case ISOTP_PCI_TYPE_SF:
		LOG_DBG("Got SF IRQ");
#ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING
		/* AUTOSAR requirement SWS_CanTp_00345 */
		if (frame->dlc != ISOTP_CAN_DL) {
			LOG_INF("SF DLC invalid. Ignore");
			return;
		}
#endif

		payload_len = index + 1 + (frame->data[index] &
						ISOTP_PCI_SF_DL_MASK);

		if (payload_len > frame->dlc) {
			LOG_INF("SF DL does not fit. Ignore");
			return;
		}

		ctx->state = ISOTP_RX_STATE_PROCESS_SF;
		break;

	default:
		LOG_INF("Got unexpected frame. Ignore");
		return;
	}

	net_buf_add_mem(ctx->buf, &frame->data[index], payload_len - index);
}

static inline void receive_add_mem(struct isotp_recv_ctx *ctx, uint8_t *data,
				   size_t len)
{
	size_t tailroom = net_buf_tailroom(ctx->act_frag);

	if (tailroom >= len) {
		net_buf_add_mem(ctx->act_frag, data, len);
		return;
	}

	/* Use next fragment that is already allocated*/
	net_buf_add_mem(ctx->act_frag, data, tailroom);
	ctx->act_frag = ctx->act_frag->frags;
	if (!ctx->act_frag) {
		LOG_ERR("No fragment left to append data");
		receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW);
		return;
	}

	net_buf_add_mem(ctx->act_frag, data + tailroom, len - tailroom);
}

static void process_cf(struct isotp_recv_ctx *ctx, struct can_frame *frame)
{
	uint32_t *ud_rem_len = (uint32_t *)net_buf_user_data(ctx->buf);
	int index = 0;
	uint32_t data_len;

	if (ctx->rx_addr.use_ext_addr) {
		if (frame->data[index++] != ctx->rx_addr.ext_addr) {
			return;
		}
	}

	if ((frame->data[index] & ISOTP_PCI_TYPE_MASK) != ISOTP_PCI_TYPE_CF) {
		LOG_DBG("Waiting for CF but got something else (%d)",
			frame->data[index] >> ISOTP_PCI_TYPE_POS);
		receive_report_error(ctx, ISOTP_N_UNEXP_PDU);
		k_work_submit(&ctx->work);
		return;
	}

	z_abort_timeout(&ctx->timeout);
	z_add_timeout(&ctx->timeout, receive_timeout_handler,
		      K_MSEC(ISOTP_CR));

	if ((frame->data[index++] & ISOTP_PCI_SN_MASK) != ctx->sn_expected++) {
		LOG_ERR("Sequence number mismatch");
		receive_report_error(ctx, ISOTP_N_WRONG_SN);
		k_work_submit(&ctx->work);
		return;
	}

#ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING
	/* AUTOSAR requirement SWS_CanTp_00346 */
	if (frame->dlc != ISOTP_CAN_DL) {
		LOG_ERR("CF DL invalid");
		receive_report_error(ctx, ISOTP_N_ERROR);
		return;
	}
#endif

	LOG_DBG("Got CF irq. Appending data");
	data_len = (ctx->length > frame->dlc - index) ? frame->dlc - index :
		ctx->length;
	receive_add_mem(ctx, &frame->data[index], data_len);
	ctx->length -= data_len;
	LOG_DBG("%d bytes remaining", ctx->length);

	if (ctx->length == 0) {
		ctx->state = ISOTP_RX_STATE_RECYCLE;
		*ud_rem_len = 0;
		net_buf_put(&ctx->fifo, ctx->buf);
		return;
	}

	if (ctx->opts.bs && !--ctx->bs) {
		LOG_DBG("Block is complete. Allocate new buffer");
		ctx->bs = ctx->opts.bs;
		*ud_rem_len = ctx->length;
		net_buf_put(&ctx->fifo, ctx->buf);
		ctx->state = ISOTP_RX_STATE_TRY_ALLOC;
	}
}

static void receive_can_rx(const struct device *dev, struct can_frame *frame, void *arg)
{
	struct isotp_recv_ctx *ctx = (struct isotp_recv_ctx *)arg;

	ARG_UNUSED(dev);

	switch (ctx->state) {
	case ISOTP_RX_STATE_WAIT_FF_SF:
		__ASSERT_NO_MSG(ctx->buf);
		process_ff_sf(ctx, frame);
		break;

	case ISOTP_RX_STATE_WAIT_CF:
		process_cf(ctx, frame);
		/* still waiting for more CF */
		if (ctx->state == ISOTP_RX_STATE_WAIT_CF) {
			return;
		}

		break;

	case ISOTP_RX_STATE_RECYCLE:
		LOG_ERR("Got a frame but was not yet ready for a new one");
		receive_report_error(ctx, ISOTP_N_BUFFER_OVERFLW);
		break;

	default:
		LOG_INF("Got a frame in a state where it is unexpected.");
	}

	k_work_submit(&ctx->work);
}

static inline int attach_ff_filter(struct isotp_recv_ctx *ctx)
{
	uint32_t mask;

	if (ctx->rx_addr.use_fixed_addr) {
		mask = ISOTP_FIXED_ADDR_RX_MASK;
	} else {
		mask = CAN_EXT_ID_MASK;
	}

	struct can_filter filter = {
		.id_type = ctx->rx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->rx_addr.ext_id,
		.rtr_mask = 1,
		.id_mask = mask
	};

	ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx,
					   &filter);
	if (ctx->filter_id < 0) {
		LOG_ERR("Error attaching FF filter [%d]", ctx->filter_id);
		return ISOTP_NO_FREE_FILTER;
	}

	return 0;
}

int isotp_bind(struct isotp_recv_ctx *ctx, const struct device *can_dev,
	       const struct isotp_msg_id *rx_addr,
	       const struct isotp_msg_id *tx_addr,
	       const struct isotp_fc_opts *opts,
	       k_timeout_t timeout)
{
	int ret;

	__ASSERT(ctx, "ctx is NULL");
	__ASSERT(can_dev, "CAN device is NULL");
	__ASSERT(rx_addr && tx_addr, "RX or TX addr is NULL");
	__ASSERT(opts, "OPTS is NULL");

	ctx->can_dev = can_dev;
	ctx->rx_addr = *rx_addr;
	ctx->tx_addr = *tx_addr;
	k_fifo_init(&ctx->fifo);

	__ASSERT(opts->stmin < ISOTP_STMIN_MAX, "STmin limit");
	__ASSERT(opts->stmin <= ISOTP_STMIN_MS_MAX ||
		 opts->stmin >= ISOTP_STMIN_US_BEGIN, "STmin reserved");

	ctx->opts = *opts;
	ctx->state = ISOTP_RX_STATE_WAIT_FF_SF;

	LOG_DBG("Binding to addr: 0x%x. Responding on 0x%x",
		ctx->rx_addr.ext_id, ctx->tx_addr.ext_id);

	ctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, timeout);
	if (!ctx->buf) {
		LOG_ERR("No buffer for FF left");
		return ISOTP_NO_NET_BUF_LEFT;
	}

	ret = attach_ff_filter(ctx);
	if (ret) {
		LOG_ERR("Can't attach filter for binding");
		net_buf_unref(ctx->buf);
		ctx->buf = NULL;
		return ret;
	}

	k_work_init(&ctx->work, receive_work_handler);
	z_init_timeout(&ctx->timeout);

	return ISOTP_N_OK;
}

void isotp_unbind(struct isotp_recv_ctx *ctx)
{
	struct net_buf *buf;

	if (ctx->filter_id >= 0 && ctx->can_dev) {
		can_remove_rx_filter(ctx->can_dev, ctx->filter_id);
	}

	z_abort_timeout(&ctx->timeout);

	sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list,
				  &ctx->alloc_node);
	sys_slist_find_and_remove(&global_ctx.alloc_list,
				  &ctx->alloc_node);

	ctx->state = ISOTP_RX_STATE_UNBOUND;

	while ((buf = net_buf_get(&ctx->fifo, K_NO_WAIT))) {
		net_buf_unref(buf);
	}

	k_fifo_cancel_wait(&ctx->fifo);

	if (ctx->buf) {
		net_buf_unref(ctx->buf);
	}

	LOG_DBG("Unbound");
}

int isotp_recv_net(struct isotp_recv_ctx *ctx, struct net_buf **buffer,
		   k_timeout_t timeout)
{
	struct net_buf *buf;
	int ret;

	buf = net_buf_get(&ctx->fifo, timeout);
	if (!buf) {
		ret = ctx->error_nr ? ctx->error_nr : ISOTP_RECV_TIMEOUT;
		ctx->error_nr = 0;

		return ret;
	}

	*buffer = buf;

	return *(uint32_t *)net_buf_user_data(buf);
}

int isotp_recv(struct isotp_recv_ctx *ctx, uint8_t *data, size_t len,
	       k_timeout_t timeout)
{
	size_t copied, to_copy;
	int err;

	if (!ctx->recv_buf) {
		ctx->recv_buf = net_buf_get(&ctx->fifo, timeout);
		if (!ctx->recv_buf) {
			err = ctx->error_nr ? ctx->error_nr : ISOTP_RECV_TIMEOUT;
			ctx->error_nr = 0;

			return err;
		}
	}

	/* traverse fragments and delete them after copying the data */
	copied = 0;
	while (ctx->recv_buf && copied < len) {
		to_copy = MIN(len - copied, ctx->recv_buf->len);
		memcpy((uint8_t *)data + copied, ctx->recv_buf->data, to_copy);

		if (ctx->recv_buf->len == to_copy) {
			/* point recv_buf to next frag */
			ctx->recv_buf = net_buf_frag_del(NULL, ctx->recv_buf);
		} else {
			/* pull received data from remaining frag(s) */
			net_buf_pull(ctx->recv_buf, to_copy);
		}

		copied += to_copy;
	}

	return copied;
}

static inline void send_report_error(struct isotp_send_ctx *ctx, uint32_t err)
{
	ctx->state = ISOTP_TX_ERR;
	ctx->error_nr = err;
}

static void send_can_tx_cb(const struct device *dev, int error, void *arg)
{
	struct isotp_send_ctx *ctx = (struct isotp_send_ctx *)arg;

	ARG_UNUSED(dev);

	ctx->tx_backlog--;
	k_sem_give(&ctx->tx_sem);

	if (ctx->state == ISOTP_TX_WAIT_BACKLOG) {
		if (ctx->tx_backlog > 0) {
			return;
		}

		ctx->state = ISOTP_TX_WAIT_FIN;
	}

	k_work_submit(&ctx->work);
}

static void send_timeout_handler(struct _timeout *to)
{
	struct isotp_send_ctx *ctx = CONTAINER_OF(to, struct isotp_send_ctx,
						  timeout);

	if (ctx->state != ISOTP_TX_SEND_CF) {
		send_report_error(ctx, ISOTP_N_TIMEOUT_BS);
		LOG_ERR("Reception of next FC has timed out");
	}

	k_work_submit(&ctx->work);
}

static void send_process_fc(struct isotp_send_ctx *ctx,
			    struct can_frame *frame)
{
	uint8_t *data = frame->data;

	if (ctx->rx_addr.use_ext_addr) {
		if (ctx->rx_addr.ext_addr != *data++) {
			return;
		}
	}

	if ((*data & ISOTP_PCI_TYPE_MASK) != ISOTP_PCI_TYPE_FC) {
		LOG_ERR("Got unexpected PDU expected FC");
		send_report_error(ctx, ISOTP_N_UNEXP_PDU);
		return;
	}

#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING
	/* AUTOSAR requirement SWS_CanTp_00349 */
	if (frame->dlc != ISOTP_CAN_DL) {
		LOG_ERR("FC DL invalid. Ignore");
		send_report_error(ctx, ISOTP_N_ERROR);
		return;
	}
#endif

	switch (*data++ & ISOTP_PCI_FS_MASK) {
	case ISOTP_PCI_FS_CTS:
		ctx->state = ISOTP_TX_SEND_CF;
		ctx->wft = 0;
		ctx->tx_backlog = 0;
		k_sem_reset(&ctx->tx_sem);
		ctx->opts.bs = *data++;
		ctx->opts.stmin = *data++;
		ctx->bs = ctx->opts.bs;
		LOG_DBG("Got CTS. BS: %d, STmin: %d", ctx->opts.bs,
			ctx->opts.stmin);
		break;

	case ISOTP_PCI_FS_WAIT:
		LOG_DBG("Got WAIT frame");
		z_abort_timeout(&ctx->timeout);
		z_add_timeout(&ctx->timeout, send_timeout_handler,
			      K_MSEC(ISOTP_BS));
		if (ctx->wft >= CONFIG_ISOTP_WFTMAX) {
			LOG_INF("Got to many wait frames");
			send_report_error(ctx, ISOTP_N_WFT_OVRN);
		}

		ctx->wft++;
		break;

	case ISOTP_PCI_FS_OVFLW:
		LOG_ERR("Got overflow FC frame");
		send_report_error(ctx, ISOTP_N_BUFFER_OVERFLW);
		break;

	default:
		send_report_error(ctx, ISOTP_N_INVALID_FS);
	}
}

static void send_can_rx_cb(const struct device *dev, struct can_frame *frame, void *arg)
{
	struct isotp_send_ctx *ctx = (struct isotp_send_ctx *)arg;

	ARG_UNUSED(dev);

	if (ctx->state == ISOTP_TX_WAIT_FC) {
		z_abort_timeout(&ctx->timeout);
		send_process_fc(ctx, frame);
	} else {
		LOG_ERR("Got unexpected PDU");
		send_report_error(ctx, ISOTP_N_UNEXP_PDU);
	}

	k_work_submit(&ctx->work);
}

static size_t get_ctx_data_length(struct isotp_send_ctx *ctx)
{
	return ctx->is_net_buf ? net_buf_frags_len(ctx->buf) : ctx->len;
}

static const uint8_t *get_data_ctx(struct isotp_send_ctx *ctx)
{
	if (ctx->is_net_buf) {
		return ctx->buf->data;
	} else {
		return ctx->data;
	}
}

static void pull_data_ctx(struct isotp_send_ctx *ctx, size_t len)
{
	if (ctx->is_net_buf) {
		net_buf_pull_mem(ctx->buf, len);
	} else {
		ctx->data += len;
		ctx->len -= len;
	}
}

static inline int send_sf(struct isotp_send_ctx *ctx)
{
	struct can_frame frame = {
		.id_type = ctx->tx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->tx_addr.ext_id
	};
	size_t len = get_ctx_data_length(ctx);
	int index = 0;
	int ret;
	const uint8_t *data;

	data = get_data_ctx(ctx);
	pull_data_ctx(ctx, len);

	if (ctx->tx_addr.use_ext_addr) {
		frame.data[index++] = ctx->tx_addr.ext_addr;
	}

	frame.data[index++] = ISOTP_PCI_TYPE_SF | len;

	__ASSERT_NO_MSG(len <= ISOTP_CAN_DL - index);
	memcpy(&frame.data[index], data, len);

#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING
	/* AUTOSAR requirement SWS_CanTp_00348 */
	memset(&frame.data[index + len], 0xCC, ISOTP_CAN_DL - len - index);
	frame.dlc = ISOTP_CAN_DL;
#else
	frame.dlc = len + index;
#endif

	ctx->state = ISOTP_TX_SEND_SF;
	ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A),
		       send_can_tx_cb, ctx);
	return ret;
}

static inline int send_ff(struct isotp_send_ctx *ctx)
{
	struct can_frame frame = {
		.id_type = ctx->tx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->tx_addr.ext_id,
		.dlc = ISOTP_CAN_DL
	};
	int index = 0;
	size_t len = get_ctx_data_length(ctx);
	int ret;
	const uint8_t *data;

	if (ctx->tx_addr.use_ext_addr) {
		frame.data[index++] = ctx->tx_addr.ext_addr;
	}

	if (len > 0xFFF) {
		frame.data[index++] = ISOTP_PCI_TYPE_FF;
		frame.data[index++] = 0;
		frame.data[index++] = (len >> 3 * 8) & 0xFF;
		frame.data[index++] = (len >> 2 * 8) & 0xFF;
		frame.data[index++] = (len >>   8) & 0xFF;
		frame.data[index++] = len & 0xFF;
	} else {
		frame.data[index++] = ISOTP_PCI_TYPE_FF | (len >> 8);
		frame.data[index++] = len & 0xFF;
	}

	/* According to ISO FF has sn 0 and is incremented to one
	 * although it's not part of the FF frame
	 */
	ctx->sn = 1;
	data = get_data_ctx(ctx);
	pull_data_ctx(ctx, ISOTP_CAN_DL - index);
	memcpy(&frame.data[index], data, ISOTP_CAN_DL - index);

	ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A),
		       send_can_tx_cb, ctx);
	return ret;
}

static inline int send_cf(struct isotp_send_ctx *ctx)
{
	struct can_frame frame = {
		.id_type = ctx->tx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->tx_addr.ext_id,
	};
	int index = 0;
	int ret;
	int len;
	int rem_len;
	const uint8_t *data;

	if (ctx->tx_addr.use_ext_addr) {
		frame.data[index++] = ctx->tx_addr.ext_addr;
	}

	/*sn wraps around at 0xF automatically because it has a 4 bit size*/
	frame.data[index++] = ISOTP_PCI_TYPE_CF | ctx->sn;

	rem_len = get_ctx_data_length(ctx);
	len = MIN(rem_len, ISOTP_CAN_DL - index);
	rem_len -= len;
	data = get_data_ctx(ctx);
	memcpy(&frame.data[index], data, len);

#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING
	/* AUTOSAR requirement SWS_CanTp_00348 */
	memset(&frame.data[index + len], 0xCC, ISOTP_CAN_DL - len - index);
	frame.dlc = ISOTP_CAN_DL;
#else
	frame.dlc = len + index;
#endif

	ret = can_send(ctx->can_dev, &frame, K_MSEC(ISOTP_A),
		       send_can_tx_cb, ctx);
	if (ret == 0) {
		ctx->sn++;
		pull_data_ctx(ctx, len);
		ctx->bs--;
		ctx->tx_backlog++;
	}

	ret = ret ? ret : rem_len;
	return ret;
}

#ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS
static inline void free_send_ctx(struct isotp_send_ctx **ctx)
{
	if ((*ctx)->is_net_buf) {
		net_buf_unref((*ctx)->buf);
		(*ctx)->buf = NULL;
	}

	if ((*ctx)->is_ctx_slab) {
		k_mem_slab_free(&ctx_slab, (void **)ctx);
	}
}

static int alloc_ctx(struct isotp_send_ctx **ctx, k_timeout_t timeout)
{
	int ret;

	ret = k_mem_slab_alloc(&ctx_slab, (void **)ctx, timeout);
	if (ret) {
		return ISOTP_NO_CTX_LEFT;
	}

	(*ctx)->is_ctx_slab = 1;

	return 0;
}
#else
#define free_send_ctx(x)
#endif /*CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS*/

static k_timeout_t stmin_to_ticks(uint8_t stmin)
{
	/* According to ISO 15765-2 stmin should be 127ms if value is corrupt */
	if (stmin > ISOTP_STMIN_MAX ||
	    (stmin > ISOTP_STMIN_MS_MAX && stmin < ISOTP_STMIN_US_BEGIN)) {
		return K_MSEC(ISOTP_STMIN_MS_MAX);
	}

	if (stmin >= ISOTP_STMIN_US_BEGIN) {
		return K_USEC((stmin + 1 - ISOTP_STMIN_US_BEGIN) * 100U);
	}

	return K_MSEC(stmin);
}

static void send_state_machine(struct isotp_send_ctx *ctx)
{
	int ret;

	switch (ctx->state) {

	case ISOTP_TX_SEND_FF:
		send_ff(ctx);
		z_add_timeout(&ctx->timeout, send_timeout_handler,
			      K_MSEC(ISOTP_BS));
		ctx->state = ISOTP_TX_WAIT_FC;
		LOG_DBG("SM send FF");
		break;

	case ISOTP_TX_SEND_CF:
		LOG_DBG("SM send CF");
		z_abort_timeout(&ctx->timeout);
		do {
			ret = send_cf(ctx);
			if (!ret) {
				ctx->state = ISOTP_TX_WAIT_BACKLOG;
				break;
			}

			if (ret < 0) {
				LOG_ERR("Failed to send CF");
				send_report_error(ctx, ret == -EAGAIN ?
						ISOTP_N_TIMEOUT_A :
						ISOTP_N_ERROR);
				break;
			}

			if (ctx->opts.bs && !ctx->bs) {
				z_add_timeout(&ctx->timeout,
					      send_timeout_handler,
					      K_MSEC(ISOTP_BS));
				ctx->state = ISOTP_TX_WAIT_FC;
				LOG_DBG("BS reached. Wait for FC again");
				break;
			} else if (ctx->opts.stmin) {
				ctx->state = ISOTP_TX_WAIT_ST;
				break;
			}

			/* Ensure FIFO style transmission of CF */
			k_sem_take(&ctx->tx_sem, K_FOREVER);
		} while (ret > 0);

		break;

	case ISOTP_TX_WAIT_ST:
		z_add_timeout(&ctx->timeout, send_timeout_handler,
			      stmin_to_ticks(ctx->opts.stmin));
		ctx->state = ISOTP_TX_SEND_CF;
		LOG_DBG("SM wait ST");
		break;

	case ISOTP_TX_ERR:
		LOG_DBG("SM error");
		__fallthrough;
	case ISOTP_TX_WAIT_FIN:
		if (ctx->filter_id >= 0) {
			can_remove_rx_filter(ctx->can_dev, ctx->filter_id);
		}

		LOG_DBG("SM finish");
		z_abort_timeout(&ctx->timeout);

		if (ctx->has_callback) {
			ctx->fin_cb.cb(ctx->error_nr, ctx->fin_cb.arg);
			free_send_ctx(&ctx);
		} else {
			k_sem_give(&ctx->fin_sem);
		}

		ctx->state = ISOTP_TX_STATE_RESET;
		break;

	default:
		break;
	}
}

static void send_work_handler(struct k_work *item)
{
	struct isotp_send_ctx *ctx = CONTAINER_OF(item, struct isotp_send_ctx,
						  work);

	send_state_machine(ctx);
}

static inline int attach_fc_filter(struct isotp_send_ctx *ctx)
{
	struct can_filter filter = {
		.id_type = ctx->rx_addr.id_type,
		.rtr = CAN_DATAFRAME,
		.id = ctx->rx_addr.ext_id,
		.rtr_mask = 1,
		.id_mask = CAN_EXT_ID_MASK
	};

	ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx,
					   &filter);
	if (ctx->filter_id < 0) {
		LOG_ERR("Error attaching FC filter [%d]", ctx->filter_id);
		return ISOTP_NO_FREE_FILTER;
	}

	return 0;
}

static int send(struct isotp_send_ctx *ctx, const struct device *can_dev,
		const struct isotp_msg_id *tx_addr,
		const struct isotp_msg_id *rx_addr,
		isotp_tx_callback_t complete_cb, void *cb_arg)
{
	size_t len;
	int ret;

	__ASSERT_NO_MSG(ctx);
	__ASSERT_NO_MSG(can_dev);
	__ASSERT_NO_MSG(rx_addr && tx_addr);

	if (complete_cb) {
		ctx->fin_cb.cb = complete_cb;
		ctx->fin_cb.arg = cb_arg;
		ctx->has_callback = 1;
	} else {
		k_sem_init(&ctx->fin_sem, 0, 1);
		ctx->has_callback = 0;
	}

	k_sem_init(&ctx->tx_sem, 0, 1);
	ctx->can_dev = can_dev;
	ctx->tx_addr = *tx_addr;
	ctx->rx_addr = *rx_addr;
	ctx->error_nr = ISOTP_N_OK;
	ctx->wft = 0;
	k_work_init(&ctx->work, send_work_handler);
	z_init_timeout(&ctx->timeout);

	len = get_ctx_data_length(ctx);
	LOG_DBG("Send %d bytes to addr 0x%x and listen on 0x%x", len,
		ctx->tx_addr.ext_id, ctx->rx_addr.ext_id);
	if (len > ISOTP_CAN_DL - (tx_addr->use_ext_addr ? 2 : 1)) {
		ret = attach_fc_filter(ctx);
		if (ret) {
			LOG_ERR("Can't attach fc filter: %d", ret);
			return ret;
		}

		LOG_DBG("Starting work to send FF");
		ctx->state = ISOTP_TX_SEND_FF;
		k_work_submit(&ctx->work);
	} else {
		LOG_DBG("Sending single frame");
		ctx->filter_id = -1;
		ret = send_sf(ctx);
		ctx->state = ISOTP_TX_WAIT_FIN;
		if (ret) {
			return ret == -EAGAIN ?
			       ISOTP_N_TIMEOUT_A : ISOTP_N_ERROR;
		}
	}

	if (!complete_cb) {
		k_sem_take(&ctx->fin_sem, K_FOREVER);
		ret = ctx->error_nr;
		free_send_ctx(&ctx);
		return ret;
	}

	return ISOTP_N_OK;
}

int isotp_send(struct isotp_send_ctx *ctx, const struct device *can_dev,
	       const uint8_t *data, size_t len,
	       const struct isotp_msg_id *tx_addr,
	       const struct isotp_msg_id *rx_addr,
	       isotp_tx_callback_t complete_cb, void *cb_arg)
{
	ctx->data = data;
	ctx->len = len;
	ctx->is_ctx_slab = 0;
	ctx->is_net_buf = 0;

	return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg);
}

#ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS

int isotp_send_ctx_buf(const struct device *can_dev,
		       const uint8_t *data, size_t len,
		       const struct isotp_msg_id *tx_addr,
		       const struct isotp_msg_id *rx_addr,
		       isotp_tx_callback_t complete_cb, void *cb_arg,
		       k_timeout_t timeout)
{
	struct isotp_send_ctx *ctx;
	int ret;

	__ASSERT_NO_MSG(data);

	ret = alloc_ctx(&ctx, timeout);
	if (ret) {
		return ret;
	}

	ctx->data = data;
	ctx->len = len;
	ctx->is_net_buf = 0;

	return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg);
}

int isotp_send_net_ctx_buf(const struct device *can_dev,
			   struct net_buf *data,
			   const struct isotp_msg_id *tx_addr,
			   const struct isotp_msg_id *rx_addr,
			   isotp_tx_callback_t complete_cb, void *cb_arg,
			   k_timeout_t timeout)
{
	struct isotp_send_ctx *ctx;
	int ret;

	__ASSERT_NO_MSG(data);

	ret = alloc_ctx(&ctx, timeout);
	if (ret) {
		return ret;
	}

	ctx->is_net_buf = 1;
	ctx->buf = data;

	return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg);
}

#ifdef CONFIG_ISOTP_USE_TX_BUF
int isotp_send_buf(const struct device *can_dev,
		   const uint8_t *data, size_t len,
		   const struct isotp_msg_id *tx_addr,
		   const struct isotp_msg_id *rx_addr,
		   isotp_tx_callback_t complete_cb, void *cb_arg,
		   k_timeout_t timeout)
{
	struct isotp_send_ctx *ctx;
	struct net_buf *buf;
	int ret;

	__ASSERT_NO_MSG(data);

	ret = alloc_ctx(&ctx, timeout);
	if (ret) {
		return ret;
	}

	buf = net_buf_alloc_len(&isotp_tx_pool, len, timeout);
	if (!buf) {
		k_mem_slab_free(&ctx_slab, (void **)&ctx);
		return ISOTP_NO_BUF_DATA_LEFT;
	}

	net_buf_add_mem(buf, data, len);

	ctx->is_net_buf = 1;
	ctx->buf = buf;

	return send(ctx, can_dev, tx_addr, rx_addr, complete_cb, cb_arg);
}
#endif  /*CONFIG_ISOTP_USE_TX_BUF*/
#endif  /*CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS*/
