linux/drivers/bluetooth/hci_vhci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *
   4 *  Bluetooth virtual HCI driver
   5 *
   6 *  Copyright (C) 2000-2001  Qualcomm Incorporated
   7 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
   8 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
   9 */
  10
  11#include <linux/module.h>
  12#include <asm/unaligned.h>
  13
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/slab.h>
  17#include <linux/types.h>
  18#include <linux/errno.h>
  19#include <linux/sched.h>
  20#include <linux/poll.h>
  21
  22#include <linux/skbuff.h>
  23#include <linux/miscdevice.h>
  24
  25#include <net/bluetooth/bluetooth.h>
  26#include <net/bluetooth/hci_core.h>
  27
  28#define VERSION "1.5"
  29
  30static bool amp;
  31
  32struct vhci_data {
  33        struct hci_dev *hdev;
  34
  35        wait_queue_head_t read_wait;
  36        struct sk_buff_head readq;
  37
  38        struct mutex open_mutex;
  39        struct delayed_work open_timeout;
  40};
  41
  42static int vhci_open_dev(struct hci_dev *hdev)
  43{
  44        return 0;
  45}
  46
  47static int vhci_close_dev(struct hci_dev *hdev)
  48{
  49        struct vhci_data *data = hci_get_drvdata(hdev);
  50
  51        skb_queue_purge(&data->readq);
  52
  53        return 0;
  54}
  55
  56static int vhci_flush(struct hci_dev *hdev)
  57{
  58        struct vhci_data *data = hci_get_drvdata(hdev);
  59
  60        skb_queue_purge(&data->readq);
  61
  62        return 0;
  63}
  64
  65static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
  66{
  67        struct vhci_data *data = hci_get_drvdata(hdev);
  68
  69        memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
  70        skb_queue_tail(&data->readq, skb);
  71
  72        wake_up_interruptible(&data->read_wait);
  73        return 0;
  74}
  75
  76static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
  77{
  78        struct hci_dev *hdev;
  79        struct sk_buff *skb;
  80        __u8 dev_type;
  81
  82        if (data->hdev)
  83                return -EBADFD;
  84
  85        /* bits 0-1 are dev_type (Primary or AMP) */
  86        dev_type = opcode & 0x03;
  87
  88        if (dev_type != HCI_PRIMARY && dev_type != HCI_AMP)
  89                return -EINVAL;
  90
  91        /* bits 2-5 are reserved (must be zero) */
  92        if (opcode & 0x3c)
  93                return -EINVAL;
  94
  95        skb = bt_skb_alloc(4, GFP_KERNEL);
  96        if (!skb)
  97                return -ENOMEM;
  98
  99        hdev = hci_alloc_dev();
 100        if (!hdev) {
 101                kfree_skb(skb);
 102                return -ENOMEM;
 103        }
 104
 105        data->hdev = hdev;
 106
 107        hdev->bus = HCI_VIRTUAL;
 108        hdev->dev_type = dev_type;
 109        hci_set_drvdata(hdev, data);
 110
 111        hdev->open  = vhci_open_dev;
 112        hdev->close = vhci_close_dev;
 113        hdev->flush = vhci_flush;
 114        hdev->send  = vhci_send_frame;
 115
 116        /* bit 6 is for external configuration */
 117        if (opcode & 0x40)
 118                set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
 119
 120        /* bit 7 is for raw device */
 121        if (opcode & 0x80)
 122                set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 123
 124        if (hci_register_dev(hdev) < 0) {
 125                BT_ERR("Can't register HCI device");
 126                hci_free_dev(hdev);
 127                data->hdev = NULL;
 128                kfree_skb(skb);
 129                return -EBUSY;
 130        }
 131
 132        hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
 133
 134        skb_put_u8(skb, 0xff);
 135        skb_put_u8(skb, opcode);
 136        put_unaligned_le16(hdev->id, skb_put(skb, 2));
 137        skb_queue_tail(&data->readq, skb);
 138
 139        wake_up_interruptible(&data->read_wait);
 140        return 0;
 141}
 142
 143static int vhci_create_device(struct vhci_data *data, __u8 opcode)
 144{
 145        int err;
 146
 147        mutex_lock(&data->open_mutex);
 148        err = __vhci_create_device(data, opcode);
 149        mutex_unlock(&data->open_mutex);
 150
 151        return err;
 152}
 153
 154static inline ssize_t vhci_get_user(struct vhci_data *data,
 155                                    struct iov_iter *from)
 156{
 157        size_t len = iov_iter_count(from);
 158        struct sk_buff *skb;
 159        __u8 pkt_type, opcode;
 160        int ret;
 161
 162        if (len < 2 || len > HCI_MAX_FRAME_SIZE)
 163                return -EINVAL;
 164
 165        skb = bt_skb_alloc(len, GFP_KERNEL);
 166        if (!skb)
 167                return -ENOMEM;
 168
 169        if (!copy_from_iter_full(skb_put(skb, len), len, from)) {
 170                kfree_skb(skb);
 171                return -EFAULT;
 172        }
 173
 174        pkt_type = *((__u8 *) skb->data);
 175        skb_pull(skb, 1);
 176
 177        switch (pkt_type) {
 178        case HCI_EVENT_PKT:
 179        case HCI_ACLDATA_PKT:
 180        case HCI_SCODATA_PKT:
 181                if (!data->hdev) {
 182                        kfree_skb(skb);
 183                        return -ENODEV;
 184                }
 185
 186                hci_skb_pkt_type(skb) = pkt_type;
 187
 188                ret = hci_recv_frame(data->hdev, skb);
 189                break;
 190
 191        case HCI_VENDOR_PKT:
 192                cancel_delayed_work_sync(&data->open_timeout);
 193
 194                opcode = *((__u8 *) skb->data);
 195                skb_pull(skb, 1);
 196
 197                if (skb->len > 0) {
 198                        kfree_skb(skb);
 199                        return -EINVAL;
 200                }
 201
 202                kfree_skb(skb);
 203
 204                ret = vhci_create_device(data, opcode);
 205                break;
 206
 207        default:
 208                kfree_skb(skb);
 209                return -EINVAL;
 210        }
 211
 212        return (ret < 0) ? ret : len;
 213}
 214
 215static inline ssize_t vhci_put_user(struct vhci_data *data,
 216                                    struct sk_buff *skb,
 217                                    char __user *buf, int count)
 218{
 219        char __user *ptr = buf;
 220        int len;
 221
 222        len = min_t(unsigned int, skb->len, count);
 223
 224        if (copy_to_user(ptr, skb->data, len))
 225                return -EFAULT;
 226
 227        if (!data->hdev)
 228                return len;
 229
 230        data->hdev->stat.byte_tx += len;
 231
 232        switch (hci_skb_pkt_type(skb)) {
 233        case HCI_COMMAND_PKT:
 234                data->hdev->stat.cmd_tx++;
 235                break;
 236        case HCI_ACLDATA_PKT:
 237                data->hdev->stat.acl_tx++;
 238                break;
 239        case HCI_SCODATA_PKT:
 240                data->hdev->stat.sco_tx++;
 241                break;
 242        }
 243
 244        return len;
 245}
 246
 247static ssize_t vhci_read(struct file *file,
 248                         char __user *buf, size_t count, loff_t *pos)
 249{
 250        struct vhci_data *data = file->private_data;
 251        struct sk_buff *skb;
 252        ssize_t ret = 0;
 253
 254        while (count) {
 255                skb = skb_dequeue(&data->readq);
 256                if (skb) {
 257                        ret = vhci_put_user(data, skb, buf, count);
 258                        if (ret < 0)
 259                                skb_queue_head(&data->readq, skb);
 260                        else
 261                                kfree_skb(skb);
 262                        break;
 263                }
 264
 265                if (file->f_flags & O_NONBLOCK) {
 266                        ret = -EAGAIN;
 267                        break;
 268                }
 269
 270                ret = wait_event_interruptible(data->read_wait,
 271                                               !skb_queue_empty(&data->readq));
 272                if (ret < 0)
 273                        break;
 274        }
 275
 276        return ret;
 277}
 278
 279static ssize_t vhci_write(struct kiocb *iocb, struct iov_iter *from)
 280{
 281        struct file *file = iocb->ki_filp;
 282        struct vhci_data *data = file->private_data;
 283
 284        return vhci_get_user(data, from);
 285}
 286
 287static __poll_t vhci_poll(struct file *file, poll_table *wait)
 288{
 289        struct vhci_data *data = file->private_data;
 290
 291        poll_wait(file, &data->read_wait, wait);
 292
 293        if (!skb_queue_empty(&data->readq))
 294                return EPOLLIN | EPOLLRDNORM;
 295
 296        return EPOLLOUT | EPOLLWRNORM;
 297}
 298
 299static void vhci_open_timeout(struct work_struct *work)
 300{
 301        struct vhci_data *data = container_of(work, struct vhci_data,
 302                                              open_timeout.work);
 303
 304        vhci_create_device(data, amp ? HCI_AMP : HCI_PRIMARY);
 305}
 306
 307static int vhci_open(struct inode *inode, struct file *file)
 308{
 309        struct vhci_data *data;
 310
 311        data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
 312        if (!data)
 313                return -ENOMEM;
 314
 315        skb_queue_head_init(&data->readq);
 316        init_waitqueue_head(&data->read_wait);
 317
 318        mutex_init(&data->open_mutex);
 319        INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
 320
 321        file->private_data = data;
 322        nonseekable_open(inode, file);
 323
 324        schedule_delayed_work(&data->open_timeout, msecs_to_jiffies(1000));
 325
 326        return 0;
 327}
 328
 329static int vhci_release(struct inode *inode, struct file *file)
 330{
 331        struct vhci_data *data = file->private_data;
 332        struct hci_dev *hdev;
 333
 334        cancel_delayed_work_sync(&data->open_timeout);
 335
 336        hdev = data->hdev;
 337
 338        if (hdev) {
 339                hci_unregister_dev(hdev);
 340                hci_free_dev(hdev);
 341        }
 342
 343        skb_queue_purge(&data->readq);
 344        file->private_data = NULL;
 345        kfree(data);
 346
 347        return 0;
 348}
 349
 350static const struct file_operations vhci_fops = {
 351        .owner          = THIS_MODULE,
 352        .read           = vhci_read,
 353        .write_iter     = vhci_write,
 354        .poll           = vhci_poll,
 355        .open           = vhci_open,
 356        .release        = vhci_release,
 357        .llseek         = no_llseek,
 358};
 359
 360static struct miscdevice vhci_miscdev = {
 361        .name   = "vhci",
 362        .fops   = &vhci_fops,
 363        .minor  = VHCI_MINOR,
 364};
 365module_misc_device(vhci_miscdev);
 366
 367module_param(amp, bool, 0644);
 368MODULE_PARM_DESC(amp, "Create AMP controller device");
 369
 370MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 371MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
 372MODULE_VERSION(VERSION);
 373MODULE_LICENSE("GPL");
 374MODULE_ALIAS("devname:vhci");
 375MODULE_ALIAS_MISCDEV(VHCI_MINOR);
 376