/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#undef pr_fmt
#define pr_fmt(fmt) "core: " fmt

#include "libmctp.h"
#include "libmctp-alloc.h"
#include "libmctp-log.h"
#include "libmctp-cmds.h"
#include "range.h"
#include "compiler.h"
#include "core-internal.h"

#if MCTP_DEFAULT_CLOCK_GETTIME
#include <time.h>
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif

static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
				  mctp_eid_t dest, bool tag_owner,
				  uint8_t msg_tag, void *msg, size_t msg_len);
static void mctp_dealloc_tag(struct mctp_bus *bus, mctp_eid_t local,
			     mctp_eid_t remote, uint8_t tag);

struct mctp_pktbuf *mctp_pktbuf_alloc(struct mctp_binding *binding, size_t len)
{
	size_t size =
		binding->pkt_size + binding->pkt_header + binding->pkt_trailer;
	if (len > size) {
		return NULL;
	}

	void *storage = __mctp_alloc(size + sizeof(struct mctp_pktbuf));
	if (!storage) {
		return NULL;
	}
	struct mctp_pktbuf *pkt = mctp_pktbuf_init(binding, storage);
	pkt->alloc = true;
	pkt->end = pkt->start + len;
	return pkt;
}

void mctp_pktbuf_free(struct mctp_pktbuf *pkt)
{
	if (pkt->alloc) {
		__mctp_free(pkt);
	} else {
		mctp_prdebug("pktbuf_free called for non-alloced");
	}
}

struct mctp_pktbuf *mctp_pktbuf_init(struct mctp_binding *binding,
				     void *storage)
{
	size_t size =
		binding->pkt_size + binding->pkt_header + binding->pkt_trailer;
	struct mctp_pktbuf *buf = (struct mctp_pktbuf *)storage;
	buf->size = size;
	buf->start = binding->pkt_header;
	buf->end = buf->start;
	buf->mctp_hdr_off = buf->start;
	buf->alloc = false;

	return buf;
}

struct mctp_hdr *mctp_pktbuf_hdr(struct mctp_pktbuf *pkt)
{
	return (struct mctp_hdr *)(pkt->data + pkt->mctp_hdr_off);
}

void *mctp_pktbuf_data(struct mctp_pktbuf *pkt)
{
	return pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr);
}

size_t mctp_pktbuf_size(const struct mctp_pktbuf *pkt)
{
	return pkt->end - pkt->start;
}

void *mctp_pktbuf_alloc_start(struct mctp_pktbuf *pkt, size_t size)
{
	assert(size <= pkt->start);
	pkt->start -= size;
	return pkt->data + pkt->start;
}

void *mctp_pktbuf_alloc_end(struct mctp_pktbuf *pkt, size_t size)
{
	void *buf;

	assert(size <= (pkt->size - pkt->end));
	buf = pkt->data + pkt->end;
	pkt->end += size;
	return buf;
}

int mctp_pktbuf_push(struct mctp_pktbuf *pkt, const void *data, size_t len)
{
	void *p;

	if (pkt->end + len > pkt->size)
		return -1;

	p = pkt->data + pkt->end;

	pkt->end += len;
	memcpy(p, data, len);

	return 0;
}

void *mctp_pktbuf_pop(struct mctp_pktbuf *pkt, size_t len)
{
	if (len > mctp_pktbuf_size(pkt))
		return NULL;

	pkt->end -= len;
	return pkt->data + pkt->end;
}

/* Allocate a duplicate of the message and copy it */
static void *mctp_msg_dup(const void *msg, size_t msg_len, struct mctp *mctp)
{
	void *copy = __mctp_msg_alloc(msg_len, mctp);
	if (!copy) {
		mctp_prdebug("msg dup len %zu failed", msg_len);
		return NULL;
	}

	memcpy(copy, msg, msg_len);
	return copy;
}

/* Message reassembly */
static struct mctp_msg_ctx *mctp_msg_ctx_lookup(struct mctp *mctp, uint8_t src,
						uint8_t dest, uint8_t tag)
{
	unsigned int i;

	/* @todo: better lookup, if we add support for more outstanding
	 * message contexts */
	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *ctx = &mctp->msg_ctxs[i];
		if (ctx->buf && ctx->src == src && ctx->dest == dest &&
		    ctx->tag == tag)
			return ctx;
	}

	return NULL;
}

