/*
 * Wireless / Bluetooth USB class
 *
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/usb/usb_device.h>
#include <usb_descriptor.h>

#include <zephyr/net/buf.h>

#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/hci_raw.h>
#include <zephyr/bluetooth/l2cap.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_bt_h4, CONFIG_USB_DEVICE_LOG_LEVEL);

static K_FIFO_DEFINE(rx_queue);
static K_FIFO_DEFINE(tx_queue);

#define BT_H4_OUT_EP_ADDR               0x01
#define BT_H4_IN_EP_ADDR                0x81

#define BT_H4_OUT_EP_IDX                0
#define BT_H4_IN_EP_IDX                 1

/* HCI RX/TX threads */
static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
static struct k_thread rx_thread_data;
static K_KERNEL_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
static struct k_thread tx_thread_data;

/* HCI USB state flags */
static bool configured;
static bool suspended;

struct usb_bt_h4_config {
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_out_ep;
	struct usb_ep_descriptor if0_in_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_bt_h4_config bt_h4_cfg = {
	/* Interface descriptor 0 */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_DESC_INTERFACE,
		.bInterfaceNumber = 0,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = USB_BCC_VENDOR, /* TBD */
		.bInterfaceSubClass = 0,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},

	/* Data Endpoint OUT */
	.if0_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_DESC_ENDPOINT,
		.bEndpointAddress = BT_H4_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize = sys_cpu_to_le16(USB_MAX_FS_BULK_MPS),
		.bInterval = 0x01,
	},

	/* Data Endpoint IN */
	.if0_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_DESC_ENDPOINT,
		.bEndpointAddress = BT_H4_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize = sys_cpu_to_le16(USB_MAX_FS_BULK_MPS),
		.bInterval = 0x01,
	},
};

static struct usb_ep_cfg_data bt_h4_ep_data[] = {
	{
		.ep_cb = usb_transfer_ep_callback,
		.ep_addr = BT_H4_OUT_EP_ADDR,
	},
	{
		.ep_cb = usb_transfer_ep_callback,
		.ep_addr = BT_H4_IN_EP_ADDR,
	},
};

static void bt_h4_read(uint8_t ep, int size, void *priv)
{
	static uint8_t data[USB_MAX_FS_BULK_MPS];

	if (size > 0) {
		struct net_buf *buf;

		buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, data, size);
		if (!buf) {
			LOG_ERR("Cannot get free TX buffer\n");
			return;
		}

		net_buf_put(&rx_queue, buf);
	}

	/* Start a new read transfer */
	usb_transfer(bt_h4_ep_data[BT_H4_OUT_EP_IDX].ep_addr, data,
		     USB_MAX_FS_BULK_MPS, USB_TRANS_READ, bt_h4_read, NULL);
}

static void hci_tx_thread(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	LOG_DBG("Start USB Bluetooth thread");

	while (true) {
		struct net_buf *buf;

		buf = net_buf_get(&tx_queue, K_FOREVER);

		usb_transfer_sync(bt_h4_ep_data[BT_H4_IN_EP_IDX].ep_addr,
				  buf->data, buf->len, USB_TRANS_WRITE);

		net_buf_unref(buf);
	}
}

static void hci_rx_thread(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	while (true) {
		struct net_buf *buf;

		buf = net_buf_get(&rx_queue, K_FOREVER);
		if (bt_send(buf)) {
			LOG_ERR("Error sending to driver");
			net_buf_unref(buf);
		}
	}
}

static void bt_h4_status_cb(struct usb_cfg_data *cfg,
			    enum usb_dc_status_code status, const uint8_t *param)
{
	ARG_UNUSED(cfg);

	/* Check the USB status and do needed action if required */
	switch (status) {
	case USB_DC_RESET:
		LOG_DBG("Device reset detected");
		suspended = false;
		configured = false;
		break;
	case USB_DC_CONFIGURED:
		LOG_DBG("Device configured");
		if (!configured) {
			configured = true;
			/* Start reading */
			bt_h4_read(bt_h4_ep_data[BT_H4_OUT_EP_IDX].ep_addr,
				   0, NULL);
		}
		break;
	case USB_DC_DISCONNECTED:
		LOG_DBG("Device disconnected");
		/* Cancel any transfer */
		usb_cancel_transfer(bt_h4_ep_data[BT_H4_IN_EP_IDX].ep_addr);
		usb_cancel_transfer(bt_h4_ep_data[BT_H4_OUT_EP_IDX].ep_addr);
		suspended = false;
		configured = false;
		break;
	case USB_DC_SUSPEND:
		suspended = true;
		break;
	case USB_DC_RESUME:
		LOG_DBG("Device resumed");
		if (suspended) {
			LOG_DBG("from suspend");
			suspended = false;
		} else {
			LOG_DBG("Spurious resume event");
		}
		break;
	case USB_DC_UNKNOWN:
	default:
		LOG_DBG("Unhandled status: %u", status);
		break;
	}
}

static int bt_h4_vendor_handler(struct usb_setup_packet *setup,
				int32_t *len, uint8_t **data)
{
	LOG_DBG("Class request: bRequest 0x%x bmRequestType 0x%x len %d",
		setup->bRequest, setup->bmRequestType, *len);

	return -ENOTSUP;
}

static void bt_h4_interface_config(struct usb_desc_header *head,
				   uint8_t bInterfaceNumber)
{
	ARG_UNUSED(head);

	bt_h4_cfg.if0.bInterfaceNumber = bInterfaceNumber;
}

USBD_DEFINE_CFG_DATA(bt_h4_config) = {
	.usb_device_description = NULL,
	.interface_config = bt_h4_interface_config,
	.interface_descriptor = &bt_h4_cfg.if0,
	.cb_usb_status = bt_h4_status_cb,
	.interface = {
		.class_handler = NULL,
		.custom_handler = NULL,
		.vendor_handler = bt_h4_vendor_handler,
	},
	.num_endpoints = ARRAY_SIZE(bt_h4_ep_data),
	.endpoint = bt_h4_ep_data,
};

static int bt_h4_init(void)
{
	int ret;

	LOG_DBG("Initialization");

	ret = bt_enable_raw(&tx_queue);
	if (ret) {
		LOG_ERR("Failed to open Bluetooth raw channel: %d", ret);
		return ret;
	}

	k_thread_create(&rx_thread_data, rx_thread_stack,
			K_KERNEL_STACK_SIZEOF(rx_thread_stack),
			hci_rx_thread, NULL, NULL, NULL,
			K_PRIO_COOP(8), 0, K_NO_WAIT);

	k_thread_name_set(&rx_thread_data, "usb_bt_h4_rx");

	k_thread_create(&tx_thread_data, tx_thread_stack,
			K_KERNEL_STACK_SIZEOF(tx_thread_stack),
			hci_tx_thread, NULL, NULL, NULL,
			K_PRIO_COOP(8), 0, K_NO_WAIT);

	k_thread_name_set(&tx_thread_data, "usb_bt_h4_tx");

	return 0;
}

SYS_INIT(bt_h4_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
