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

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define ASTLPC_VER_CUR 3
#include "astlpc.c"

#ifdef pr_fmt
#undef pr_fmt
#define pr_fmt(x) "test: " x
#endif

#include "compiler.h"
#include "container_of.h"
#include "libmctp-astlpc.h"
#include "libmctp-log.h"

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/random.h>
#include <unistd.h>

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

struct mctp_binding_astlpc_mmio {
	struct mctp_binding_astlpc astlpc;
	bool bmc;

	uint8_t (*kcs)[2];

	size_t lpc_size;
	uint8_t *lpc;
};

struct astlpc_endpoint {
	struct mctp_binding_astlpc_mmio mmio;
	struct mctp_binding_astlpc *astlpc;
	struct mctp *mctp;
};

struct astlpc_test {
	struct astlpc_endpoint bmc;
	struct astlpc_endpoint host;
	uint8_t kcs[2];
	uint8_t *lpc_mem;

	void *msg;
	uint8_t count;
};

#define binding_to_mmio(b)                                                     \
	container_of(b, struct mctp_binding_astlpc_mmio, astlpc)

static int mctp_astlpc_mmio_kcs_read(void *data,
				     enum mctp_binding_astlpc_kcs_reg reg,
				     uint8_t *val)
{
	struct mctp_binding_astlpc_mmio *mmio = binding_to_mmio(data);

	*val = (*mmio->kcs)[reg];

	mctp_prdebug("%s: 0x%hhx from %s", __func__, *val,
		     reg ? "status" : "data");

	if (reg == MCTP_ASTLPC_KCS_REG_DATA) {
		uint8_t flag = mmio->bmc ? KCS_STATUS_IBF : KCS_STATUS_OBF;
		(*mmio->kcs)[MCTP_ASTLPC_KCS_REG_STATUS] &= ~flag;
	}

	return 0;
}

static int mctp_astlpc_mmio_kcs_write(void *data,
				      enum mctp_binding_astlpc_kcs_reg reg,
				      uint8_t val)
{
	struct mctp_binding_astlpc_mmio *mmio = binding_to_mmio(data);
	uint8_t *regp;

	assert(reg == MCTP_ASTLPC_KCS_REG_DATA ||
	       reg == MCTP_ASTLPC_KCS_REG_STATUS);

	if (reg == MCTP_ASTLPC_KCS_REG_DATA) {
		uint8_t flag = mmio->bmc ? KCS_STATUS_OBF : KCS_STATUS_IBF;
		(*mmio->kcs)[MCTP_ASTLPC_KCS_REG_STATUS] |= flag;
	}

	regp = &(*mmio->kcs)[reg];
	if (reg == MCTP_ASTLPC_KCS_REG_STATUS)
		*regp = (val & ~0xbU) | (val & *regp & 1);
	else
		*regp = val;

	mctp_prdebug("%s: 0x%hhx to %s", __func__, val,
		     reg ? "status" : "data");

	return 0;
}

static const struct mctp_binding_astlpc_ops astlpc_direct_mmio_ops = {
	.kcs_read = mctp_astlpc_mmio_kcs_read,
	.kcs_write = mctp_astlpc_mmio_kcs_write,
};

int mctp_astlpc_mmio_lpc_read(void *data, void *buf, long offset, size_t len)
{
	struct mctp_binding_astlpc_mmio *mmio = binding_to_mmio(data);

	mctp_prdebug("%s: %zu bytes from 0x%lx", __func__, len, offset);

	assert(offset >= 0L);
	assert(offset + len < mmio->lpc_size);

	memcpy(buf, mmio->lpc + offset, len);

	return 0;
}

int mctp_astlpc_mmio_lpc_write(void *data, const void *buf, long offset,
			       size_t len)
{
	struct mctp_binding_astlpc_mmio *mmio = binding_to_mmio(data);

	mctp_prdebug("%s: %zu bytes to 0x%lx", __func__, len, offset);

	assert(offset >= 0L);
	assert(offset + len < mmio->lpc_size);

	memcpy(mmio->lpc + offset, buf, len);

	return 0;
}

static const struct mctp_binding_astlpc_ops astlpc_indirect_mmio_ops = {
	.kcs_read = mctp_astlpc_mmio_kcs_read,
	.kcs_write = mctp_astlpc_mmio_kcs_write,
	.lpc_read = mctp_astlpc_mmio_lpc_read,
	.lpc_write = mctp_astlpc_mmio_lpc_write,
};

static void astlpc_test_rx_message(uint8_t eid __unused,
				   bool tag_owner __unused,
				   uint8_t msg_tag __unused,
				   void *data __unused, void *msg, size_t len)
{
	struct astlpc_test *test = data;

	mctp_prdebug("MCTP message received: msg: %p, len %zd", msg, len);

	assert(len > 0);
	assert(msg);
	assert(test);
	assert(test->msg);
	assert(!memcmp(test->msg, msg, len));

	test->count++;
}