static struct mctp_msg_ctx *mctp_msg_ctx_create(struct mctp *mctp, uint8_t src,
						uint8_t dest, uint8_t tag)
{
	struct mctp_msg_ctx *ctx = NULL;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i];
		if (!tmp->buf) {
			ctx = tmp;
			break;
		}
	}

	if (!ctx)
		return NULL;

	ctx->src = src;
	ctx->dest = dest;
	ctx->tag = tag;

	ctx->buf_size = 0;
	ctx->buf_alloc_size = mctp->max_message_size;
	ctx->buf = __mctp_msg_alloc(ctx->buf_alloc_size, mctp);
	if (!ctx->buf) {
		return NULL;
	}

	return ctx;
}

static void mctp_msg_ctx_drop(struct mctp_bus *bus, struct mctp_msg_ctx *ctx)
{
	/* Free and mark as unused */
	__mctp_msg_free(ctx->buf, bus->mctp);
	ctx->buf = NULL;
}

static void mctp_msg_ctx_reset(struct mctp_msg_ctx *ctx)
{
	ctx->buf_size = 0;
	ctx->fragment_size = 0;
}

static int mctp_msg_ctx_add_pkt(struct mctp_msg_ctx *ctx,
				struct mctp_pktbuf *pkt)
{
	size_t len;

	len = mctp_pktbuf_size(pkt) - sizeof(struct mctp_hdr);

	if (len + ctx->buf_size < ctx->buf_size) {
		return -1;
	}

	if (ctx->buf_size + len > ctx->buf_alloc_size) {
		return -1;
	}

	memcpy((uint8_t *)ctx->buf + ctx->buf_size, mctp_pktbuf_data(pkt), len);
	ctx->buf_size += len;

	return 0;
}

/* Core API functions */
struct mctp *mctp_init(void)
{
	struct mctp *mctp;

	mctp = __mctp_alloc(sizeof(*mctp));

	if (!mctp)
		return NULL;

	mctp_setup(mctp, sizeof(*mctp));
	return mctp;
}

#if MCTP_DEFAULT_CLOCK_GETTIME
static uint64_t mctp_default_now(void *ctx __attribute__((unused)))
{
	struct timespec tp;
	int rc = clock_gettime(CLOCK_MONOTONIC, &tp);
	if (rc) {
		/* Should not be possible */
		return 0;
	}
	return (uint64_t)tp.tv_sec * 1000 + tp.tv_nsec / 1000000;
}
#endif

int mctp_setup(struct mctp *mctp, size_t struct_mctp_size)
{
	if (struct_mctp_size < sizeof(struct mctp)) {
		mctp_prdebug("Mismatching struct mctp");
		return -EINVAL;
	}
	memset(mctp, 0, sizeof(*mctp));
	mctp->max_message_size = MCTP_MAX_MESSAGE_SIZE;
#if MCTP_DEFAULT_CLOCK_GETTIME
	mctp->platform_now = mctp_default_now;
#endif
	return 0;
}

void mctp_set_max_message_size(struct mctp *mctp, size_t message_size)
{
	mctp->max_message_size = message_size;
}

void mctp_set_capture_handler(struct mctp *mctp, mctp_capture_fn fn, void *user)
{
	mctp->capture = fn;
	mctp->capture_data = user;
}

static void mctp_bus_destroy(struct mctp_bus *bus, struct mctp *mctp)
{
	if (bus->tx_msg) {
		__mctp_msg_free(bus->tx_msg, mctp);
		bus->tx_msg = NULL;
	}
}

void mctp_cleanup(struct mctp *mctp)
{
	size_t i;

	/* Cleanup message assembly contexts */
	static_assert(ARRAY_SIZE(mctp->msg_ctxs) < SIZE_MAX, "size");
	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
		struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i];
		if (tmp->buf)
			__mctp_msg_free(tmp->buf, mctp);
	}

	while (mctp->n_busses--)
		mctp_bus_destroy(&mctp->busses[mctp->n_busses], mctp);
}

void mctp_destroy(struct mctp *mctp)
{
	mctp_cleanup(mctp);
	__mctp_free(mctp);
}

int mctp_set_rx_all(struct mctp *mctp, mctp_rx_fn fn, void *data)
{
	mctp->message_rx = fn;
	mctp->message_rx_data = data;
	return 0;
}

