/* Copyright 2017 - 2018 Intel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/ipmi_bmc.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <systemd/sd-bus.h>
#include <time.h>
#include <unistd.h>
#include <stdbool.h>

#define DBUS_ERR "org.openbmc.error"

#define LOG_PREFIX "KCSBRIDGED"
#define DBUS_NAME "org.openbmc.HostIpmi."
#define OBJ_NAME "/org/openbmc/HostIpmi/"

#define KCS_TIMEOUT_IN_SEC 5
#define KCS_MESSAGE_SIZE 256

#define SD_BUS_FD 0
#define KCS_FD 1
#define TIMER_FD 2
#define TOTAL_FDS 3

#define NAMEBUFFERLEN 50
#define OPTMAXLEN (NAMEBUFFERLEN - sizeof(OBJ_NAME) - 1)

char kcsDevice[NAMEBUFFERLEN];
char busName[NAMEBUFFERLEN];
char objPath[NAMEBUFFERLEN];

struct kcs_msg_req {
	uint8_t netfn;
	uint8_t lun;
	uint8_t cmd;
	uint8_t *data;
	size_t data_len;
};

struct kcsbridged_context {
	struct pollfd fds[TOTAL_FDS];
	struct sd_bus *bus;

	/*
	 * Request and Response Messages are paired together as a Write Transfer
	 * to the BMC to send the request followed by a Read Transfer from the
	 * BMC to get the response.
	 */
	int expired;
	uint8_t seqnum;
	struct kcs_msg_req req;
};

enum { KCS_LOG_NONE = 0, KCS_LOG_VERBOSE, KCS_LOG_DEBUG };

static void (*kcs_vlog)(int p, const char *fmt, va_list args);
static int verbosity = KCS_LOG_NONE;