static int endpoint_init(struct astlpc_endpoint *ep, mctp_eid_t eid,
			 uint8_t mode, uint32_t mtu, uint8_t (*kcs)[2],
			 void *lpc_mem)
{
	/*
	 * Configure the direction of the KCS interface so we know whether to
	 * set or clear IBF or OBF on writes or reads.
	 */
	ep->mmio.bmc = (mode == MCTP_BINDING_ASTLPC_MODE_BMC);

	ep->mctp = mctp_init();
	assert(ep->mctp);

	/* Inject KCS registers */
	ep->mmio.kcs = kcs;

	/* Initialise the binding */
	ep->astlpc = mctp_astlpc_init(mode, mtu, lpc_mem,
				      &astlpc_direct_mmio_ops, &ep->mmio);
	assert(ep->astlpc);

	return mctp_register_bus(ep->mctp, &ep->astlpc->binding, eid);
}

static void endpoint_destroy(struct astlpc_endpoint *ep)
{
	mctp_astlpc_destroy(ep->astlpc);
	mctp_destroy(ep->mctp);
}

static void network_init(struct astlpc_test *ctx)
{
	int rc;

	ctx->lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(ctx->lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&ctx->bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &ctx->kcs, ctx->lpc_mem);
	assert(!rc);
	assert(ctx->kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_BMC_READY);

	/* Host initialisation */
	rc = endpoint_init(&ctx->host, 9, MCTP_BINDING_ASTLPC_MODE_HOST,
			   MCTP_BTU, &ctx->kcs, ctx->lpc_mem);
	assert(!rc);

	/* BMC processes host channel init request, alerts host */
	mctp_astlpc_poll(ctx->bmc.astlpc);
	assert(ctx->kcs[MCTP_ASTLPC_KCS_REG_STATUS] &
	       KCS_STATUS_CHANNEL_ACTIVE);
	assert(ctx->kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0xff);

	/* Host dequeues channel init result */
	mctp_astlpc_poll(ctx->host.astlpc);
}

static void network_destroy(struct astlpc_test *ctx)
{
	endpoint_destroy(&ctx->bmc);
	endpoint_destroy(&ctx->host);
	free(ctx->lpc_mem);
}

static void astlpc_assert_tx_packet(struct astlpc_endpoint *src,
				    const void *expected, size_t len)
{
	const size_t tx_body = src->astlpc->layout.tx.offset + 4 + 4;
	const void *test = ((char *)src->astlpc->lpc_map) + tx_body;
	assert(!memcmp(test, expected, len));
}

static void astlpc_test_packetised_message_bmc_to_host(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t msg[2 * MCTP_BTU];
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0x5a, MCTP_BTU);
	memset(&msg[MCTP_BTU], 0xa5, MCTP_BTU);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* BMC sends a message */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_SRC, 0, msg,
			     sizeof(msg));
	assert(rc == 0);

	/* Host receives the first packet */
	mctp_astlpc_poll(ctx.host.astlpc);

	/* BMC dequeues ownership hand-over and sends the queued packet */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	/* Host receives the next packet */
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x01);

	astlpc_assert_tx_packet(&ctx.bmc, &msg[MCTP_BTU], MCTP_BTU);

	/* Host receives final packet */
	mctp_astlpc_poll(ctx.host.astlpc);
	assert(ctx.count == 1);

	network_destroy(&ctx);
}

static void astlpc_test_simple_message_host_to_bmc(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t msg[MCTP_BTU];
	uint8_t tag = 0;
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0xa5, MCTP_BTU);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.bmc.mctp, astlpc_test_rx_message, &ctx);

	/* Host sends the single-packet message */
	rc = mctp_message_tx(ctx.host.mctp, 8, MCTP_MESSAGE_TO_DST, tag, msg,
			     sizeof(msg));
	assert(rc == 0);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x01);

	astlpc_assert_tx_packet(&ctx.host, &msg[0], MCTP_BTU);

	/* BMC receives the single-packet message */
	mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(ctx.count == 1);

	/* BMC returns Tx area ownership to Host */
	assert(!(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF));
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x02);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);

	/* Host dequeues ownership hand-over and sends the queued packet */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);

	network_destroy(&ctx);
}

static void astlpc_test_simple_message_bmc_to_host(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t msg[MCTP_BTU];
	uint8_t tag = 0;
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0x5a, MCTP_BTU);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* BMC sends the single-packet message */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_SRC, tag, msg,
			     sizeof(msg));
	assert(rc == 0);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x01);

	astlpc_assert_tx_packet(&ctx.bmc, &msg[0], MCTP_BTU);

	/* Host receives the single-packet message */
	mctp_astlpc_poll(ctx.host.astlpc);
	assert(ctx.count == 1);

	/* Host returns Rx area ownership to BMC */
	assert(!(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF));
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x02);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);

	/* BMC dequeues ownership hand-over and sends the queued packet */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	network_destroy(&ctx);
}

static void astlpc_test_host_before_bmc(void)
{
	struct mctp_binding_astlpc_mmio mmio = { 0 };
	struct mctp_binding_astlpc *astlpc;
	uint8_t kcs[2] = { 0 };
	struct mctp *mctp;
	int rc;

	mctp = mctp_init();
	assert(mctp);

	/* Inject KCS registers */
	mmio.kcs = &kcs;

	/* Initialise the binding */
	astlpc = mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU, NULL,
				  &astlpc_direct_mmio_ops, &mmio);

	/* Register the binding to trigger the start-up sequence */
	rc = mctp_register_bus(mctp, &astlpc->binding, 8);

	/* Start-up should fail as we haven't initialised the BMC */
	assert(rc < 0);

	mctp_astlpc_destroy(astlpc);
	mctp_destroy(mctp);
}

