/* bttester.c - Bluetooth Tester */

/*
 * Copyright (c) 2015-2016 Intel Corporation
 * Copyright (c) 2022 Codecoup
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/toolchain.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/uart_pipe.h>

#include <zephyr/logging/log.h>
#define LOG_MODULE_NAME bttester
LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);

#include "btp/btp.h"

#define STACKSIZE 2048
static K_THREAD_STACK_DEFINE(stack, STACKSIZE);
static struct k_thread cmd_thread;

#define CMD_QUEUED 2
struct btp_buf {
	intptr_t _reserved;
	union {
		uint8_t data[BTP_MTU];
		struct btp_hdr hdr;
	};
	uint8_t rsp[BTP_MTU];
};

static struct btp_buf cmd_buf[CMD_QUEUED];

static K_FIFO_DEFINE(cmds_queue);
static K_FIFO_DEFINE(avail_queue);

static struct btp_buf *delayed_cmd;

static struct {
	const struct btp_handler *handlers;
	size_t num;
} service_handler[BTP_SERVICE_ID_MAX + 1];

static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index,
				   const uint8_t *data, size_t len);
static void tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index,
				  uint8_t status);

void tester_register_command_handlers(uint8_t service,
				      const struct btp_handler *handlers,
				      size_t num)
{
	__ASSERT_NO_MSG(service <= BTP_SERVICE_ID_MAX);
	__ASSERT_NO_MSG(service_handler[service].handlers == NULL);

	service_handler[service].handlers = handlers;
	service_handler[service].num = num;
}

static const struct btp_handler *find_btp_handler(uint8_t service, uint8_t opcode)
{
	if ((service > BTP_SERVICE_ID_MAX) ||
	    (service_handler[service].handlers == NULL)) {
		return NULL;
	}

	for (uint8_t i = 0; i < service_handler[service].num; i++) {
		if (service_handler[service].handlers[i].opcode == opcode) {
			return &service_handler[service].handlers[i];
		}
	}

	return NULL;
}

static void cmd_handler(void *p1, void *p2, void *p3)
{
	while (1) {
		const struct btp_handler *btp;
		struct btp_buf *cmd;
		uint8_t status;
		uint16_t rsp_len = 0;
		uint16_t len;

		cmd = k_fifo_get(&cmds_queue, K_FOREVER);

		len = sys_le16_to_cpu(cmd->hdr.len);

		btp = find_btp_handler(cmd->hdr.service, cmd->hdr.opcode);
		if (btp) {
			if (btp->index != cmd->hdr.index) {
				status = BTP_STATUS_FAILED;
			} else if ((btp->expect_len >= 0) && (btp->expect_len != len)) {
				status = BTP_STATUS_FAILED;
			} else {
				status = btp->func(cmd->hdr.data, len,
						   cmd->rsp, &rsp_len);
			}

			__ASSERT_NO_MSG((rsp_len + sizeof(struct btp_hdr)) <= BTP_MTU);
		} else {
			status = BTP_STATUS_UNKNOWN_CMD;
		}
		/* Allow to delay only 1 command. This is for convenience only
		 * of using cmd data without need of copying those in async
		 * functions. Should be not needed eventually.
		 */
		if (status == BTP_STATUS_DELAY_REPLY) {
			__ASSERT_NO_MSG(delayed_cmd == NULL);
			delayed_cmd = cmd;
			continue;
		}

		if ((status == BTP_STATUS_SUCCESS) && rsp_len > 0) {
			tester_send_with_index(cmd->hdr.service, cmd->hdr.opcode,
					       cmd->hdr.index, cmd->rsp, rsp_len);
		} else {
			tester_rsp_with_index(cmd->hdr.service, cmd->hdr.opcode,
					      cmd->hdr.index, status);
		}

		(void)memset(cmd, 0, sizeof(*cmd));
		k_fifo_put(&avail_queue, cmd);
	}
}