static struct mctp_bus *find_bus_for_eid(struct mctp *mctp, mctp_eid_t dest
					 __attribute__((unused)))
{
	if (mctp->n_busses == 0)
		return NULL;

	/* for now, just use the first bus. For full routing support,
	 * we will need a table of neighbours */
	return &mctp->busses[0];
}

int mctp_register_bus(struct mctp *mctp, struct mctp_binding *binding,
		      mctp_eid_t eid)
{
	int rc = 0;

	/* todo: multiple busses */
	static_assert(MCTP_MAX_BUSSES >= 1, "need a bus");
	assert(mctp->n_busses == 0);
	mctp->n_busses = 1;

	assert(binding->tx_storage);

	memset(mctp->busses, 0, sizeof(struct mctp_bus));
	mctp->busses[0].mctp = mctp;
	mctp->busses[0].binding = binding;
	mctp->busses[0].eid = eid;
	binding->bus = &mctp->busses[0];
	binding->mctp = mctp;
	mctp->route_policy = ROUTE_ENDPOINT;

	if (binding->start) {
		rc = binding->start(binding);
		if (rc < 0) {
			mctp_prerr("Failed to start binding: %d", rc);
			binding->bus = NULL;
			mctp->n_busses = 0;
		}
	}

	return rc;
}

void mctp_unregister_bus(struct mctp *mctp, struct mctp_binding *binding)
{
	/*
	 * We only support one bus right now; once the call completes we will
	 * have no more busses
	 */
	mctp->n_busses = 0;
	binding->mctp = NULL;
	binding->bus = NULL;
}

int mctp_bridge_busses(struct mctp *mctp, struct mctp_binding *b1,
		       struct mctp_binding *b2)
{
	int rc = 0;

	assert(b1->tx_storage);
	assert(b2->tx_storage);

	assert(mctp->n_busses == 0);
	assert(MCTP_MAX_BUSSES >= 2);
	memset(mctp->busses, 0, 2 * sizeof(struct mctp_bus));
	mctp->n_busses = 2;
	mctp->busses[0].binding = b1;
	b1->bus = &mctp->busses[0];
	b1->mctp = mctp;
	mctp->busses[1].binding = b2;
	b2->bus = &mctp->busses[1];
	b2->mctp = mctp;

	mctp->route_policy = ROUTE_BRIDGE;

	if (b1->start) {
		rc = b1->start(b1);
		if (rc < 0) {
			mctp_prerr("Failed to start bridged bus %s: %d",
				   b1->name, rc);
			goto done;
		}
	}

	if (b2->start) {
		rc = b2->start(b2);
		if (rc < 0) {
			mctp_prerr("Failed to start bridged bus %s: %d",
				   b2->name, rc);
			goto done;
		}
	}

done:
	return rc;
}

static inline bool mctp_ctrl_cmd_is_transport(struct mctp_ctrl_msg_hdr *hdr)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
	return ((hdr->command_code >= MCTP_CTRL_CMD_FIRST_TRANSPORT) &&
		(hdr->command_code <= MCTP_CTRL_CMD_LAST_TRANSPORT));
#pragma GCC diagnostic pop
}

static bool mctp_ctrl_handle_msg(struct mctp_bus *bus, mctp_eid_t src,
				 uint8_t msg_tag, bool tag_owner, void *buffer,
				 size_t length)
{
	struct mctp_ctrl_msg_hdr *msg_hdr = buffer;

	/*
	 * Control message is received. If a transport control message handler
	 * is provided, it will called. If there is no dedicated handler, this
	 * function returns false and data can be handled by the generic
	 * message handler. The transport control message handler will be
	 * provided with messages in the command range 0xF0 - 0xFF.
	 */
	if (mctp_ctrl_cmd_is_transport(msg_hdr)) {
		if (bus->binding->control_rx != NULL) {
			/* MCTP bus binding handler */
			bus->binding->control_rx(src, msg_tag, tag_owner,
						 bus->binding->control_rx_data,
						 buffer, length);
			return true;
		}
	}

	/*
	 * Command was not handled, due to lack of specific callback.
	 * It will be passed to regular message_rx handler.
	 */
	return false;
}

static inline bool mctp_rx_dest_is_local(struct mctp_bus *bus, mctp_eid_t dest)
{
	return dest == bus->eid || dest == MCTP_EID_NULL ||
	       dest == MCTP_EID_BROADCAST;
}