static void astlpc_test_bad_version(void)
{
	assert(0 ==
	       mctp_astlpc_negotiate_version(ASTLPC_VER_BAD, ASTLPC_VER_CUR,
					     ASTLPC_VER_MIN, ASTLPC_VER_CUR));
	assert(0 ==
	       mctp_astlpc_negotiate_version(ASTLPC_VER_MIN, ASTLPC_VER_BAD,
					     ASTLPC_VER_MIN, ASTLPC_VER_CUR));
	assert(0 ==
	       mctp_astlpc_negotiate_version(ASTLPC_VER_MIN, ASTLPC_VER_CUR,
					     ASTLPC_VER_BAD, ASTLPC_VER_CUR));
	assert(0 ==
	       mctp_astlpc_negotiate_version(ASTLPC_VER_MIN, ASTLPC_VER_CUR,
					     ASTLPC_VER_MIN, ASTLPC_VER_BAD));
	assert(0 == mctp_astlpc_negotiate_version(
			    ASTLPC_VER_CUR + 1, ASTLPC_VER_CUR, ASTLPC_VER_MIN,
			    ASTLPC_VER_CUR + 1));
	assert(0 == mctp_astlpc_negotiate_version(
			    ASTLPC_VER_MIN, ASTLPC_VER_CUR + 1,
			    ASTLPC_VER_CUR + 1, ASTLPC_VER_CUR));
}

static void astlpc_test_incompatible_versions(void)
{
	assert(0 == mctp_astlpc_negotiate_version(
			    ASTLPC_VER_CUR, ASTLPC_VER_CUR, ASTLPC_VER_CUR + 1,
			    ASTLPC_VER_CUR + 1));
	assert(0 == mctp_astlpc_negotiate_version(
			    ASTLPC_VER_CUR + 1, ASTLPC_VER_CUR + 1,
			    ASTLPC_VER_CUR, ASTLPC_VER_CUR));
}

static void astlpc_test_choose_bmc_ver_cur(void)
{
	assert(2 == mctp_astlpc_negotiate_version(1, 2, 2, 3));
}

static void astlpc_test_choose_host_ver_cur(void)
{
	assert(2 == mctp_astlpc_negotiate_version(2, 3, 1, 2));
}

static void astlpc_test_version_host_fails_negotiation(void)
{
	struct astlpc_endpoint bmc, host;
	struct mctp_lpcmap_hdr *hdr;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Now the BMC is initialised, break its version announcement */
	hdr = lpc_mem;
	hdr->bmc_ver_cur = ASTLPC_VER_BAD;

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(rc < 0);

	endpoint_destroy(&bmc);
	endpoint_destroy(&host);
	free(lpc_mem);
}

static void astlpc_test_version_bmc_fails_negotiation(void)
{
	struct astlpc_endpoint bmc, host;
	struct mctp_lpcmap_hdr *hdr;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Now the host is initialised, break its version announcement */
	hdr = lpc_mem;
	hdr->host_ver_cur = ASTLPC_VER_BAD;

	/* Poll the BMC to detect the broken host version */
	mctp_astlpc_poll(bmc.astlpc);
	assert(!(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_CHANNEL_ACTIVE));

	/* Poll the host so it detects failed negotiation */
	rc = mctp_astlpc_poll(host.astlpc);
	assert(rc < 0);

	endpoint_destroy(&bmc);
	endpoint_destroy(&host);
	free(lpc_mem);
}

static void astlpc_test_simple_init(void)
{
	struct astlpc_endpoint bmc, host;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Verify the BMC binding was initialised */
	assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_BMC_READY);

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Host sends channel init command */
	assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);
	assert(kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x00);

	/* BMC receives host channel init request */
	mctp_astlpc_poll(bmc.astlpc);

	/* BMC sends init response */
	assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);
	assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_CHANNEL_ACTIVE);
	assert(kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0xff);

	/* Host dequeues data */
	mctp_astlpc_poll(host.astlpc);

	endpoint_destroy(&bmc);
	endpoint_destroy(&host);
	free(lpc_mem);
}

