// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 *  Bluetooth virtual HCI driver
 *
 *  Copyright (C) 2000-2001  Qualcomm Incorporated
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
 */

#include <linux/module.h>
#include <asm/unaligned.h>

#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/poll.h>

#include <linux/skbuff.h>
#include <linux/miscdevice.h>
#include <linux/debugfs.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#define VERSION "1.5"

static bool amp;

struct vhci_data {
	struct hci_dev *hdev;

	wait_queue_head_t read_wait;
	struct sk_buff_head readq;

	struct mutex open_mutex;
	struct delayed_work open_timeout;
	struct work_struct suspend_work;

	bool suspended;
	bool wakeup;
	__u16 msft_opcode;
	bool aosp_capable;
	atomic_t initialized;
};

static int vhci_open_dev(struct hci_dev *hdev)
{
	return 0;
}

static int vhci_close_dev(struct hci_dev *hdev)
{
	struct vhci_data *data = hci_get_drvdata(hdev);

	skb_queue_purge(&data->readq);

	return 0;
}

static int vhci_flush(struct hci_dev *hdev)
{
	struct vhci_data *data = hci_get_drvdata(hdev);

	skb_queue_purge(&data->readq);

	return 0;
}

static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct vhci_data *data = hci_get_drvdata(hdev);

	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);

	skb_queue_tail(&data->readq, skb);

	if (atomic_read(&data->initialized))
		wake_up_interruptible(&data->read_wait);
	return 0;
}

static int vhci_get_data_path_id(struct hci_dev *hdev, u8 *data_path_id)
{
	*data_path_id = 0;
	return 0;
}

static int vhci_get_codec_config_data(struct hci_dev *hdev, __u8 type,
				      struct bt_codec *codec, __u8 *vnd_len,
				      __u8 **vnd_data)
{
	if (type != ESCO_LINK)
		return -EINVAL;

	*vnd_len = 0;
	*vnd_data = NULL;
	return 0;
}

static bool vhci_wakeup(struct hci_dev *hdev)
{
	struct vhci_data *data = hci_get_drvdata(hdev);

	return data->wakeup;
}

static ssize_t force_suspend_read(struct file *file, char __user *user_buf,
				  size_t count, loff_t *ppos)
{
	struct vhci_data *data = file->private_data;
	char buf[3];

	buf[0] = data->suspended ? 'Y' : 'N';
	buf[1] = '\n';
	buf[2] = '\0';
	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}

static void vhci_suspend_work(struct work_struct *work)
{
	struct vhci_data *data = container_of(work, struct vhci_data,
					      suspend_work);

	if (data->suspended)
		hci_suspend_dev(data->hdev);
	else
		hci_resume_dev(data->hdev);
}

static ssize_t force_suspend_write(struct file *file,
				   const char __user *user_buf,
				   size_t count, loff_t *ppos)
{
	struct vhci_data *data = file->private_data;
	bool enable;
	int err;

	err = kstrtobool_from_user(user_buf, count, &enable);
	if (err)
		return err;

	if (data->suspended == enable)
		return -EALREADY;

	data->suspended = enable;

	schedule_work(&data->suspend_work);

	return count;
}

static const struct file_operations force_suspend_fops = {
	.open		= simple_open,
	.read		= force_suspend_read,
	.write		= force_suspend_write,
	.llseek		= default_llseek,
};

static ssize_t force_wakeup_read(struct file *file, char __user *user_buf,
				 size_t count, loff_t *ppos)
{
	struct vhci_data *data = file->private_data;
	char buf[3];

	buf[0] = data->wakeup ? 'Y' : 'N';
	buf[1] = '\n';
	buf[2] = '\0';
	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}

static ssize_t force_wakeup_write(struct file *file,
				  const char __user *user_buf, size_t count,
				  loff_t *ppos)
{
	struct vhci_data *data = file->private_data;
	bool enable;
	int err;

	err = kstrtobool_from_user(user_buf, count, &enable);
	if (err)
		return err;

	if (data->wakeup == enable)
		return -EALREADY;

	data->wakeup = enable;

	return count;
}

static const struct file_operations force_wakeup_fops = {
	.open		= simple_open,
	.read		= force_wakeup_read,
	.write		= force_wakeup_write,
	.llseek		= default_llseek,
};