static inline bool mctp_ctrl_cmd_is_request(struct mctp_ctrl_msg_hdr *hdr)
{
	return hdr->ic_msg_type == MCTP_CTRL_HDR_MSG_TYPE &&
	       hdr->rq_dgram_inst & MCTP_CTRL_HDR_FLAG_REQUEST;
}

/*
 * Receive the complete MCTP message and route it.
 * Asserts:
 *     'buf' is not NULL.
 */
static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, mctp_eid_t src,
		    mctp_eid_t dest, bool tag_owner, uint8_t msg_tag, void *buf,
		    size_t len)
{
	assert(buf != NULL);

	if (mctp->route_policy == ROUTE_ENDPOINT &&
	    mctp_rx_dest_is_local(bus, dest)) {
		/* Note responses to allocated tags */
		if (!tag_owner) {
			mctp_dealloc_tag(bus, dest, src, msg_tag);
		}

		/* Handle MCTP Control Messages: */
		if (len >= sizeof(struct mctp_ctrl_msg_hdr)) {
			struct mctp_ctrl_msg_hdr *msg_hdr = buf;

			/*
			 * Identify if this is a control request message.
			 * See DSP0236 v1.3.0 sec. 11.5.
			 */
			if (mctp_ctrl_cmd_is_request(msg_hdr)) {
				bool handled;
				handled = mctp_ctrl_handle_msg(
					bus, src, msg_tag, tag_owner, buf, len);
				if (handled)
					return;
			}
		}

		if (mctp->message_rx)
			mctp->message_rx(src, tag_owner, msg_tag,
					 mctp->message_rx_data, buf, len);
	}

	if (mctp->route_policy == ROUTE_BRIDGE) {
		int i;

		for (i = 0; i < mctp->n_busses; i++) {
			struct mctp_bus *dest_bus = &mctp->busses[i];
			if (dest_bus == bus)
				continue;

			void *copy = mctp_msg_dup(buf, len, mctp);
			if (!copy) {
				return;
			}

			mctp_message_tx_on_bus(dest_bus, src, dest, tag_owner,
					       msg_tag, copy, len);
		}
	}
}