static void astlpc_test_simple_indirect_message_bmc_to_host(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t kcs[2] = { 0 };
	uint8_t msg[MCTP_BTU];
	uint8_t tag = 0;
	int rc;

	ctx.lpc_mem = calloc(1, LPC_WIN_SIZE);
	assert(ctx.lpc_mem);

	/* Test message data */
	memset(&msg[0], 0x5a, MCTP_BTU);

	/* Manually set up the network so we can inject the indirect ops */

	/* BMC initialisation */
	ctx.bmc.mmio.bmc = true;
	ctx.bmc.mctp = mctp_init();
	assert(ctx.bmc.mctp);
	ctx.bmc.mmio.kcs = &kcs;
	ctx.bmc.mmio.lpc = ctx.lpc_mem;
	ctx.bmc.mmio.lpc_size = LPC_WIN_SIZE;
	ctx.bmc.astlpc =
		mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU, NULL,
				 &astlpc_indirect_mmio_ops, &ctx.bmc.mmio);
	mctp_register_bus(ctx.bmc.mctp, &ctx.bmc.astlpc->binding, 8);

	/* Host initialisation */
	ctx.host.mmio.bmc = false;
	ctx.host.mctp = mctp_init();
	assert(ctx.host.mctp);
	ctx.host.mmio.kcs = &kcs;
	ctx.host.mmio.lpc = ctx.lpc_mem;
	ctx.host.mmio.lpc_size = LPC_WIN_SIZE;
	ctx.host.astlpc =
		mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU, NULL,
				 &astlpc_indirect_mmio_ops, &ctx.host.mmio);
	mctp_register_bus(ctx.host.mctp, &ctx.host.astlpc->binding, 9);

	/* BMC processes host channel init request, alerts host */
	mctp_astlpc_poll(ctx.bmc.astlpc);

	/* Host dequeues channel init result */
	mctp_astlpc_poll(ctx.host.astlpc);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* BMC sends the single-packet message */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_SRC, tag, msg,
			     sizeof(msg));
	assert(rc == 0);

	/* Host receives the single-packet message */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);
	assert(ctx.count == 1);

	/* BMC dequeues ownership hand-over and sends the queued packet */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	/* Can still tear-down the network in the normal fashion */
	network_destroy(&ctx);
}

static void astlpc_test_host_tx_bmc_gone(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t unwritten[MCTP_BTU];
	uint8_t msg[MCTP_BTU];
	uint8_t tag = 0;
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0x5a, sizeof(msg));
	memset(&unwritten[0], 0, sizeof(unwritten));

	ctx.msg = &msg[0];
	ctx.count = 0;

	/* Clear bmc-ready */
	endpoint_destroy(&ctx.bmc);

	/* Host detects that the BMC is disabled */
	mctp_astlpc_poll(ctx.host.astlpc);

	/* Host attempts to send the single-packet message, but is prevented */
	rc = mctp_message_tx(ctx.host.mctp, 8, MCTP_MESSAGE_TO_DST, tag, msg,
			     sizeof(msg));
	assert(rc == 0);
	assert(!(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF));
	astlpc_assert_tx_packet(&ctx.host, &unwritten[0], MCTP_BTU);

	/* BMC comes back */
	rc = endpoint_init(&ctx.bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &ctx.kcs, ctx.lpc_mem);
	assert(!rc);
	mctp_set_rx_all(ctx.bmc.mctp, astlpc_test_rx_message, &ctx);

	/* Host triggers channel init */
	mctp_astlpc_poll(ctx.host.astlpc);

	/* BMC handles channel init */
	mctp_astlpc_poll(ctx.bmc.astlpc);

	/* Host completes channel init, flushing the Tx queue */
	mctp_astlpc_poll(ctx.host.astlpc);

	/* BMC receives the single-packet message */
	mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(ctx.count == 1);

	network_destroy(&ctx);
}