#define MSG_OUT(f_, ...)                                                       \
	do {                                                                   \
		if (verbosity != KCS_LOG_NONE)                                 \
			kcs_log(LOG_INFO, f_, ##__VA_ARGS__);                  \
	} while (0)

#define MSG_ERR(f_, ...)                                                       \
	do {                                                                   \
		if (verbosity != KCS_LOG_NONE)                                 \
			kcs_log(LOG_ERR, f_, ##__VA_ARGS__);                   \
	} while (0)

static void kcs_log_console(int p, const char *fmt, va_list args)
{
	vfprintf(stderr, fmt, args);
}

__attribute__((format(printf, 2, 3))) static void kcs_log(int p,
							  const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	kcs_vlog(p, fmt, args);
	va_end(args);
}

static void kcs_dump_data(uint8_t *data, size_t data_len)
{
	size_t i;
	int str_len;
	char str[64];

	str_len = 0;
	for (i = 0; i < data_len; i++) {
		if (i % 8 == 0) {
			if (i != 0) {
				kcs_log(LOG_INFO, "%s\n", str);
				str_len = 0;
			}
			str_len += sprintf(&str[str_len], "\t");
		}

		str_len += sprintf(&str[str_len], "0x%02x ", data[i]);
	}

	if (str_len != 0)
		kcs_log(LOG_INFO, "%s\n", str);
}

static void kcs_set_timer(struct kcsbridged_context *context, int seconds)
{
	struct itimerspec ts;
	int r;

	ts.it_interval.tv_sec = 0;
	ts.it_interval.tv_nsec = 0;
	ts.it_value.tv_nsec = 0;
	ts.it_value.tv_sec = seconds;

	r = timerfd_settime(context->fds[TIMER_FD].fd, 0, &ts, NULL);
	if (r == -1)
		MSG_ERR("Couldn't set timerfd: %s\n", strerror(errno));
}

static int handle_kcs_request(struct kcsbridged_context *context, uint8_t *msg,
			      size_t msglen)
{
	struct kcs_msg_req *req;

	if (msglen < 2) {
		MSG_ERR("KCS message with a short length (%zd)\n", msglen);
		return -1;
	}

	context->expired = 0;
	context->seqnum++;

	req = &context->req;
	req->netfn = msg[0] >> 2;
	req->lun = msg[0] & 0x3;
	req->cmd = msg[1];
	req->data = msg + 2;
	req->data_len = msglen - 2;

	return 0;
}

static int method_send_message(sd_bus_message *msg, void *userdata,
			       sd_bus_error *err)
{
	struct kcsbridged_context *context = userdata;
	uint8_t netfn, lun, seqnum, cmd, cc;
	struct kcs_msg_req *req;
	uint8_t *data;
	size_t data_sz;
	int r;
	uint8_t rsp[KCS_MESSAGE_SIZE];

	if (!context || context->expired) {
		sd_bus_error_set_const(err, DBUS_ERR, "Internal error");
		r = 0;
		goto out;
	}

	r = sd_bus_message_read(msg, "yyyyy", &seqnum, &netfn, &lun, &cmd, &cc);
	if (r < 0) {
		sd_bus_error_set_const(err, DBUS_ERR, "Bad message");
		r = -EINVAL;
		goto out;
	}

	req = &context->req;
	if (context->seqnum != seqnum || (req->netfn | 1) != netfn
	    || req->lun != lun || req->cmd != cmd) {
		sd_bus_error_set_const(err, DBUS_ERR, "No matching request");
		r = -EINVAL;
		goto out;
	}

	kcs_set_timer(context, 0); /* Stop the timer. */

	r = sd_bus_message_read_array(msg, 'y', (const void **)&data, &data_sz);
	if (r < 0 || data_sz > sizeof(rsp) - 3) {
		sd_bus_error_set_const(err, DBUS_ERR, "Bad message data");
		r = -EINVAL;
		goto out;
	}

	rsp[0] = (netfn << 2) | (lun & 0x3);
	rsp[1] = cmd;
	rsp[2] = cc;
	if (data_sz)
		memcpy(rsp + 3, data, data_sz);

	r = write(context->fds[KCS_FD].fd, rsp, 3 + data_sz);
	if (r > 0)
		r = 0;

	MSG_OUT("Send rsp msg <- seq=0x%02x netfn=0x%02x lun=0x%02x cmd=0x%02x cc=0x%02x\n",
		seqnum, netfn, lun, cmd, cc);

	if (verbosity == KCS_LOG_DEBUG && data_sz != 0)
		kcs_dump_data(data, data_sz);

out:
	return sd_bus_reply_method_return(msg, "x", r);
}

static int method_set_sms_atn(sd_bus_message *msg, void *userdata,
			      sd_bus_error *err)
{
	struct kcsbridged_context *context = userdata;
	int r;

	MSG_OUT("Sending SET_SMS_ATN\n");

	r = ioctl(context->fds[KCS_FD].fd, IPMI_BMC_IOCTL_SET_SMS_ATN);
	if (r == -1) {
		r = errno;
		MSG_ERR("Couldn't SET_SMS_ATN: %s\n", strerror(r));
		return sd_bus_reply_method_errno(msg, errno, err);
	}

	r = 0;
	return sd_bus_reply_method_return(msg, "x", r);
}

static int method_clear_sms_atn(sd_bus_message *msg, void *userdata,
				sd_bus_error *err)
{
	struct kcsbridged_context *context = userdata;
	int r;

	MSG_OUT("Sending CLEAR_SMS_ATN\n");

	r = ioctl(context->fds[KCS_FD].fd, IPMI_BMC_IOCTL_CLEAR_SMS_ATN);
	if (r == -1) {
		r = errno;
		MSG_ERR("Couldn't CLEAR_SMS_ATN: %s\n", strerror(r));
		return sd_bus_reply_method_errno(msg, errno, err);
	}

	r = 0;
	return sd_bus_reply_method_return(msg, "x", r);
}

static int method_force_abort(sd_bus_message *msg, void *userdata,
			      sd_bus_error *err)
{
	struct kcsbridged_context *context = userdata;
	int r;

	MSG_OUT("Sending FORCE_ABORT\n");

	r = ioctl(context->fds[KCS_FD].fd, IPMI_BMC_IOCTL_FORCE_ABORT);
	if (r == -1) {
		r = errno;
		MSG_ERR("Couldn't FORCE_ABORT: %s\n", strerror(r));
		return sd_bus_reply_method_errno(msg, errno, err);
	}

	r = 0;
	return sd_bus_reply_method_return(msg, "x", r);
}

static int dispatch_sd_bus(struct kcsbridged_context *context)
{
	int r = 0;

	if (context->fds[SD_BUS_FD].revents) {
		r = sd_bus_process(context->bus, NULL);
		if (r > 0)
			MSG_OUT("Processed %d dbus events\n", r);
	}

	return r;
}

static int dispatch_timer(struct kcsbridged_context *context)
{
	if (context->fds[TIMER_FD].revents & POLLIN) {
		struct kcs_msg_req *req;
		uint8_t rsp[3];

		MSG_OUT("Timeout on msg with seq: 0x%02x\n", context->seqnum);

		context->expired = 1;

		req = &context->req;
		rsp[0] = ((req->netfn | 1) << 2) | (req->lun & 0x3);
		rsp[1] = req->cmd;
		rsp[2] = 0xce; /* Command response could not be provided */
		if (write(context->fds[KCS_FD].fd, rsp, 3) < 0)
			MSG_ERR("Failed to send the timeout response!\n");
	}

	return 0;
}

static int dispatch_kcs(struct kcsbridged_context *context)
{
	struct kcs_msg_req *req = &context->req;
	sd_bus_message *msg;
	int r = 0, len;
	uint8_t data[KCS_MESSAGE_SIZE];

	if (!(context->fds[KCS_FD].revents & POLLIN))
		goto out;

	len = read(context->fds[KCS_FD].fd, data, sizeof(data));
	if (len < 0 || handle_kcs_request(context, data, len))
		goto out;

	r = sd_bus_message_new_signal(context->bus, &msg, objPath, busName,
				      "ReceivedMessage");
	if (r < 0) {
		MSG_ERR("Failed to create signal: %s\n", strerror(-r));
		goto out;
	}

	r = sd_bus_message_append(msg, "yyyy", context->seqnum, req->netfn,
				  req->lun, req->cmd);
	if (r < 0) {
		MSG_ERR("Couldn't append header to signal: %s\n", strerror(-r));
		goto bail;
	}

	r = sd_bus_message_append_array(msg, 'y', req->data, req->data_len);
	if (r < 0) {
		MSG_ERR("Couldn't append array to signal: %s\n", strerror(-r));
		goto bail;
	}

	r = sd_bus_send(context->bus, msg, NULL);
	if (r < 0) {
		MSG_ERR("Couldn't emit dbus signal: %s\n", strerror(-r));
		goto bail;
	}

	kcs_set_timer(context, KCS_TIMEOUT_IN_SEC);

	MSG_OUT("Recv req msg -> seq=0x%02x netfn=0x%02x lun=0x%02x cmd=0x%02x\n",
		context->seqnum, req->netfn, req->lun, req->cmd);

	if (verbosity == KCS_LOG_DEBUG && req->data_len != 0)
		kcs_dump_data(req->data, req->data_len);

bail:
	sd_bus_message_unref(msg);
out:
	return r;
}

static void usage(const char *name)
{
	fprintf(stderr,
		"Usage %s [--v[v] | --syslog] --i <ID> --d <DEVICE>\n"
		"--v                      Be verbose\n"
		"--vv                     Be verbose and dump entire messages\n"
		"--s, --syslog            Log output to syslog (pointless without --verbose)\n"
		"--i, --instanceid <ID>   instance id (string type)\n"
		"--d, --device <DEVICE>   Use <DEVICE> file.\n\n",
		name);
}

static const sd_bus_vtable ipmid_vtable[] = {
	SD_BUS_VTABLE_START(0),
	SD_BUS_METHOD("sendMessage", "yyyyyay", "x", &method_send_message,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("setAttention", "", "x", &method_set_sms_atn,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("clearAttention", "", "x", &method_clear_sms_atn,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("forceAbort", "", "x", &method_force_abort,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_SIGNAL("ReceivedMessage", "yyyyay", 0),
	SD_BUS_VTABLE_END};

int main(int argc, char *argv[])
{
	struct kcsbridged_context *context;
	const char *name = argv[0];
	bool deviceOptFlag = false, dbusOptFlag = false;
	int opt, polled, r;
	static const struct option long_options[] = {
		{"device", required_argument, 0, 'd'},
		{"instanceid", required_argument, 0, 'i'},
		{"v", no_argument, &verbosity, KCS_LOG_VERBOSE},
		{"vv", no_argument, &verbosity, KCS_LOG_DEBUG},
		{"syslog", no_argument, 0, 's'},
		{0, 0, 0, 0}};

	context = calloc(1, sizeof(*context));
	if (!context) {
		fprintf(stderr, "OOM!\n");
		return -1;
	}

	kcs_vlog = &kcs_log_console;
	while ((opt = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
		switch (opt) {
		case 0:
			break;

		case 'd':
			snprintf(kcsDevice, NAMEBUFFERLEN, "%s", optarg);
			deviceOptFlag = true;
			break;

		case 'i':
			if (sizeof(*optarg) > OPTMAXLEN) {
				fprintf(stderr, "ID is too long!\n");
				exit(EXIT_FAILURE);
			}
			if ((NULL != strstr(optarg, "."))
			    || (NULL != strstr(optarg, "/"))) {
				fprintf(stderr, "invalid ID!\n");
				exit(EXIT_FAILURE);
			}
			snprintf(busName, NAMEBUFFERLEN, "%s%s", DBUS_NAME,
				 optarg);
			snprintf(objPath, NAMEBUFFERLEN, "%s%s", OBJ_NAME,
				 optarg);
			dbusOptFlag = true;
			break;

		case 's':
			if (kcs_vlog != &vsyslog) {
				openlog(LOG_PREFIX, LOG_ODELAY, LOG_DAEMON);
				kcs_vlog = &vsyslog;
			}
			break;

		default:
			usage(name);
			exit(EXIT_FAILURE);
		}
	}

	if ((false == deviceOptFlag) || (false == dbusOptFlag)) {
		usage(name);
		MSG_OUT("Flag: device %d dbus %d \n", deviceOptFlag,
			dbusOptFlag);
		exit(EXIT_FAILURE);
	}

	if (verbosity == KCS_LOG_VERBOSE)
		MSG_OUT("Verbose logging\n");
	else if (verbosity == KCS_LOG_DEBUG)
		MSG_OUT("Debug logging\n");

	MSG_OUT("Starting\n");
	r = sd_bus_default_system(&context->bus);
	if (r < 0) {
		MSG_ERR("Failed to connect to system bus: %s\n", strerror(-r));
		goto finish;
	}

	MSG_OUT("Registering dbus methods/signals\n");
	r = sd_bus_add_object_vtable(context->bus, NULL, objPath, busName,
				     ipmid_vtable, context);
	if (r < 0) {
		MSG_ERR("Failed to issue method call: %s\n", strerror(-r));
		goto finish;
	}

	MSG_OUT("Requesting dbus name: %s objpath:%s \n", busName, objPath);
	r = sd_bus_request_name(context->bus, busName,
				SD_BUS_NAME_ALLOW_REPLACEMENT
					| SD_BUS_NAME_REPLACE_EXISTING);
	if (r < 0) {
		MSG_ERR("Failed to acquire service name: %s\n", strerror(-r));
		goto finish;
	}

	MSG_OUT("Getting dbus file descriptors\n");
	context->fds[SD_BUS_FD].fd = sd_bus_get_fd(context->bus);
	if (context->fds[SD_BUS_FD].fd < 0) {
		r = -errno;
		MSG_OUT("Couldn't get the bus file descriptor: %s\n",
			strerror(errno));
		goto finish;
	}

	MSG_OUT("Opening %s\n", kcsDevice);
	context->fds[KCS_FD].fd = open(kcsDevice, O_RDWR | O_NONBLOCK);
	if (context->fds[KCS_FD].fd < 0) {
		r = -errno;
		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n", kcsDevice,
			strerror(errno));
		goto finish;
	}

	MSG_OUT("Creating timer fd\n");
	context->fds[TIMER_FD].fd = timerfd_create(CLOCK_MONOTONIC, 0);
	if (context->fds[TIMER_FD].fd < 0) {
		r = -errno;
		MSG_ERR("Couldn't create timer fd: %s\n", strerror(errno));
		goto finish;
	}
	context->fds[SD_BUS_FD].events = POLLIN;
	context->fds[KCS_FD].events = POLLIN;
	context->fds[TIMER_FD].events = POLLIN;

	MSG_OUT("Entering polling loop\n");

	while (1) {
		polled = poll(context->fds, TOTAL_FDS, 5000);
		if (polled == 0)
			continue;
		if (polled < 0) {
			r = -errno;
			MSG_ERR("Error from poll(): %s\n", strerror(errno));
			goto finish;
		}

		r = dispatch_sd_bus(context);
		if (r < 0) {
			MSG_ERR("Error handling dbus event: %s\n",
				strerror(-r));
			goto finish;
		}
		r = dispatch_kcs(context);
		if (r < 0) {
			MSG_ERR("Error handling KCS event: %s\n", strerror(-r));
			goto finish;
		}
		r = dispatch_timer(context);
		if (r < 0) {
			MSG_ERR("Error handling timer event: %s\n",
				strerror(-r));
			goto finish;
		}
	}

finish:
	close(context->fds[KCS_FD].fd);
	close(context->fds[TIMER_FD].fd);
	sd_bus_unref(context->bus);
	free(context);

	return r;
}
