// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include <errno.h>
#include <stdlib.h>

#include "common.h"
#include "dbus.h"
#include "control_dbus.h"
#include "mboxd.h"

/* Command IDs (Legacy interface) */
#define DBUS_C_PING            0x00
#define DBUS_C_DAEMON_STATE    0x01
#define DBUS_C_RESET           0x02
#define DBUS_C_SUSPEND         0x03
#define DBUS_C_RESUME          0x04
#define DBUS_C_MODIFIED        0x05
#define DBUS_C_KILL            0x06
#define DBUS_C_LPC_STATE       0x07
#define NUM_DBUS_CMDS          (DBUS_C_LPC_STATE + 1)

/* Return Values (Legacy interface) */
#define DBUS_SUCCESS           0x00 /* Command Succeded */
#define E_DBUS_INTERNAL        0x01 /* Internal DBUS Error */
#define E_DBUS_INVAL           0x02 /* Invalid Command */
#define E_DBUS_REJECTED        0x03 /* Daemon Rejected Request */
#define E_DBUS_HARDWARE        0x04 /* BMC Hardware Error */
#define E_DBUS_NO_MEM          0x05 /* Failed Memory Allocation */

struct mbox_dbus_msg {
       uint8_t cmd;
       size_t num_args;
       uint8_t *args;
};

/*
 * Command: DBUS Ping
 * Ping the daemon
 *
 * Args: NONE
 * Resp: NONE
 */
static int control_legacy_ping(struct mbox_context *context,
			   struct mbox_dbus_msg *req,
			   struct mbox_dbus_msg *resp)
{
	return control_ping(context);
}

/*
 * Command: DBUS Status
 * Get the status of the daemon
 *
 * Args: NONE
 * Resp[0]: Status Code
 */
static int control_legacy_daemon_state(struct mbox_context *context,
					  struct mbox_dbus_msg *req,
					  struct mbox_dbus_msg *resp)
{
	resp->num_args = DAEMON_STATE_NUM_ARGS;
	resp->args = calloc(resp->num_args, sizeof(*resp->args));
	resp->args[0] = control_daemon_state(context);

	return 0;
}

/*
 * Command: DBUS LPC State
 * Get the state of the lpc bus mapping (whether it points to memory or flash
 *
 * Args: NONE
 * Resp[0]: LPC Bus State Code
 */
static int control_legacy_lpc_state(struct mbox_context *context,
				       struct mbox_dbus_msg *req,
				       struct mbox_dbus_msg *resp)
{
	resp->num_args = LPC_STATE_NUM_ARGS;
	resp->args = calloc(resp->num_args, sizeof(*resp->args));
	resp->args[0] = control_lpc_state(context);

	return 0;
}

/*
 * Command: DBUS Reset
 * Reset the daemon state, final operation TBA.
 * For now we just point the lpc mapping back at the flash.
 *
 * Args: NONE
 * Resp: NONE
 */
static int control_legacy_reset(struct mbox_context *context,
				   struct mbox_dbus_msg *req,
				   struct mbox_dbus_msg *resp)
{
	int rc;

	rc = control_reset(context);

	/* Map return codes for compatibility */
	if (rc == -EBUSY) {
		return -E_DBUS_REJECTED;
	} else if (rc < 0) {
		return -E_DBUS_HARDWARE;
	}

	return rc;
}

/*
 * Command: DBUS Kill
 * Stop the daemon
 *
 * Args: NONE
 * Resp: NONE
 */
static int control_legacy_kill(struct mbox_context *context,
				  struct mbox_dbus_msg *req,
				  struct mbox_dbus_msg *resp)
{
	return control_kill(context);
}

/*
 * Command: DBUS Flash Modified
 * Used to notify the daemon that the flash has been modified out from under
 * it - We need to reset all out windows to ensure flash will be reloaded
 * when a new window is opened.
 * Note: We don't flush any previously opened windows
 *
 * Args: NONE
 * Resp: NONE
 */
static int control_legacy_modified(struct mbox_context *context,
				      struct mbox_dbus_msg *req,
				      struct mbox_dbus_msg *resp)
{
	return control_modified(context);
}

/*
 * Command: DBUS Suspend
 * Suspend the daemon to inhibit it from performing flash accesses.
 * This is used to synchronise access to the flash between the daemon and
 * directly from the BMC.
 *
 * Args: NONE
 * Resp: NONE
 */
static int control_legacy_suspend(struct mbox_context *context,
				     struct mbox_dbus_msg *req,
				     struct mbox_dbus_msg *resp)
{
	int rc;

	rc = control_suspend(context);
	if (rc < 0) {
		/* Map return codes for compatibility */
		return -E_DBUS_HARDWARE;
	}

	return rc;
}

