/* hci_userchan.c - HCI user channel Bluetooth handling */ /* * Copyright (c) 2015-2016 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "monitor.h" static struct k_fifo *raw_rx; /* ACL incoming buffers */ static struct k_fifo avail_acl_in; static NET_BUF_POOL(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT, BT_BUF_ACL_IN_SIZE, &avail_acl_in, NULL, sizeof(uint8_t)); /* HCI event buffers */ static struct k_fifo avail_hci_evt; static NET_BUF_POOL(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT, BT_BUF_EVT_SIZE, &avail_hci_evt, NULL, sizeof(uint8_t)); static struct bt_dev { /* Registered HCI driver */ struct bt_hci_driver *drv; } bt_dev; int bt_hci_driver_register(struct bt_hci_driver *drv) { if (bt_dev.drv) { return -EALREADY; } if (!drv->open || !drv->send) { return -EINVAL; } bt_dev.drv = drv; BT_DBG("Registered %s", drv->name ? drv->name : ""); bt_monitor_new_index(BT_MONITOR_TYPE_PRIMARY, drv->bus, BT_ADDR_ANY, drv->name ? drv->name : "bt0"); return 0; } void bt_hci_driver_unregister(struct bt_hci_driver *drv) { bt_dev.drv = NULL; } struct net_buf *bt_buf_get_evt(uint8_t opcode) { struct net_buf *buf; buf = net_buf_get(&avail_hci_evt, 0); if (buf) { bt_buf_set_type(buf, BT_BUF_EVT); } return buf; } struct net_buf *bt_buf_get_acl(void) { struct net_buf *buf; buf = net_buf_get(&avail_acl_in, 0); if (buf) { bt_buf_set_type(buf, BT_BUF_ACL_IN); } return buf; } int bt_recv(struct net_buf *buf) { BT_DBG("buf %p len %u", buf, buf->len); bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); /* Queue to RAW rx queue */ net_buf_put(raw_rx, buf); return 0; } int bt_send(struct net_buf *buf) { BT_DBG("buf %p len %u", buf, buf->len); bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); return bt_dev.drv->send(buf); } int bt_enable_raw(struct k_fifo *rx_queue) { struct bt_hci_driver *drv = bt_dev.drv; int err; BT_DBG(""); net_buf_pool_init(hci_evt_pool); net_buf_pool_init(acl_in_pool); raw_rx = rx_queue; if (!bt_dev.drv) { BT_ERR("No HCI driver registered"); return -ENODEV; } err = drv->open(); if (err) { BT_ERR("HCI driver open failed (%d)", err); return err; } BT_INFO("Bluetooth enabled in RAW mode"); return 0; }