static int msft_opcode_set(void *data, u64 val)
{
	struct vhci_data *vhci = data;

	if (val > 0xffff || hci_opcode_ogf(val) != 0x3f)
		return -EINVAL;

	if (vhci->msft_opcode)
		return -EALREADY;

	vhci->msft_opcode = val;

	return 0;
}

static int msft_opcode_get(void *data, u64 *val)
{
	struct vhci_data *vhci = data;

	*val = vhci->msft_opcode;

	return 0;
}

DEFINE_DEBUGFS_ATTRIBUTE(msft_opcode_fops, msft_opcode_get, msft_opcode_set,
			 "%llu\n");

static ssize_t aosp_capable_read(struct file *file, char __user *user_buf,
				 size_t count, loff_t *ppos)
{
	struct vhci_data *vhci = file->private_data;
	char buf[3];

	buf[0] = vhci->aosp_capable ? 'Y' : 'N';
	buf[1] = '\n';
	buf[2] = '\0';
	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}

static ssize_t aosp_capable_write(struct file *file,
				  const char __user *user_buf, size_t count,
				  loff_t *ppos)
{
	struct vhci_data *vhci = file->private_data;
	bool enable;
	int err;

	err = kstrtobool_from_user(user_buf, count, &enable);
	if (err)
		return err;

	if (!enable)
		return -EINVAL;

	if (vhci->aosp_capable)
		return -EALREADY;

	vhci->aosp_capable = enable;

	return count;
}

static const struct file_operations aosp_capable_fops = {
	.open		= simple_open,
	.read		= aosp_capable_read,
	.write		= aosp_capable_write,
	.llseek		= default_llseek,
};

static int vhci_setup(struct hci_dev *hdev)
{
	struct vhci_data *vhci = hci_get_drvdata(hdev);

	if (vhci->msft_opcode)
		hci_set_msft_opcode(hdev, vhci->msft_opcode);

	if (vhci->aosp_capable)
		hci_set_aosp_capable(hdev);

	return 0;
}

static void vhci_coredump(struct hci_dev *hdev)
{
	/* No need to do anything */
}

static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
{
	char buf[80];

	snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n");
	skb_put_data(skb, buf, strlen(buf));

	snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n");
	skb_put_data(skb, buf, strlen(buf));

	snprintf(buf, sizeof(buf), "Driver: vhci_drv\n");
	skb_put_data(skb, buf, strlen(buf));

	snprintf(buf, sizeof(buf), "Vendor: vhci\n");
	skb_put_data(skb, buf, strlen(buf));
}

#define MAX_COREDUMP_LINE_LEN	40

struct devcoredump_test_data {
	enum devcoredump_state state;
	unsigned int timeout;
	char data[MAX_COREDUMP_LINE_LEN];
};

static inline void force_devcd_timeout(struct hci_dev *hdev,
				       unsigned int timeout)
{
#ifdef CONFIG_DEV_COREDUMP
	hdev->dump.timeout = msecs_to_jiffies(timeout * 1000);
#endif
}

static ssize_t force_devcd_write(struct file *file, const char __user *user_buf,
				 size_t count, loff_t *ppos)
{
	struct vhci_data *data = file->private_data;
	struct hci_dev *hdev = data->hdev;
	struct sk_buff *skb = NULL;
	struct devcoredump_test_data dump_data;
	size_t data_size;
	int ret;

	if (count < offsetof(struct devcoredump_test_data, data) ||
	    count > sizeof(dump_data))
		return -EINVAL;

	if (copy_from_user(&dump_data, user_buf, count))
		return -EFAULT;

	data_size = count - offsetof(struct devcoredump_test_data, data);
	skb = alloc_skb(data_size, GFP_ATOMIC);
	if (!skb)
		return -ENOMEM;
	skb_put_data(skb, &dump_data.data, data_size);

	hci_devcd_register(hdev, vhci_coredump, vhci_coredump_hdr, NULL);

	/* Force the devcoredump timeout */
	if (dump_data.timeout)
		force_devcd_timeout(hdev, dump_data.timeout);

	ret = hci_devcd_init(hdev, skb->len);
	if (ret) {
		BT_ERR("Failed to generate devcoredump");
		kfree_skb(skb);
		return ret;
	}

	hci_devcd_append(hdev, skb);

	switch (dump_data.state) {
	case HCI_DEVCOREDUMP_DONE:
		hci_devcd_complete(hdev);
		break;
	case HCI_DEVCOREDUMP_ABORT:
		hci_devcd_abort(hdev);
		break;
	case HCI_DEVCOREDUMP_TIMEOUT:
		/* Do nothing */
		break;
	default:
		return -EINVAL;
	}

	return count;
}

static const struct file_operations force_devcoredump_fops = {
	.open		= simple_open,
	.write		= force_devcd_write,
};

static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
{
	struct hci_dev *hdev;
	struct sk_buff *skb;

	if (data->hdev)
		return -EBADFD;

	/* bits 2-5 are reserved (must be zero) */
	if (opcode & 0x3c)
		return -EINVAL;

	skb = bt_skb_alloc(4, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	hdev = hci_alloc_dev();
	if (!hdev) {
		kfree_skb(skb);
		return -ENOMEM;
	}

	data->hdev = hdev;

	hdev->bus = HCI_VIRTUAL;
	hci_set_drvdata(hdev, data);

	hdev->open  = vhci_open_dev;
	hdev->close = vhci_close_dev;
	hdev->flush = vhci_flush;
	hdev->send  = vhci_send_frame;
	hdev->get_data_path_id = vhci_get_data_path_id;
	hdev->get_codec_config_data = vhci_get_codec_config_data;
	hdev->wakeup = vhci_wakeup;
	hdev->setup = vhci_setup;
	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);

	/* bit 6 is for external configuration */
	if (opcode & 0x40)
		set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);

	/* bit 7 is for raw device */
	if (opcode & 0x80)
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

	set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		data->hdev = NULL;
		kfree_skb(skb);
		return -EBUSY;
	}

	debugfs_create_file("force_suspend", 0644, hdev->debugfs, data,
			    &force_suspend_fops);

	debugfs_create_file("force_wakeup", 0644, hdev->debugfs, data,
			    &force_wakeup_fops);

	if (IS_ENABLED(CONFIG_BT_MSFTEXT))
		debugfs_create_file("msft_opcode", 0644, hdev->debugfs, data,
				    &msft_opcode_fops);

	if (IS_ENABLED(CONFIG_BT_AOSPEXT))
		debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data,
				    &aosp_capable_fops);

	debugfs_create_file("force_devcoredump", 0644, hdev->debugfs, data,
			    &force_devcoredump_fops);

	hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;

	skb_put_u8(skb, 0xff);
	skb_put_u8(skb, opcode);
	put_unaligned_le16(hdev->id, skb_put(skb, 2));
	skb_queue_head(&data->readq, skb);
	atomic_inc(&data->initialized);

	wake_up_interruptible(&data->read_wait);
	return 0;
}

static int vhci_create_device(struct vhci_data *data, __u8 opcode)
{
	int err;

	mutex_lock(&data->open_mutex);
	err = __vhci_create_device(data, opcode);
	mutex_unlock(&data->open_mutex);

	return err;
}

static inline ssize_t vhci_get_user(struct vhci_data *data,
				    struct iov_iter *from)
{
	size_t len = iov_iter_count(from);
	struct sk_buff *skb;
	__u8 pkt_type, opcode;
	int ret;

	if (len < 2 || len > HCI_MAX_FRAME_SIZE)
		return -EINVAL;