static void astlpc_test_poll_not_ready(void)
{
	struct astlpc_endpoint bmc;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Check for a command despite none present */
	rc = mctp_astlpc_poll(bmc.astlpc);

	/* Make sure it doesn't fail */
	assert(rc == 0);

	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_undefined_command(void)
{
	struct astlpc_endpoint bmc;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* 0x5a isn't legal in v1 or v2 */
	kcs[MCTP_ASTLPC_KCS_REG_DATA] = 0x5a;
	kcs[MCTP_ASTLPC_KCS_REG_STATUS] |= KCS_STATUS_IBF;

	/* Check for a command despite none present */
	rc = mctp_astlpc_poll(bmc.astlpc);

	/* Make sure it doesn't fail, bad command should be discarded */
	assert(rc == 0);

	endpoint_destroy(&bmc);
	free(lpc_mem);
}

#define BUFFER_MIN (MCTP_PACKET_SIZE(MCTP_BTU) + 4 + 4)
static const struct mctp_binding_astlpc astlpc_layout_ctx = {
	.proto = &astlpc_protocol_version[3],
};

static void astlpc_test_buffers_rx_offset_overflow(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { UINT32_MAX, BUFFER_MIN },
		.tx = { control_size, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_tx_offset_overflow(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, BUFFER_MIN },
		.tx = { UINT32_MAX, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_rx_size_overflow(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size + BUFFER_MIN, UINT32_MAX },
		.tx = { control_size, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_tx_size_overflow(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, BUFFER_MIN },
		.tx = { control_size + BUFFER_MIN, UINT32_MAX },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_rx_window_violation(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { LPC_WIN_SIZE - BUFFER_MIN + 1, BUFFER_MIN },
		.tx = { control_size, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_tx_window_violation(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, BUFFER_MIN },
		.tx = { LPC_WIN_SIZE - BUFFER_MIN + 1, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_rx_size_fails_btu(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, BUFFER_MIN - 1 },
		.tx = { control_size + BUFFER_MIN, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_tx_size_fails_btu(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, BUFFER_MIN },
		.tx = { control_size + BUFFER_MIN, BUFFER_MIN - 1 },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_overlap_rx_low(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, 2 * BUFFER_MIN },
		.tx = { control_size + BUFFER_MIN, 2 * BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_overlap_tx_low(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size + BUFFER_MIN, 2 * BUFFER_MIN },
		.tx = { control_size, 2 * BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_overlap_exact(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { control_size, 2 * BUFFER_MIN },
		.tx = { control_size, 2 * BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_overlap_control(void)
{
	struct mctp_astlpc_layout l = {
		.rx = { 0, BUFFER_MIN },
		.tx = { control_size + BUFFER_MIN, BUFFER_MIN },
	};

	assert(!mctp_astlpc_layout_validate(&astlpc_layout_ctx, &l));
}

static void astlpc_test_buffers_bad_host_proposal(void)
{
	struct astlpc_endpoint bmc, host;
	struct mctp_lpcmap_hdr *hdr;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/*
	 * Now that the host has initialised the control area, break
	 * something before polling the BMC
	 */
	hdr = lpc_mem;
	hdr->layout.rx_size = 0;

	mctp_astlpc_poll(bmc.astlpc);

	/* Make sure the BMC has not set the channel to active */
	assert(!(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_CHANNEL_ACTIVE));

	endpoint_destroy(&host);
	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_buffers_bad_bmc_proposal(void)
{
	struct astlpc_endpoint bmc, host;
	struct mctp_lpcmap_hdr *hdr;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/*
	 * Now that the BMC has initialised the control area, break something
	 * before initialising the host
	 */
	hdr = lpc_mem;
	hdr->layout.rx_size = 0;

	/* Host initialisation: Fails due to bad layout */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(rc < 0);

	endpoint_destroy(&host);
	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_buffers_bad_bmc_negotiation(void)
{
	struct astlpc_endpoint bmc, host;
	struct mctp_lpcmap_hdr *hdr;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	mctp_astlpc_poll(bmc.astlpc);

	/*
	 * Now that the BMC has initialised the control area, break something
	 * before polling the host
	 */
	hdr = lpc_mem;
	hdr->layout.rx_size = 0;

	rc = mctp_astlpc_poll(host.astlpc);
	assert(rc < 0);

	endpoint_destroy(&host);
	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_buffers_bad_host_init(void)
{
	struct astlpc_endpoint host;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	host.mctp = mctp_init();
	assert(host.mctp);
	host.mmio.kcs = &kcs;
	host.mmio.bmc = false;

	/* Set the MTU to 0 to provoke a failure */
	host.astlpc = mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, 0,
				       lpc_mem, &astlpc_direct_mmio_ops,
				       &host.mmio);

	rc = mctp_register_bus(host.mctp, &host.astlpc->binding, 8);
	assert(rc < 0);

	mctp_astlpc_destroy(host.astlpc);
	mctp_destroy(host.mctp);
	free(lpc_mem);
}

static void astlpc_test_negotiate_increased_mtu(void)
{
	struct astlpc_endpoint bmc, host;
	uint8_t kcs[2] = { 0 };
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, 3 * MCTP_BTU,
			   &kcs, lpc_mem);
	assert(!rc);

	/* Host initialisation */
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST,
			   2 * MCTP_BTU, &kcs, lpc_mem);
	assert(!rc);

	rc = mctp_astlpc_poll(bmc.astlpc);
	assert(rc == 0);

	rc = mctp_astlpc_poll(host.astlpc);
	assert(rc == 0);

	endpoint_destroy(&host);
	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_negotiate_mtu_low_high(void)
{
	struct astlpc_endpoint bmc, host;
	uint8_t kcs[2] = { 0 };
	uint32_t bmtu, hmtu;
	void *lpc_mem;
	int rc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	bmtu = 3 * MCTP_BTU;
	rc = endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, bmtu, &kcs,
			   lpc_mem);
	assert(!rc);

	/* Host initialisation with low MTU */
	hmtu = 2 * MCTP_BTU;
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, hmtu, &kcs,
			   lpc_mem);
	assert(!rc);

	/* Process low MTU proposal */
	rc = mctp_astlpc_poll(bmc.astlpc);
	assert(rc == 0);

	/* Accept low MTU proposal */
	rc = mctp_astlpc_poll(host.astlpc);
	assert(rc == 0);

	assert(host.astlpc->layout.rx.size ==
	       astlpc_layout_ctx.proto->packet_size(MCTP_PACKET_SIZE(hmtu)));

	/* Tear-down the host so we can bring up a new one */
	endpoint_destroy(&host);

	/*
	 * Bring up a new host endpoint with a higher MTU than we previously
	 * negotiated
	 */
	hmtu = 3 * MCTP_BTU;
	rc = endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, hmtu, &kcs,
			   lpc_mem);
	assert(!rc);

	/* Process high MTU proposal */
	rc = mctp_astlpc_poll(bmc.astlpc);
	assert(rc == 0);

	/* Accept high MTU proposal */
	rc = mctp_astlpc_poll(host.astlpc);
	assert(rc == 0);

	assert(host.astlpc->layout.rx.size ==
	       astlpc_layout_ctx.proto->packet_size(MCTP_PACKET_SIZE(bmtu)));

	endpoint_destroy(&host);
	endpoint_destroy(&bmc);
	free(lpc_mem);
}

static void astlpc_test_send_large_packet(void)
{
	struct astlpc_endpoint *bmc, *host;
	struct astlpc_test ctx;
	uint8_t kcs[2] = { 0 };
	uint8_t tag = 0;
	void *lpc_mem;
	int rc;

	host = &ctx.host;
	bmc = &ctx.bmc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, 8192, &kcs,
			   lpc_mem);
	assert(!rc);

	/* Host initialisation */
	rc = endpoint_init(host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, 8192, &kcs,
			   lpc_mem);
	assert(!rc);

	ctx.count = 0;
	mctp_set_rx_all(bmc->mctp, astlpc_test_rx_message, &ctx);

	rc = mctp_astlpc_poll(bmc->astlpc);
	assert(rc == 0);

	rc = mctp_astlpc_poll(host->astlpc);
	assert(rc == 0);

	ctx.msg = malloc(2 * MCTP_BODY_SIZE(8192));
	assert(ctx.msg);

	memset(ctx.msg, 0x5a, 2 * MCTP_BODY_SIZE(8192));

	rc = mctp_message_tx(host->mctp, 8, MCTP_MESSAGE_TO_DST, tag, ctx.msg,
			     2 * MCTP_BODY_SIZE(8192));
	assert(rc == 0);
	rc = mctp_astlpc_poll(bmc->astlpc);
	assert(rc == 0);
	rc = mctp_astlpc_poll(host->astlpc);
	assert(rc == 0);
	rc = mctp_astlpc_poll(bmc->astlpc);
	assert(rc == 0);
	rc = mctp_astlpc_poll(host->astlpc);
	assert(rc == 0);

	assert(ctx.count == 1);

	free(ctx.msg);
	endpoint_destroy(host);
	endpoint_destroy(bmc);
	free(lpc_mem);
}

static void astlpc_test_negotiate_mtu_high_low(void)
{
	uint8_t msg[3 * MCTP_BTU] = { 0 };
	struct astlpc_test ctx = { 0 };
	uint32_t bmtu, hmtu;
	uint8_t tag = 0;
	int rc;

	/* Configure message */
	memset(&msg[0], 0xa5, sizeof(msg));

	/* Test harness initialisation */
	ctx.lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(ctx.lpc_mem);

	/* BMC initialisation */
	bmtu = 3 * MCTP_BTU;
	rc = endpoint_init(&ctx.bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, bmtu,
			   &ctx.kcs, ctx.lpc_mem);
	assert(!rc);

	/* Host initialisation with low MTU */
	hmtu = 3 * MCTP_BTU;
	rc = endpoint_init(&ctx.host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, hmtu,
			   &ctx.kcs, ctx.lpc_mem);
	assert(!rc);

	/* Configure host message handler */
	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* Startup BMC and host interfaces */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);

	/*
	 * Transmit a message to place a packet on the interface. This releases the buffer and
	 * disables the binding, plugging the binding's transmit queue while the host hasn't polled
	 * to pull the packet off.
	 */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_DST, tag, msg,
			     sizeof(msg));

	/* Leave the packet in place on the interface by not polling the host binding */

	/*
	 * Transmit another message to force packetisation at the current MTU while the binding is
	 * disabled, leaving the packet(s) in the binding's transmit queue
	 */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_DST, tag, msg,
			     sizeof(msg));

	/* Tear-down the host so we can bring up a new one */
	endpoint_destroy(&ctx.host);

	/* Bring up a new host endpoint with a lower MTU than we previously negotiated */
	hmtu = 2 * MCTP_BTU;
	rc = endpoint_init(&ctx.host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, hmtu,
			   &ctx.kcs, ctx.lpc_mem);
	assert(!rc);

	/* Configure host message handler again after reinitialisation */
	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* Process low MTU proposal */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	/* Accept low MTU proposal */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);

	/*
	 * Check that there are no outstanding messages to be received by the host. The message
	 * packetised on the BMC at the larger MTU must be dropped as its now no longer possible to
	 * transmit those packets
	 */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);
	assert(ctx.count == 0);

	/* Transmit another message from the BMC to the host, packetised using the new MTU */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_DST, tag, msg,
			     hmtu);

	/* Check that the most recent BMC transmission is received by the host */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);
	assert(ctx.count == 1);

	/* Ensure buffer ownership is returned to the BMC and the BMC Tx queue is processed */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	/* Check that no further messages are propagated to the host */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);
	assert(ctx.count == 1);

	endpoint_destroy(&ctx.host);
	endpoint_destroy(&ctx.bmc);
	free(ctx.lpc_mem);
}

static void astlpc_test_tx_before_channel_init(void)
{
	struct astlpc_endpoint *bmc;
	struct astlpc_test ctx;
	uint8_t kcs[2] = { 0 };
	uint8_t msg[MCTP_BTU];
	uint8_t tag = 0;
	void *lpc_mem;
	int rc;

	bmc = &ctx.bmc;

	/* Test harness initialisation */
	lpc_mem = calloc(1, 1 * 1024 * 1024);
	assert(lpc_mem);

	/* BMC initialisation */
	rc = endpoint_init(bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, 0, &kcs,
			   lpc_mem);
	assert(!rc);

	memset(msg, '\0', sizeof(msg));

	/*
	 * There was once a bug where the calculated MTU was 0 and the
	 * packetisation loop in mctp_message_tx_on_bus() allocated all the
	 * memory. Catch the bug and avoid OOMing the test machine by
	 * terminating after a period long enough to packetise the message.
	 */
	alarm(1);
	mctp_message_tx(bmc->mctp, 9, MCTP_MESSAGE_TO_SRC, tag, msg,
			sizeof(msg));
	alarm(0);

	endpoint_destroy(bmc);
	free(lpc_mem);
}

static void astlpc_test_corrupt_host_tx(void)
{
	struct astlpc_test ctx = { 0 };
	struct mctp_lpcmap_hdr *hdr;
	uint8_t msg[MCTP_BTU];
	uint32_t offset;
	uint8_t tag = 0;
	uint32_t code;
	uint8_t *tlr;
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0xa5, MCTP_BTU);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.bmc.mctp, astlpc_test_rx_message, &ctx);

	/* Host sends the single-packet message */
	rc = mctp_message_tx(ctx.host.mctp, 8, MCTP_MESSAGE_TO_DST, tag, msg,
			     sizeof(msg));
	assert(rc == 0);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x01);

	astlpc_assert_tx_packet(&ctx.host, &msg[0], MCTP_BTU);

	/* Corrupt the CRC-32 in the message trailer */
	hdr = (struct mctp_lpcmap_hdr *)ctx.lpc_mem;
	offset = be32toh(hdr->layout.tx_offset);
	tlr = (uint8_t *)&ctx.lpc_mem[offset] + 4 + sizeof(msg);
	memcpy(&code, tlr, sizeof(code));
	code = ~code;
	memcpy(tlr, &code, sizeof(code));

	/* BMC receives the single-packet message */
	mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(ctx.count == 0);

	/* BMC returns Tx area ownership to Host */
	assert(!(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF));
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x02);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);

	/* Host dequeues ownership hand-over */
	rc = mctp_astlpc_poll(ctx.host.astlpc);
	assert(rc == 0);

	network_destroy(&ctx);
}