void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt)
{
	struct mctp_bus *bus = binding->bus;
	struct mctp *mctp = binding->mctp;
	uint8_t flags, exp_seq, seq, tag;
	struct mctp_msg_ctx *ctx;
	struct mctp_hdr *hdr;
	bool tag_owner;
	size_t len;
	void *p;
	int rc;

	assert(bus);

	/* Drop packet if it was smaller than mctp hdr size */
	if (mctp_pktbuf_size(pkt) < sizeof(struct mctp_hdr))
		goto out;

	if (mctp->capture)
		mctp->capture(pkt, MCTP_MESSAGE_CAPTURE_INCOMING,
			      mctp->capture_data);

	hdr = mctp_pktbuf_hdr(pkt);

	/* small optimisation: don't bother reassembly if we're going to
	 * drop the packet in mctp_rx anyway */
	if (mctp->route_policy == ROUTE_ENDPOINT &&
	    !mctp_rx_dest_is_local(bus, hdr->dest))
		goto out;

	flags = hdr->flags_seq_tag & (MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM);
	tag = (hdr->flags_seq_tag >> MCTP_HDR_TAG_SHIFT) & MCTP_HDR_TAG_MASK;
	seq = (hdr->flags_seq_tag >> MCTP_HDR_SEQ_SHIFT) & MCTP_HDR_SEQ_MASK;
	tag_owner = (hdr->flags_seq_tag >> MCTP_HDR_TO_SHIFT) &
		    MCTP_HDR_TO_MASK;

	switch (flags) {
	case MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM:
		/* single-packet message - send straight up to rx function,
		 * no need to create a message context */
		len = pkt->end - pkt->mctp_hdr_off - sizeof(struct mctp_hdr);
		p = mctp_msg_dup(pkt->data + pkt->mctp_hdr_off +
					 sizeof(struct mctp_hdr),
				 len, mctp);
		if (p) {
			mctp_rx(mctp, bus, hdr->src, hdr->dest, tag_owner, tag,
				p, len);
			__mctp_msg_free(p, mctp);
		}
		break;

	case MCTP_HDR_FLAG_SOM:
		/* start of a new message - start the new context for
		 * future message reception. If an existing context is
		 * already present, drop it. */
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (ctx) {
			mctp_msg_ctx_reset(ctx);
		} else {
			ctx = mctp_msg_ctx_create(mctp, hdr->src, hdr->dest,
						  tag);
			/* If context creation fails due to exhaution of contexts we
			* can support, drop the packet */
			if (!ctx) {
				mctp_prdebug("Context buffers exhausted.");
				goto out;
			}
		}

		/* Save the fragment size, subsequent middle fragments
		 * should of the same size */
		ctx->fragment_size = mctp_pktbuf_size(pkt);

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (rc) {
			mctp_msg_ctx_drop(bus, ctx);
		} else {
			ctx->last_seq = seq;
		}

		break;

	case MCTP_HDR_FLAG_EOM:
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (!ctx)
			goto out;

		exp_seq = (ctx->last_seq + 1) % 4;

		if (exp_seq != seq) {
			mctp_prdebug(
				"Sequence number %d does not match expected %d",
				seq, exp_seq);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		len = mctp_pktbuf_size(pkt);

		if (len > ctx->fragment_size) {
			mctp_prdebug("Unexpected fragment size. Expected"
				     " less than %zu, received = %zu",
				     ctx->fragment_size, len);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (!rc)
			mctp_rx(mctp, bus, ctx->src, ctx->dest, tag_owner, tag,
				ctx->buf, ctx->buf_size);

		mctp_msg_ctx_drop(bus, ctx);
		break;

	case 0:
		/* Neither SOM nor EOM */
		ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag);
		if (!ctx)
			goto out;

		exp_seq = (ctx->last_seq + 1) % 4;
		if (exp_seq != seq) {
			mctp_prdebug(
				"Sequence number %d does not match expected %d",
				seq, exp_seq);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		len = mctp_pktbuf_size(pkt);

		if (len != ctx->fragment_size) {
			mctp_prdebug("Unexpected fragment size. Expected = %zu "
				     "received = %zu",
				     ctx->fragment_size, len);
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}

		rc = mctp_msg_ctx_add_pkt(ctx, pkt);
		if (rc) {
			mctp_msg_ctx_drop(bus, ctx);
			goto out;
		}
		ctx->last_seq = seq;

		break;
	}
out:
	return;
}

static int mctp_packet_tx(struct mctp_bus *bus, struct mctp_pktbuf *pkt)
{
	struct mctp *mctp = bus->binding->mctp;

	if (bus->state != mctp_bus_state_tx_enabled) {
		mctp_prdebug("tx with bus disabled");
		return -1;
	}

	if (mctp->capture)
		mctp->capture(pkt, MCTP_MESSAGE_CAPTURE_OUTGOING,
			      mctp->capture_data);

	return bus->binding->tx(bus->binding, pkt);
}

/* Returns a pointer to the binding's tx_storage */
static struct mctp_pktbuf *mctp_next_tx_pkt(struct mctp_bus *bus)
{
	if (!bus->tx_msg) {
		return NULL;
	}

	size_t p = bus->tx_msgpos;
	size_t msg_len = bus->tx_msglen;
	size_t payload_len = msg_len - p;
	size_t max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size);
	if (payload_len > max_payload_len)
		payload_len = max_payload_len;

	struct mctp_pktbuf *pkt =
		mctp_pktbuf_init(bus->binding, bus->binding->tx_storage);
	struct mctp_hdr *hdr = mctp_pktbuf_hdr(pkt);

	hdr->ver = bus->binding->version & 0xf;
	hdr->dest = bus->tx_dest;
	hdr->src = bus->tx_src;
	hdr->flags_seq_tag = (bus->tx_to << MCTP_HDR_TO_SHIFT) |
			     (bus->tx_tag << MCTP_HDR_TAG_SHIFT);

	if (p == 0)
		hdr->flags_seq_tag |= MCTP_HDR_FLAG_SOM;
	if (p + payload_len >= msg_len)
		hdr->flags_seq_tag |= MCTP_HDR_FLAG_EOM;
	hdr->flags_seq_tag |= bus->tx_seq << MCTP_HDR_SEQ_SHIFT;

	memcpy(mctp_pktbuf_data(pkt), (uint8_t *)bus->tx_msg + p, payload_len);
	pkt->end = pkt->start + sizeof(*hdr) + payload_len;
	bus->tx_pktlen = payload_len;

	mctp_prdebug(
		"tx dst %d tag %d payload len %zu seq %d. msg pos %zu len %zu",
		hdr->dest, bus->tx_tag, payload_len, bus->tx_seq, p, msg_len);

	return pkt;
}

/* Called when a packet has successfully been sent */
static void mctp_tx_complete(struct mctp_bus *bus)
{
	if (!bus->tx_msg) {
		mctp_prdebug("tx complete no message");
		return;
	}

	bus->tx_seq = (bus->tx_seq + 1) & MCTP_HDR_SEQ_MASK;
	bus->tx_msgpos += bus->tx_pktlen;

	if (bus->tx_msgpos >= bus->tx_msglen) {
		__mctp_msg_free(bus->tx_msg, bus->binding->mctp);
		bus->tx_msg = NULL;
	}
}

static void mctp_send_tx_queue(struct mctp_bus *bus)
{
	struct mctp_pktbuf *pkt;

	while (bus->tx_msg && bus->state == mctp_bus_state_tx_enabled) {
		int rc;

		pkt = mctp_next_tx_pkt(bus);

		rc = mctp_packet_tx(bus, pkt);
		switch (rc) {
		/* If transmission succeded */
		case 0:
			/* Drop the packet */
			mctp_tx_complete(bus);
			break;

		/* If the binding was busy */
		case -EBUSY:
			/* Keep the packet for next try */
			mctp_prdebug("tx EBUSY");
			return;

		/* Some other unknown error occurred */
		default:
			/* Drop the packet */
			mctp_prdebug("tx drop %d", rc);
			mctp_tx_complete(bus);
			return;
		};
	}
}

void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable)
{
	struct mctp_bus *bus = binding->bus;

	switch (bus->state) {
	case mctp_bus_state_constructed:
		if (!enable)
			return;

		if (binding->pkt_size < MCTP_PACKET_SIZE(MCTP_BTU)) {
			mctp_prerr(
				"Cannot start %s binding with invalid MTU: %zu",
				binding->name,
				MCTP_BODY_SIZE(binding->pkt_size));
			return;
		}

		bus->state = mctp_bus_state_tx_enabled;
		mctp_prinfo("%s binding started", binding->name);
		return;
	case mctp_bus_state_tx_enabled:
		if (enable)
			return;

		bus->state = mctp_bus_state_tx_disabled;
		mctp_prdebug("%s binding Tx disabled", binding->name);
		return;
	case mctp_bus_state_tx_disabled:
		if (!enable)
			return;

		bus->state = mctp_bus_state_tx_enabled;
		mctp_prdebug("%s binding Tx enabled", binding->name);
		mctp_send_tx_queue(bus);
		return;
	}
}

