/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#include "container-of.h"
#include "mctp-defines.h"
#include "responder.h"
#include "socket.h"
#include "transport.h"

#include <libpldm/base.h>
#include <libpldm/pldm.h>
#include <libpldm/transport.h>
#include <libpldm/transport/af-mctp.h>

#include <errno.h>
#include <limits.h>
#include <linux/mctp.h>
#include <poll.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

struct pldm_responder_cookie_af_mctp {
	struct pldm_responder_cookie req;
	struct sockaddr_mctp smctp;
};

#define cookie_to_af_mctp(c)                                                   \
	container_of((c), struct pldm_responder_cookie_af_mctp, req)

#define AF_MCTP_NAME "AF_MCTP"
struct pldm_transport_af_mctp {
	struct pldm_transport transport;
	int socket;
	pldm_tid_t tid_eid_map[MCTP_MAX_NUM_EID];
	struct pldm_socket_sndbuf socket_send_buf;
	bool bound;
	struct pldm_responder_cookie cookie_jar;
};

#define transport_to_af_mctp(ptr)                                              \
	container_of(ptr, struct pldm_transport_af_mctp, transport)

LIBPLDM_ABI_STABLE
struct pldm_transport *
pldm_transport_af_mctp_core(struct pldm_transport_af_mctp *ctx)
{
	return &ctx->transport;
}

LIBPLDM_ABI_STABLE
int pldm_transport_af_mctp_init_pollfd(struct pldm_transport *t,
				       struct pollfd *pollfd)
{
	struct pldm_transport_af_mctp *ctx = transport_to_af_mctp(t);
	pollfd->fd = ctx->socket;
	pollfd->events = POLLIN;
	return 0;
}

static int pldm_transport_af_mctp_get_eid(struct pldm_transport_af_mctp *ctx,
					  pldm_tid_t tid, mctp_eid_t *eid)
{
	int i;
	for (i = 0; i < MCTP_MAX_NUM_EID; i++) {
		if (ctx->tid_eid_map[i] == tid) {
			*eid = i;
			return 0;
		}
	}
	*eid = -1;
	return -1;
}

static int pldm_transport_af_mctp_get_tid(struct pldm_transport_af_mctp *ctx,
					  mctp_eid_t eid, pldm_tid_t *tid)
{
	if (ctx->tid_eid_map[eid] != 0) {
		*tid = ctx->tid_eid_map[eid];
		return 0;
	}
	return -1;
}

LIBPLDM_ABI_STABLE
int pldm_transport_af_mctp_map_tid(struct pldm_transport_af_mctp *ctx,
				   pldm_tid_t tid, mctp_eid_t eid)
{
	ctx->tid_eid_map[eid] = tid;

	return 0;
}

LIBPLDM_ABI_STABLE
int pldm_transport_af_mctp_unmap_tid(struct pldm_transport_af_mctp *ctx,
				     __attribute__((unused)) pldm_tid_t tid,
				     mctp_eid_t eid)
{
	ctx->tid_eid_map[eid] = 0;

	return 0;
}

static pldm_requester_rc_t pldm_transport_af_mctp_recv(struct pldm_transport *t,
						       pldm_tid_t *tid,
						       void **pldm_msg,
						       size_t *msg_len)
{
	struct pldm_transport_af_mctp *af_mctp = transport_to_af_mctp(t);
	struct sockaddr_mctp addr = { 0 };
	socklen_t addrlen = sizeof(addr);
	struct pldm_msg_hdr *hdr;
	pldm_requester_rc_t res;
	mctp_eid_t eid = 0;
	ssize_t length;
	void *msg;
	int rc;

	length = recv(af_mctp->socket, NULL, 0, MSG_PEEK | MSG_TRUNC);
	if (length <= 0) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	msg = malloc(length);
	if (!msg) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	length = recvfrom(af_mctp->socket, msg, length, MSG_TRUNC,
			  (struct sockaddr *)&addr, &addrlen);
	if (length < (ssize_t)sizeof(struct pldm_msg_hdr)) {
		res = PLDM_REQUESTER_INVALID_RECV_LEN;
		goto cleanup_msg;
	}

	eid = addr.smctp_addr.s_addr;
	rc = pldm_transport_af_mctp_get_tid(af_mctp, eid, tid);
	if (rc) {
		res = PLDM_REQUESTER_RECV_FAIL;
		goto cleanup_msg;
	}

	hdr = msg;

	if (af_mctp->bound && hdr->request) {
		struct pldm_responder_cookie_af_mctp *cookie;

		cookie = malloc(sizeof(*cookie));
		if (!cookie) {
			res = PLDM_REQUESTER_RECV_FAIL;
			goto cleanup_msg;
		}

		cookie->req.tid = *tid,
		cookie->req.instance_id = hdr->instance_id,
		cookie->req.type = hdr->type,
		cookie->req.command = hdr->command;
		cookie->smctp = addr;

		rc = pldm_responder_cookie_track(&af_mctp->cookie_jar,
						 &cookie->req);
		if (rc) {
			res = PLDM_REQUESTER_RECV_FAIL;
			goto cleanup_msg;
		}
	}

	*pldm_msg = msg;
	*msg_len = length;

	return PLDM_REQUESTER_SUCCESS;

cleanup_msg:
	free(msg);

	return res;
}