static void astlpc_test_corrupt_bmc_tx(void)
{
	struct astlpc_test ctx = { 0 };
	struct mctp_lpcmap_hdr *hdr;
	uint8_t msg[MCTP_BTU];
	uint32_t offset;
	uint8_t tag = 0;
	uint32_t code;
	uint8_t *tlr;
	int rc;

	/* Test harness initialisation */

	network_init(&ctx);

	memset(&msg[0], 0x5a, MCTP_BTU);

	ctx.msg = &msg[0];
	ctx.count = 0;
	mctp_set_rx_all(ctx.host.mctp, astlpc_test_rx_message, &ctx);

	/* BMC sends the single-packet message */
	rc = mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_SRC, tag, msg,
			     sizeof(msg));
	assert(rc == 0);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x01);

	/* Check that the BMC sent a fully-formed packet */
	astlpc_assert_tx_packet(&ctx.bmc, &msg[0], MCTP_BTU);

	/* Corrupt the CRC-32 in the message trailer */
	hdr = (struct mctp_lpcmap_hdr *)ctx.lpc_mem;
	offset = be32toh(hdr->layout.rx_offset);
	tlr = (uint8_t *)&ctx.lpc_mem[offset] + 4 + sizeof(msg);
	memcpy(&code, tlr, sizeof(code));
	code = ~code;
	memcpy(tlr, &code, sizeof(code));

	/* Host drops the single-packet message */
	mctp_astlpc_poll(ctx.host.astlpc);
	assert(ctx.count == 0);

	/* Host returns Rx area ownership to BMC */
	assert(!(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_OBF));
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_DATA] == 0x02);
	assert(ctx.kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);

	/* BMC dequeues ownership hand-over */
	rc = mctp_astlpc_poll(ctx.bmc.astlpc);
	assert(rc == 0);

	network_destroy(&ctx);
}