/*
 * Command: DBUS Resume
 * Resume the daemon to let it perform flash accesses again.
 *
 * Args[0]: Flash Modified (0 - no | 1 - yes)
 * Resp: NONE
 */
static int control_legacy_resume(struct mbox_context *context,
				    struct mbox_dbus_msg *req,
				    struct mbox_dbus_msg *resp)
{
	int rc;

	if (req->num_args != 1) {
		return -E_DBUS_INVAL;
	}

	rc = control_resume(context, req->args[0] == RESUME_FLASH_MODIFIED);
	if (rc < 0) {
		/* Map return codes for compatibility */
		rc = -E_DBUS_HARDWARE;
	}

	return rc;
}

typedef int (*control_action)(struct mbox_context *context,
				 struct mbox_dbus_msg *req,
				 struct mbox_dbus_msg *resp);
static const control_action dbus_handlers[NUM_DBUS_CMDS] = {
	control_legacy_ping,
	control_legacy_daemon_state,
	control_legacy_reset,
	control_legacy_suspend,
	control_legacy_resume,
	control_legacy_modified,
	control_legacy_kill,
	control_legacy_lpc_state
};

static int method_cmd(sd_bus_message *m, void *userdata,
		      sd_bus_error *ret_error)
{
	struct mbox_dbus_msg req = { 0 }, resp = { 0 };
	struct mbox_context *context;
	sd_bus_message *n;
	int rc, i;

	context = (struct mbox_context *) userdata;
	if (!context) {
		MSG_ERR("DBUS Internal Error\n");
		rc = -E_DBUS_INTERNAL;
		goto out;
	}

	/* Read the command */
	rc = sd_bus_message_read(m, "y", &req.cmd);
	if (rc < 0) {
		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
		rc = -E_DBUS_INTERNAL;
		goto out;
	}
	MSG_DBG("DBUS request: %u\n", req.cmd);

	/* Read the args */
	rc = sd_bus_message_read_array(m, 'y', (const void **) &req.args,
				       &req.num_args);
	if (rc < 0) {
		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
		rc = -E_DBUS_INTERNAL;
		goto out;
	}
	MSG_DBG("DBUS num_args: %u\n", (unsigned) req.num_args);
	for (i = 0; i < req.num_args; i++) {
		MSG_DBG("DBUS arg[%d]: %u\n", i, req.args[i]);
	}

	/* Handle the command */
	if (req.cmd >= NUM_DBUS_CMDS) {
		rc = -E_DBUS_INVAL;
		MSG_ERR("Received unknown dbus cmd: %d\n", req.cmd);
	} else {
		rc = dbus_handlers[req.cmd](context, &req, &resp);
	}

out:
	if (rc < 0) {
		resp.cmd = -rc;
	}
	rc = sd_bus_message_new_method_return(m, &n); /* Generate response */
	if (rc < 0) {
		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
		goto cleanup;
	}

	rc = sd_bus_message_append(n, "y", resp.cmd); /* Set return code */
	if (rc < 0) {
		MSG_ERR("sd_bus_message_append failed: %d\n", rc);
		goto cleanup;
	}

	rc = sd_bus_message_append_array(n, 'y', resp.args, resp.num_args);
	if (rc < 0) {
		MSG_ERR("sd_bus_message_append_array failed: %d\n", rc);
		goto cleanup;
	}

	MSG_DBG("DBUS response: %u\n", resp.cmd);
	MSG_DBG("DBUS num_args: %u\n", (unsigned) resp.num_args);
	for (i = 0; i < resp.num_args; i++) {
		MSG_DBG("DBUS arg[%d]: %u\n", i, resp.args[i]);
	}

	rc = sd_bus_send(NULL, n, NULL); /* Send response */
	if (rc < 0)
		MSG_ERR("sd_bus_send failed: %d\n", rc);

cleanup:
	free(resp.args);
	return rc;
}

static const sd_bus_vtable control_legacy_vtable[] = {
	SD_BUS_VTABLE_START(0),
	SD_BUS_METHOD("cmd", "yay", "yay", &method_cmd,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_VTABLE_END
};

int control_legacy_init(struct mbox_context *context)
{
	int rc;

	rc = sd_bus_add_object_vtable(context->bus, NULL,
				      MBOX_DBUS_LEGACY_OBJECT,
				      MBOX_DBUS_LEGACY_NAME,
				      control_legacy_vtable, context);
	if (rc < 0) {
		MSG_ERR("Failed to register vtable: %s\n", strerror(-rc));
		return rc;
	}

	return sd_bus_request_name(context->bus, MBOX_DBUS_LEGACY_NAME,
				 SD_BUS_NAME_ALLOW_REPLACEMENT |
				 SD_BUS_NAME_REPLACE_EXISTING);
}

void control_legacy_free(struct mbox_context *context __attribute__((unused)))
{
	return;
}