static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
				  mctp_eid_t dest, bool tag_owner,
				  uint8_t msg_tag, void *msg, size_t msg_len)
{
	size_t max_payload_len;
	int rc;

	if (bus->state == mctp_bus_state_constructed) {
		rc = -ENXIO;
		goto err;
	}

	if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag) {
		rc = -EINVAL;
		goto err;
	}

	max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size);

	{
		const bool valid_mtu = max_payload_len >= MCTP_BTU;
		assert(valid_mtu);
		if (!valid_mtu) {
			rc = -EINVAL;
			goto err;
		}
	}

	mctp_prdebug(
		"%s: Generating packets for transmission of %zu byte message from %hhu to %hhu",
		__func__, msg_len, src, dest);

	if (bus->tx_msg) {
		mctp_prdebug("Bus busy");
		rc = -EBUSY;
		goto err;
	}

	/* Take the message to send */
	bus->tx_msg = msg;
	bus->tx_msglen = msg_len;
	bus->tx_msgpos = 0;
	/* bus->tx_seq is allowed to continue from previous message */
	bus->tx_src = src;
	bus->tx_dest = dest;
	bus->tx_to = tag_owner;
	bus->tx_tag = msg_tag;

	mctp_send_tx_queue(bus);
	return 0;

err:
	__mctp_msg_free(msg, bus->binding->mctp);
	return rc;
}