static void astlpc_test_async_exchange(void)
{
	struct astlpc_test ctx = { 0 };
	uint8_t msg[MCTP_BTU];
	struct pollfd pollfd;
	uint8_t tag = 0;

	network_init(&ctx);

	memset(&msg[0], 0x5a, MCTP_BTU);

	/* (1)
	 * Fill the KCS transmit buffer by sending a message from the BMC to the host without
	 * dequeuing it on the host side
	 */
	mctp_message_tx(ctx.bmc.mctp, 9, MCTP_MESSAGE_TO_SRC, tag, msg,
			sizeof(msg));

	/* (2)
	 * Assert that we're still listening for in-bound messages on the BMC
	 */
	mctp_astlpc_init_pollfd(ctx.bmc.astlpc, &pollfd);
	assert(pollfd.events & POLLIN);
	assert(!(pollfd.events & POLLOUT));

	/* (3)
	 * Send a message from the host to the BMC and dequeue the message on the BMC, triggering a
	 * buffer ownership transfer command back to the host
	 */
	mctp_message_tx(ctx.host.mctp, 8, MCTP_MESSAGE_TO_SRC, tag, msg,
			sizeof(msg));
	mctp_astlpc_poll(ctx.bmc.astlpc);

	/* (4)
	 * Assert that the BMC has to wait for the host to dequeue the ownership transfer command
	 * from (1) before further transfers take place.
	 */
	mctp_astlpc_init_pollfd(ctx.bmc.astlpc, &pollfd);
	assert(!(pollfd.events & POLLIN));
	assert(pollfd.events & POLLOUT);

	/* (5)
	 * Dequeue the message from (1) on the host side, allowing transmisson of the outstanding
	 * ownership transfer command from (3)
	 */
	mctp_astlpc_poll(ctx.host.astlpc);

	/* (6)
	 * Emulate a POLLOUT event on the BMC side
	 */
	mctp_astlpc_poll(ctx.bmc.astlpc);

	/* (7)
	 * Assert that we're again listening for in-bound messages on the BMC.
	 */
	mctp_astlpc_init_pollfd(ctx.bmc.astlpc, &pollfd);
	assert(pollfd.events & POLLIN);
	assert(!(pollfd.events & POLLOUT));

	network_destroy(&ctx);
}