	skb = bt_skb_alloc(len, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	if (!copy_from_iter_full(skb_put(skb, len), len, from)) {
		kfree_skb(skb);
		return -EFAULT;
	}

	pkt_type = *((__u8 *) skb->data);
	skb_pull(skb, 1);

	switch (pkt_type) {
	case HCI_EVENT_PKT:
	case HCI_ACLDATA_PKT:
	case HCI_SCODATA_PKT:
	case HCI_ISODATA_PKT:
		if (!data->hdev) {
			kfree_skb(skb);
			return -ENODEV;
		}

		hci_skb_pkt_type(skb) = pkt_type;

		ret = hci_recv_frame(data->hdev, skb);
		break;

	case HCI_VENDOR_PKT:
		cancel_delayed_work_sync(&data->open_timeout);

		opcode = *((__u8 *) skb->data);
		skb_pull(skb, 1);

		if (skb->len > 0) {
			kfree_skb(skb);
			return -EINVAL;
		}

		kfree_skb(skb);

		ret = vhci_create_device(data, opcode);
		break;

	default:
		kfree_skb(skb);
		return -EINVAL;
	}

	return (ret < 0) ? ret : len;
}

static inline ssize_t vhci_put_user(struct vhci_data *data,
				    struct sk_buff *skb,
				    char __user *buf, int count)
{
	char __user *ptr = buf;
	int len;

	len = min_t(unsigned int, skb->len, count);

	if (copy_to_user(ptr, skb->data, len))
		return -EFAULT;

	if (!data->hdev)
		return len;

	data->hdev->stat.byte_tx += len;

	switch (hci_skb_pkt_type(skb)) {
	case HCI_COMMAND_PKT:
		data->hdev->stat.cmd_tx++;
		break;
	case HCI_ACLDATA_PKT:
		data->hdev->stat.acl_tx++;
		break;
	case HCI_SCODATA_PKT:
		data->hdev->stat.sco_tx++;
		break;
	}

	return len;
}

static ssize_t vhci_read(struct file *file,
			 char __user *buf, size_t count, loff_t *pos)
{
	struct vhci_data *data = file->private_data;
	struct sk_buff *skb;
	ssize_t ret = 0;

	while (count) {
		skb = skb_dequeue(&data->readq);
		if (skb) {
			ret = vhci_put_user(data, skb, buf, count);
			if (ret < 0)
				skb_queue_head(&data->readq, skb);
			else
				kfree_skb(skb);
			break;
		}

		if (file->f_flags & O_NONBLOCK) {
			ret = -EAGAIN;
			break;
		}

		ret = wait_event_interruptible(data->read_wait,
					       !skb_queue_empty(&data->readq));
		if (ret < 0)
			break;
	}

	return ret;
}

static ssize_t vhci_write(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	struct vhci_data *data = file->private_data;

	return vhci_get_user(data, from);
}

static __poll_t vhci_poll(struct file *file, poll_table *wait)
{
	struct vhci_data *data = file->private_data;

	poll_wait(file, &data->read_wait, wait);

	if (!skb_queue_empty(&data->readq))
		return EPOLLIN | EPOLLRDNORM;

	return EPOLLOUT | EPOLLWRNORM;
}

static void vhci_open_timeout(struct work_struct *work)
{
	struct vhci_data *data = container_of(work, struct vhci_data,
					      open_timeout.work);

	vhci_create_device(data, 0x00);
}

static int vhci_open(struct inode *inode, struct file *file)
{
	struct vhci_data *data;

	data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	skb_queue_head_init(&data->readq);
	init_waitqueue_head(&data->read_wait);

	mutex_init(&data->open_mutex);
	INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
	INIT_WORK(&data->suspend_work, vhci_suspend_work);

	file->private_data = data;
	nonseekable_open(inode, file);

	schedule_delayed_work(&data->open_timeout, msecs_to_jiffies(1000));

	return 0;
}

static int vhci_release(struct inode *inode, struct file *file)
{
	struct vhci_data *data = file->private_data;
	struct hci_dev *hdev;

	cancel_delayed_work_sync(&data->open_timeout);
	flush_work(&data->suspend_work);

	hdev = data->hdev;

	if (hdev) {
		hci_unregister_dev(hdev);
		hci_free_dev(hdev);
	}

	skb_queue_purge(&data->readq);
	file->private_data = NULL;
	kfree(data);

	return 0;
}

static const struct file_operations vhci_fops = {
	.owner		= THIS_MODULE,
	.read		= vhci_read,
	.write_iter	= vhci_write,
	.poll		= vhci_poll,
	.open		= vhci_open,
	.release	= vhci_release,
	.llseek		= no_llseek,
};

static struct miscdevice vhci_miscdev = {
	.name	= "vhci",
	.fops	= &vhci_fops,
	.minor	= VHCI_MINOR,
};
module_misc_device(vhci_miscdev);

module_param(amp, bool, 0644);
MODULE_PARM_DESC(amp, "Create AMP controller device");

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS("devname:vhci");
MODULE_ALIAS_MISCDEV(VHCI_MINOR);
