Bluetooth: Add RAW API interface to Bluetooth
HCI RAW channel API is intended to expose HCI interface to the remote entity. The local Bluetooth controller gets owned by the remote entity and host Bluetooth stack is not used. RAW API provides direct access to packets which are sent and received by Bluetooth HCI drivers. Change-Id: I4ba2b7ca2c2b0d6c5de6ef1f231d1c5b82125e09 Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
0b67e04922
commit
6ab1b9cdc4
5 changed files with 196 additions and 21 deletions
|
@ -24,7 +24,7 @@ if BLUETOOTH
|
|||
|
||||
menu "Bluetooth Drivers"
|
||||
|
||||
if BLUETOOTH_STACK_HCI
|
||||
if BLUETOOTH_STACK_HCI || BLUETOOTH_STACK_HCI_RAW
|
||||
|
||||
comment "Bluetooth HCI Driver Options"
|
||||
|
||||
|
|
20
include/bluetooth/hci_raw.h
Normal file
20
include/bluetooth/hci_raw.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* hci_raw.h - Bluetooth HCI RAW channel handling */
|
||||
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
int bt_send(struct net_buf *buf);
|
||||
int bt_enable_raw(struct nano_fifo *rx_queue);
|
|
@ -42,6 +42,12 @@ config BLUETOOTH_STACK_NBLE
|
|||
help
|
||||
Select the Bluetooth stack to use with Nordic BLE drivers.
|
||||
|
||||
config BLUETOOTH_STACK_HCI_RAW
|
||||
bool "Bluetooth RAW HCI access to the controller"
|
||||
help
|
||||
This option allows to access Bluetooth controller
|
||||
from the application with the RAW HCI protocol.
|
||||
|
||||
endchoice
|
||||
|
||||
comment "HCI Stack Configurations"
|
||||
|
@ -62,7 +68,7 @@ config BLUETOOTH_LE
|
|||
Currently it is mandatory whenever Bluetooth support
|
||||
(CONFIG_BLUETOOTH) is enabled.
|
||||
|
||||
if BLUETOOTH_LE
|
||||
if BLUETOOTH_LE || BLUETOOTH_STACK_HCI_RAW
|
||||
config BLUETOOTH_HCI_CMD_COUNT
|
||||
int "Number of HCI command buffers"
|
||||
default 2
|
||||
|
@ -100,7 +106,27 @@ config BLUETOOTH_MAX_EVT_LEN
|
|||
for LE is the Command Complete for Read Local Supported
|
||||
Commands. It is a 3 byte Command Complete header + 65 byte
|
||||
return parameters = 68 bytes in total.
|
||||
endif # BLUETOOTH_LE || BLUETOOTH_STACK_HCI_RAW
|
||||
|
||||
if (BLUETOOTH_LE && BLUETOOTH_CONN) || BLUETOOTH_STACK_HCI_RAW
|
||||
config BLUETOOTH_ACL_IN_COUNT
|
||||
int "Number of incoming ACL data buffers"
|
||||
default 5
|
||||
range 2 64
|
||||
help
|
||||
Number of buffers available for incoming ACL data.
|
||||
|
||||
config BLUETOOTH_L2CAP_IN_MTU
|
||||
int "Maximum supported L2CAP MTU for incoming data"
|
||||
default 65 if BLUETOOTH_SMP
|
||||
default 23 if !BLUETOOTH_SMP
|
||||
range 65 1300 if BLUETOOTH_SMP
|
||||
range 23 1300 if !BLUETOOTH_SMP
|
||||
help
|
||||
Maximum size of each incoming L2CAP PDU.
|
||||
endif # BLUETOOTH_LE && BLUETOOTH_CONN || BLUETOOTH_STACK_HCI_RAW
|
||||
|
||||
if BLUETOOTH_LE
|
||||
config BLUETOOTH_RX_STACK_SIZE
|
||||
int "Size of the receiving fiber stack"
|
||||
default 1024
|
||||
|
@ -134,22 +160,6 @@ config BLUETOOTH_CONN
|
|||
default n
|
||||
|
||||
if BLUETOOTH_CONN
|
||||
config BLUETOOTH_ACL_IN_COUNT
|
||||
int "Number of incoming ACL data buffers"
|
||||
default 5
|
||||
range 2 64
|
||||
help
|
||||
Number of buffers available for incoming ACL data.
|
||||
|
||||
config BLUETOOTH_L2CAP_IN_MTU
|
||||
int "Maximum supported L2CAP MTU for incoming data"
|
||||
default 65 if BLUETOOTH_SMP
|
||||
default 23 if !BLUETOOTH_SMP
|
||||
range 65 1300 if BLUETOOTH_SMP
|
||||
range 23 1300 if !BLUETOOTH_SMP
|
||||
help
|
||||
Maximum size of each incoming L2CAP PDU.
|
||||
|
||||
config BLUETOOTH_ATT_MTU
|
||||
int "Attribute Protocol (ATT) channel MTU"
|
||||
default 50 if BLUETOOTH_SMP # BLUETOOTH_L2CAP_IN_MTU is big enough
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
ccflags-y +=-I$(srctree)/include/drivers
|
||||
|
||||
obj-$(CONFIG_BLUETOOTH_STACK_HCI) = \
|
||||
hci_core.o \
|
||||
uuid.o
|
||||
obj-$(CONFIG_BLUETOOTH_STACK_HCI) += \
|
||||
uuid.o \
|
||||
hci_core.o
|
||||
|
||||
obj-$(CONFIG_BLUETOOTH_STACK_HCI_RAW) += \
|
||||
hci_raw.o
|
||||
|
||||
obj-$(CONFIG_BLUETOOTH_DEBUG) += log.o
|
||||
|
||||
|
|
142
net/bluetooth/hci_raw.c
Normal file
142
net/bluetooth/hci_raw.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* 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 <errno.h>
|
||||
#include <atomic.h>
|
||||
|
||||
#include <bluetooth/driver.h>
|
||||
#include <bluetooth/log.h>
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
static struct nano_fifo *raw_rx;
|
||||
|
||||
/* ACL incoming buffers */
|
||||
static struct nano_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 nano_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_driver *drv;
|
||||
} bt_dev;
|
||||
|
||||
int bt_driver_register(struct bt_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_driver_unregister(struct bt_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 nano_fifo *rx_queue)
|
||||
{
|
||||
struct bt_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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue