/* * Copyright (c) 2020 Actions Semiconductor Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Bluetooth hci driver */ #include #include #include #include #include #include #ifdef CONFIG_ACTS_BT #include #include #include #else #include #include #include #endif #include #include static struct net_buf *buf; static uint8_t *hci_get_buf(uint8_t type, uint8_t evt, uint16_t exp_len) { switch (type) { case HCI_EVT: if (exp_len) { buf = bt_buf_get_evt_len(evt, false, K_NO_WAIT, exp_len); } else { buf = bt_buf_get_evt(evt, false, K_NO_WAIT); } break; case HCI_ACL: if (exp_len) { buf = bt_buf_get_rx_len(BT_BUF_ACL_IN, K_NO_WAIT, exp_len); } else { buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT); } break; case HCI_SCO: if (exp_len) { buf = bt_buf_get_rx_len(BT_BUF_SCO_IN, K_NO_WAIT, exp_len); } else { buf = bt_buf_get_rx(BT_BUF_SCO_IN, K_NO_WAIT); } break; case HCI_ISO: if (exp_len) { buf = bt_buf_get_rx_len(BT_BUF_ISO_IN, K_NO_WAIT, exp_len); } else { buf = bt_buf_get_rx(BT_BUF_ISO_IN, K_NO_WAIT); } break; default: buf = NULL; break; } if (!buf) { printk("Error to get buf!\n"); return NULL; } return buf->data; } /* process hci rx buf */ static int hci_recv(uint16_t len) { if (buf) { net_buf_add(buf, len); return bt_recv(buf); } else { printk("hci_recv buf NULL!\n"); return -ENOMEM; } } static int acts_hci_send(struct net_buf *buf) { int err = 0; uint8_t type = 0; if (buf == NULL) { return -EINVAL; } switch (bt_buf_get_type(buf)) { case BT_BUF_CMD: type = HCI_CMD; break; case BT_BUF_ACL_OUT: type = HCI_ACL; break; case BT_BUF_SCO_OUT: type = HCI_SCO; break; case BT_BUF_ISO_OUT: type = HCI_ISO; break; default: printk("unknown buf type\n"); break; } err = btdrv_send(type, buf->data, buf->len); net_buf_unref(buf); //should unref buf return err; } static const btdrv_hci_cb_t cb = { .get_buf = hci_get_buf, .recv = hci_recv, }; static int acts_hci_open(void) { return btdrv_init((btdrv_hci_cb_t *)&cb); } static const struct bt_hci_driver drv = { .name = "H:ACTS", .bus = BT_HCI_DRIVER_BUS_VIRTUAL, .quirks = BT_QUIRK_NO_AUTO_DLE, /* Controller does not auto-initiate a DLE procedure */ .open = acts_hci_open, .send = acts_hci_send, }; static int bt_acts_init(const struct device *unused) { ARG_UNUSED(unused); printk("bt hci drv register\n"); bt_hci_driver_register(&drv); return 0; } SYS_INIT(bt_acts_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);