int mctp_message_tx_alloced(struct mctp *mctp, mctp_eid_t eid, bool tag_owner,
			    uint8_t msg_tag, void *msg, size_t msg_len)
{
	struct mctp_bus *bus;

	/* TODO: Protect against same tag being used across
	 * different callers */
	if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag) {
		mctp_prerr("Incorrect message tag %u passed.", msg_tag);
		__mctp_msg_free(msg, mctp);
		return -EINVAL;
	}

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		__mctp_msg_free(msg, mctp);
		return 0;
	}

	return mctp_message_tx_on_bus(bus, bus->eid, eid, tag_owner, msg_tag,
				      msg, msg_len);
}

int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid, bool tag_owner,
		    uint8_t msg_tag, const void *msg, size_t msg_len)
{
	void *copy = mctp_msg_dup(msg, msg_len, mctp);
	if (!copy) {
		return -ENOMEM;
	}

	return mctp_message_tx_alloced(mctp, eid, tag_owner, msg_tag, copy,
				       msg_len);
}

void mctp_set_now_op(struct mctp *mctp, uint64_t (*now)(void *), void *ctx)
{
	assert(now);
	mctp->platform_now = now;
	mctp->platform_now_ctx = ctx;
}

uint64_t mctp_now(struct mctp *mctp)
{
	assert(mctp->platform_now);
	return mctp->platform_now(mctp->platform_now_ctx);
}

static void mctp_dealloc_tag(struct mctp_bus *bus, mctp_eid_t local,
			     mctp_eid_t remote, uint8_t tag)
{
	struct mctp *mctp = bus->binding->mctp;
	if (local == 0) {
		return;
	}

	for (size_t i = 0; i < ARRAY_SIZE(mctp->req_tags); i++) {
		struct mctp_req_tag *r = &mctp->req_tags[i];
		if (r->local == local && r->remote == remote && r->tag == tag) {
			r->local = 0;
			r->remote = 0;
			r->tag = 0;
			r->expiry = 0;
			return;
		}
	}
}

static int mctp_alloc_tag(struct mctp *mctp, mctp_eid_t local,
			  mctp_eid_t remote, uint8_t *ret_tag)
{
	assert(local != 0);
	uint64_t now = mctp_now(mctp);

	uint8_t used = 0;
	struct mctp_req_tag *spare = NULL;
	/* Find which tags and slots are used/spare */
	for (size_t i = 0; i < ARRAY_SIZE(mctp->req_tags); i++) {
		struct mctp_req_tag *r = &mctp->req_tags[i];
		if (r->local == 0 || r->expiry < now) {
			spare = r;
		} else {
			if (r->local == local && r->remote == remote) {
				used |= 1 << r->tag;
			}
		}
	}

	if (spare == NULL) {
		// All req_tag slots are in-use
		return -EBUSY;
	}

	for (uint8_t t = 0; t < 8; t++) {
		uint8_t tag = (t + mctp->tag_round_robin) % 8;
		if ((used & 1 << tag) == 0) {
			spare->local = local;
			spare->remote = remote;
			spare->tag = tag;
			spare->expiry = now + MCTP_TAG_TIMEOUT;
			*ret_tag = tag;
			mctp->tag_round_robin = (tag + 1) % 8;
			return 0;
		}
	}

	// All 8 tags are used for this src/dest pair
	return -EBUSY;
}

int mctp_message_tx_request(struct mctp *mctp, mctp_eid_t eid, void *msg,
			    size_t msg_len, uint8_t *ret_alloc_msg_tag)
{
	int rc;
	struct mctp_bus *bus;

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		__mctp_msg_free(msg, mctp);
		return 0;
	}

	uint8_t alloc_tag;
	rc = mctp_alloc_tag(mctp, bus->eid, eid, &alloc_tag);
	if (rc) {
		mctp_prdebug("Failed allocating tag");
		__mctp_msg_free(msg, mctp);
		return rc;
	}

	if (ret_alloc_msg_tag) {
		*ret_alloc_msg_tag = alloc_tag;
	}

	return mctp_message_tx_alloced(mctp, eid, true, alloc_tag, msg,
				       msg_len);
}

bool mctp_is_tx_ready(struct mctp *mctp, mctp_eid_t eid)
{
	struct mctp_bus *bus;

	bus = find_bus_for_eid(mctp, eid);
	if (!bus) {
		return true;
	}
	return bus->tx_msg == NULL;
}

void *mctp_get_alloc_ctx(struct mctp *mctp)
{
	return mctp->alloc_ctx;
}

void mctp_set_alloc_ctx(struct mctp *mctp, void *ctx)
{
	mctp->alloc_ctx = ctx;
}