static uint8_t *recv_cb(uint8_t *buf, size_t *off)
{
	struct btp_hdr *cmd = (void *) buf;
	struct btp_buf *new_buf;
	uint16_t len;

	if (*off < sizeof(*cmd)) {
		return buf;
	}

	len = sys_le16_to_cpu(cmd->len);
	if (len > BTP_MTU - sizeof(*cmd)) {
		LOG_ERR("BT tester: invalid packet length");
		*off = 0;
		return buf;
	}

	if (*off < sizeof(*cmd) + len) {
		return buf;
	}

	new_buf =  k_fifo_get(&avail_queue, K_NO_WAIT);
	if (!new_buf) {
		LOG_ERR("BT tester: RX overflow");
		*off = 0;
		return buf;
	}

	k_fifo_put(&cmds_queue, CONTAINER_OF(buf, struct btp_buf, data));

	*off = 0;
	return new_buf->data;
}

#if defined(CONFIG_UART_PIPE)
/* Uart Pipe */
static void uart_init(uint8_t *data)
{
	uart_pipe_register(data, BTP_MTU, recv_cb);
}

static void uart_send(const uint8_t *data, size_t len)
{
	uart_pipe_send(data, len);
}
#else /* !CONFIG_UART_PIPE */
static uint8_t *recv_buf;
static size_t recv_off;
static const struct device *const dev =
	DEVICE_DT_GET(DT_CHOSEN(zephyr_console));

static void timer_expiry_cb(struct k_timer *timer)
{
	uint8_t c;

	while (uart_poll_in(dev, &c) == 0) {
		recv_buf[recv_off++] = c;
		recv_buf = recv_cb(recv_buf, &recv_off);
	}
}

K_TIMER_DEFINE(timer, timer_expiry_cb, NULL);

/* Uart Poll */
static void uart_init(uint8_t *data)
{
	__ASSERT_NO_MSG(device_is_ready(dev));

	recv_buf = data;

	k_timer_start(&timer, K_MSEC(10), K_MSEC(10));
}

static void uart_send(const uint8_t *data, size_t len)
{
	int i;

	for (i = 0; i < len; i++) {
		uart_poll_out(dev, data[i]);
	}
}
#endif /* CONFIG_UART_PIPE */

void tester_init(void)
{
	int i;
	struct btp_buf *buf;

	LOG_DBG("Initializing tester");

	for (i = 0; i < CMD_QUEUED; i++) {
		k_fifo_put(&avail_queue, &cmd_buf[i]);
	}

	k_thread_create(&cmd_thread, stack, STACKSIZE, cmd_handler,
			NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);

	buf = k_fifo_get(&avail_queue, K_NO_WAIT);

	uart_init(buf->data);

	/* core service is always available */
	tester_init_core();

	tester_send_with_index(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY,
			      BTP_INDEX_NONE, NULL, 0);
}

static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index,
				   const uint8_t *data, size_t len)
{
	struct btp_hdr msg;

	msg.service = service;
	msg.opcode = opcode;
	msg.index = index;
	msg.len = sys_cpu_to_le16(len);

	uart_send((uint8_t *)&msg, sizeof(msg));
	if (data && len) {
		uart_send(data, len);
	}
}

static void tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index,
				  uint8_t status)
{
	struct btp_status s;

	if (status == BTP_STATUS_SUCCESS) {
		tester_send_with_index(service, opcode, index, NULL, 0);
		return;
	}

	s.code = status;
	tester_send_with_index(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s));
}

void tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len)
{
	__ASSERT_NO_MSG(opcode >= 0x80);
	tester_send_with_index(service, opcode, BTP_INDEX, data, len);
}

void tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len)
{
	struct btp_buf *cmd;

	__ASSERT_NO_MSG(opcode < 0x80);
	__ASSERT_NO_MSG(delayed_cmd != NULL);

	tester_send_with_index(service, opcode, BTP_INDEX, rsp, len);

	cmd = delayed_cmd;
	delayed_cmd = NULL;

	(void)memset(cmd, 0, sizeof(*cmd));
	k_fifo_put(&avail_queue, cmd);
}

void tester_rsp(uint8_t service, uint8_t opcode, uint8_t status)
{
	struct btp_buf *cmd;

	__ASSERT_NO_MSG(opcode < 0x80);
	__ASSERT_NO_MSG(delayed_cmd != NULL);

	tester_rsp_with_index(service, opcode, BTP_INDEX, status);

	cmd = delayed_cmd;
	delayed_cmd = NULL;

	(void)memset(cmd, 0, sizeof(*cmd));
	k_fifo_put(&avail_queue, cmd);
}