/* clang-format off */
#define TEST_CASE(test) { #test, test }
static const struct {
	const char *name;
	void (*test)(void);
} astlpc_tests[] = {
	TEST_CASE(astlpc_test_simple_init),
	TEST_CASE(astlpc_test_bad_version),
	TEST_CASE(astlpc_test_incompatible_versions),
	TEST_CASE(astlpc_test_choose_bmc_ver_cur),
	TEST_CASE(astlpc_test_choose_host_ver_cur),
	TEST_CASE(astlpc_test_version_host_fails_negotiation),
	TEST_CASE(astlpc_test_version_bmc_fails_negotiation),
	TEST_CASE(astlpc_test_host_before_bmc),
	TEST_CASE(astlpc_test_simple_message_bmc_to_host),
	TEST_CASE(astlpc_test_simple_message_host_to_bmc),
	TEST_CASE(astlpc_test_packetised_message_bmc_to_host),
	TEST_CASE(astlpc_test_simple_indirect_message_bmc_to_host),
	TEST_CASE(astlpc_test_host_tx_bmc_gone),
	TEST_CASE(astlpc_test_poll_not_ready),
	TEST_CASE(astlpc_test_undefined_command),
	TEST_CASE(astlpc_test_buffers_rx_offset_overflow),
	TEST_CASE(astlpc_test_buffers_tx_offset_overflow),
	TEST_CASE(astlpc_test_buffers_rx_size_overflow),
	TEST_CASE(astlpc_test_buffers_tx_size_overflow),
	TEST_CASE(astlpc_test_buffers_rx_window_violation),
	TEST_CASE(astlpc_test_buffers_tx_window_violation),
	TEST_CASE(astlpc_test_buffers_rx_size_fails_btu),
	TEST_CASE(astlpc_test_buffers_tx_size_fails_btu),
	TEST_CASE(astlpc_test_buffers_overlap_rx_low),
	TEST_CASE(astlpc_test_buffers_overlap_tx_low),
	TEST_CASE(astlpc_test_buffers_bad_host_proposal),
	TEST_CASE(astlpc_test_buffers_bad_bmc_proposal),
	TEST_CASE(astlpc_test_buffers_bad_bmc_negotiation),
	TEST_CASE(astlpc_test_buffers_overlap_exact),
	TEST_CASE(astlpc_test_buffers_overlap_control),
	TEST_CASE(astlpc_test_buffers_bad_host_init),
	TEST_CASE(astlpc_test_negotiate_increased_mtu),
	TEST_CASE(astlpc_test_negotiate_mtu_low_high),
	TEST_CASE(astlpc_test_negotiate_mtu_high_low),
	TEST_CASE(astlpc_test_send_large_packet),
	TEST_CASE(astlpc_test_tx_before_channel_init),
	TEST_CASE(astlpc_test_corrupt_host_tx),
	TEST_CASE(astlpc_test_corrupt_bmc_tx),
	TEST_CASE(astlpc_test_async_exchange),
};
/* clang-format on */

#ifndef BUILD_ASSERT
#define BUILD_ASSERT(x)                                                        \
	do {                                                                   \
		(void)sizeof(char[0 - (!(x))]);                                \
	} while (0)
#endif

int main(void)
{
	size_t i;

	mctp_set_log_stdio(MCTP_LOG_DEBUG);

	BUILD_ASSERT(ARRAY_SIZE(astlpc_tests) < SIZE_MAX);
	for (i = 0; i < ARRAY_SIZE(astlpc_tests); i++) {
		mctp_prlog(MCTP_LOG_DEBUG, "begin: %s", astlpc_tests[i].name);
		astlpc_tests[i].test();
		mctp_prlog(MCTP_LOG_DEBUG, "end: %s\n", astlpc_tests[i].name);
	}

	return 0;
}