static pldm_requester_rc_t pldm_transport_af_mctp_send(struct pldm_transport *t,
						       pldm_tid_t tid,
						       const void *pldm_msg,
						       size_t msg_len)
{
	struct pldm_transport_af_mctp *af_mctp = transport_to_af_mctp(t);
	const struct pldm_msg_hdr *hdr;
	struct sockaddr_mctp addr = { 0 };

	if (msg_len < (ssize_t)sizeof(struct pldm_msg_hdr)) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	hdr = pldm_msg;
	if (af_mctp->bound && !hdr->request) {
		struct pldm_responder_cookie_af_mctp *cookie;
		struct pldm_responder_cookie *req;

		req = pldm_responder_cookie_untrack(&af_mctp->cookie_jar, tid,
						    hdr->instance_id, hdr->type,
						    hdr->command);
		if (!req) {
			return PLDM_REQUESTER_SEND_FAIL;
		}

		cookie = cookie_to_af_mctp(req);
		addr = cookie->smctp;
		/* Clear the TO to indicate a response */
		addr.smctp_tag &= ~MCTP_TAG_OWNER;
		free(cookie);
	} else {
		mctp_eid_t eid = 0;
		if (pldm_transport_af_mctp_get_eid(af_mctp, tid, &eid)) {
			return PLDM_REQUESTER_SEND_FAIL;
		}

		addr.smctp_family = AF_MCTP;
		addr.smctp_addr.s_addr = eid;
		addr.smctp_type = MCTP_MSG_TYPE_PLDM;
		addr.smctp_tag = MCTP_TAG_OWNER;
	}

	if (msg_len > INT_MAX ||
	    pldm_socket_sndbuf_accomodate(&(af_mctp->socket_send_buf),
					  (int)msg_len)) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	ssize_t rc = sendto(af_mctp->socket, pldm_msg, msg_len, 0,
			    (struct sockaddr *)&addr, sizeof(addr));
	if (rc == -1) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	return PLDM_REQUESTER_SUCCESS;
}

LIBPLDM_ABI_STABLE
int pldm_transport_af_mctp_init(struct pldm_transport_af_mctp **ctx)
{
	if (!ctx || *ctx) {
		return -EINVAL;
	}

	struct pldm_transport_af_mctp *af_mctp =
		calloc(1, sizeof(struct pldm_transport_af_mctp));
	if (!af_mctp) {
		return -ENOMEM;
	}

	af_mctp->transport.name = AF_MCTP_NAME;
	af_mctp->transport.version = 1;
	af_mctp->transport.recv = pldm_transport_af_mctp_recv;
	af_mctp->transport.send = pldm_transport_af_mctp_send;
	af_mctp->transport.init_pollfd = pldm_transport_af_mctp_init_pollfd;
	af_mctp->bound = false;
	af_mctp->cookie_jar.next = NULL;
	af_mctp->socket = socket(AF_MCTP, SOCK_DGRAM, 0);
	if (af_mctp->socket == -1) {
		free(af_mctp);
		return -1;
	}

	if (pldm_socket_sndbuf_init(&af_mctp->socket_send_buf,
				    af_mctp->socket)) {
		close(af_mctp->socket);
		free(af_mctp);
		return -1;
	}

	*ctx = af_mctp;
	return 0;
}

LIBPLDM_ABI_STABLE
void pldm_transport_af_mctp_destroy(struct pldm_transport_af_mctp *ctx)
{
	if (!ctx) {
		return;
	}
	close(ctx->socket);
	free(ctx);
}

LIBPLDM_ABI_STABLE
int pldm_transport_af_mctp_bind(struct pldm_transport_af_mctp *transport,
				const struct sockaddr_mctp *smctp, size_t len)
{
	struct sockaddr_mctp lsmctp = { 0 };
	int rc;

	if (!transport) {
		return PLDM_REQUESTER_INVALID_SETUP;
	}

	if (!smctp && len) {
		return PLDM_REQUESTER_INVALID_SETUP;
	}

	if (!smctp) {
		lsmctp.smctp_family = AF_MCTP;
		lsmctp.smctp_network = MCTP_NET_ANY;
		lsmctp.smctp_addr.s_addr = MCTP_ADDR_ANY;
		lsmctp.smctp_type = MCTP_MSG_TYPE_PLDM;
		lsmctp.smctp_tag = MCTP_TAG_OWNER;
		smctp = &lsmctp;
		len = sizeof(lsmctp);
	}

	if (smctp->smctp_family != AF_MCTP ||
	    smctp->smctp_type != MCTP_MSG_TYPE_PLDM ||
	    smctp->smctp_tag != MCTP_TAG_OWNER) {
		return PLDM_REQUESTER_INVALID_SETUP;
	}

	if (len != sizeof(*smctp)) {
		return PLDM_REQUESTER_INVALID_SETUP;
	}

	rc = bind(transport->socket, (const struct sockaddr *)smctp,
		  sizeof(*smctp));
	if (rc) {
		return PLDM_REQUESTER_SETUP_FAIL;
	}

	transport->bound = true;

	return PLDM_REQUESTER_SUCCESS;
}
