From 3822aecd2488c7ad5375f869a7085e322c296e81 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 28 Oct 2015 15:14:46 +0200 Subject: [PATCH] Bluetooth: Merge buf.[ch] functionality into hci_core.[ch] There's no need to maintain a separate module for this anymore. Subsequent patches will have further simplifications thanks to this being now handled in a single c-file. Change-Id: I4510c9f72b121e1e5fd19eeb8b5d5ddf2f4bfffe Signed-off-by: Johan Hedberg --- include/bluetooth/bluetooth.h | 1 - include/bluetooth/buf.h | 99 ---------------------------- include/bluetooth/l2cap.h | 1 + net/bluetooth/Kconfig | 8 --- net/bluetooth/Makefile | 3 +- net/bluetooth/buf.c | 119 ---------------------------------- net/bluetooth/gatt.c | 1 - net/bluetooth/hci_core.c | 77 +++++++++++++++++++++- net/bluetooth/hci_core.h | 68 +++++++++++++++++++ net/bluetooth/smp.c | 1 + 10 files changed, 147 insertions(+), 231 deletions(-) delete mode 100644 include/bluetooth/buf.h delete mode 100644 net/bluetooth/buf.c diff --git a/include/bluetooth/bluetooth.h b/include/bluetooth/bluetooth.h index 19e10c0049c..8ddc26a39be 100644 --- a/include/bluetooth/bluetooth.h +++ b/include/bluetooth/bluetooth.h @@ -24,7 +24,6 @@ #include #include -#include #include #include diff --git a/include/bluetooth/buf.h b/include/bluetooth/buf.h deleted file mode 100644 index 0ff716217e1..00000000000 --- a/include/bluetooth/buf.h +++ /dev/null @@ -1,99 +0,0 @@ -/** @file - * @brief Bluetooth buffer management. - */ - -/* - * Copyright (c) 2015 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. - */ -#ifndef __BT_BUF_H -#define __BT_BUF_H - -#include -#include -#include - -/** @def BT_BUF_MAX_DATA - * @brief Maximum amount of data that can fit in a buffer. - * - * The biggest foreseeable buffer size requirement right now comes from - * the Bluetooth 4.2 SMP MTU which is 65. This then become 65 + 4 (L2CAP - * header) + 4 (ACL header) + 1 (H4 header) = 74. This also covers the - * biggest HCI commands and events which are a bit under the 70 byte - * mark. - */ -#define BT_BUF_MAX_DATA 74 - -#define BT_BUF_ACL_IN_MAX 7 -#define BT_BUF_ACL_OUT_MAX 7 - -enum bt_buf_type { - BT_CMD, /** HCI command */ - BT_EVT, /** HCI event */ - BT_ACL_OUT, /** Outgoing ACL data */ - BT_ACL_IN, /** Incoming ACL data */ - BT_DUMMY = BT_CMD, /** Only used for waking up fibers */ -}; - -struct bt_hci_data { - /** Type of data contained in a buffer (bt_buf_type) */ - uint8_t type; - - /** The command OpCode that the buffer contains */ - uint16_t opcode; - - /** Used by bt_hci_cmd_send_sync. Initially contains the waiting - * semaphore, as the semaphore is given back contains the bt_buf - * for the return parameters. - */ - void *sync; - -}; -struct bt_acl_data { - /** Type of data contained in a buffer (bt_buf_type) */ - uint8_t type; - - /** ACL connection handle */ - uint16_t handle; -}; - -#define bt_hci(buf) ((struct bt_hci_data *)net_buf_user_data(buf)) -#define bt_acl(buf) ((struct bt_acl_data *)net_buf_user_data(buf)) -#define bt_type(buf) (*((uint8_t *)net_buf_user_data(buf))) - -/** @brief Get a new buffer from the pool. - * - * Get buffer from the available buffers pool with specified type and - * reserved headroom. - * - * @param type Buffer type. - * @param reserve_head How much headroom to reserve. - * - * @return New buffer or NULL if out of buffers. - * - * @warning If there are no available buffers and the function is - * called from a task or fiber the call will block until a buffer - * becomes available in the pool. - */ -struct net_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head); - -/** @brief Initialize buffer handling. - * - * Initialize the HCI and ACL buffers. - * - * @return Zero on success or (negative) error code on failure. - */ -int bt_buf_init(void); - -#endif /* __BT_BUF_H */ diff --git a/include/bluetooth/l2cap.h b/include/bluetooth/l2cap.h index 4f8b93e0c15..508983ecde3 100644 --- a/include/bluetooth/l2cap.h +++ b/include/bluetooth/l2cap.h @@ -35,6 +35,7 @@ #define __BT_L2CAP_H #if defined(CONFIG_BLUETOOTH_CENTRAL) || defined(CONFIG_BLUETOOTH_PERIPHERAL) +#include #include /** @brief L2CAP Endpoint structure. */ diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index a643c8e6875..be51bc80d39 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -104,14 +104,6 @@ config BLUETOOTH_DEBUG_HCI_CORE This option enables debug support for Bluetooth HCI core -config BLUETOOTH_DEBUG_BUF - bool - prompt "Bluetooth buffers debug" - depends on BLUETOOTH_DEBUG - default n - help - This option enables debug support for Bluetooth buffers. - config BLUETOOTH_DEBUG_CONN bool prompt "Bluetooth connection debug" diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 27d443d078f..67b7cc11608 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -1,5 +1,4 @@ -obj-y = buf.o \ - hci_core.o +obj-y = hci_core.o ifeq ($(CONFIG_BLUETOOTH_CONN),y) obj-y += conn.o \ diff --git a/net/bluetooth/buf.c b/net/bluetooth/buf.c deleted file mode 100644 index c4c0497b599..00000000000 --- a/net/bluetooth/buf.c +++ /dev/null @@ -1,119 +0,0 @@ -/* buf.c - Bluetooth buffer management */ - -/* - * Copyright (c) 2015 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 -#include -#include - -#include -#include -#include -#include - -#include "hci_core.h" - -#if !defined(CONFIG_BLUETOOTH_DEBUG_BUF) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - -/* Available (free) buffers queues */ -static struct nano_fifo avail_hci; -static NET_BUF_POOL(hci_pool, 8, BT_BUF_MAX_DATA, &avail_hci, NULL, - sizeof(struct bt_hci_data)); - -#if defined(CONFIG_BLUETOOTH_CONN) -static void report_completed_packet(struct net_buf *buf) -{ - - struct bt_hci_cp_host_num_completed_packets *cp; - struct bt_hci_handle_count *hc; - - BT_DBG("Reporting completed packet for handle %u\n", - bt_acl(buf)->handle); - - buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, - sizeof(*cp) + sizeof(*hc)); - if (!buf) { - BT_ERR("Unable to allocate new HCI command\n"); - return; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->num_handles = sys_cpu_to_le16(1); - - hc = net_buf_add(buf, sizeof(*hc)); - hc->handle = sys_cpu_to_le16(bt_acl(buf)->handle); - hc->count = sys_cpu_to_le16(1); - - bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf); -} - -static struct nano_fifo avail_acl_in; -static struct nano_fifo avail_acl_out; -static NET_BUF_POOL(acl_in_pool, BT_BUF_ACL_IN_MAX, BT_BUF_MAX_DATA, - &avail_acl_in, report_completed_packet, - sizeof(struct bt_acl_data)); -static NET_BUF_POOL(acl_out_pool, BT_BUF_ACL_OUT_MAX, BT_BUF_MAX_DATA, - &avail_acl_out, NULL, sizeof(struct bt_acl_data)); -#endif /* CONFIG_BLUETOOTH_CONN */ - -struct net_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head) -{ - struct net_buf *buf; - - switch (type) { - case BT_CMD: - case BT_EVT: - buf = net_buf_get(&avail_hci, reserve_head); - break; -#if defined(CONFIG_BLUETOOTH_CONN) - case BT_ACL_IN: - buf = net_buf_get(&avail_acl_in, reserve_head); - break; - case BT_ACL_OUT: - buf = net_buf_get(&avail_acl_out, reserve_head); - break; -#endif /* CONFIG_BLUETOOTH_CONN */ - default: - return NULL; - } - - if (buf) { - uint8_t *buf_type = net_buf_user_data(buf); - *buf_type = type; - } - - return buf; -} - -int bt_buf_init(void) -{ -#if defined(CONFIG_BLUETOOTH_CONN) - net_buf_pool_init(acl_in_pool); - net_buf_pool_init(acl_out_pool); -#endif /* CONFIG_BLUETOOTH_CONN */ - - net_buf_pool_init(hci_pool); - - return 0; -} diff --git a/net/bluetooth/gatt.c b/net/bluetooth/gatt.c index f7c7c884dd1..e28066b76c4 100644 --- a/net/bluetooth/gatt.c +++ b/net/bluetooth/gatt.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 70745791acc..16eb2468f89 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -54,6 +54,76 @@ struct bt_dev bt_dev; static bt_le_scan_cb_t *scan_dev_found_cb; +/* Available (free) buffers queues */ +static struct nano_fifo avail_hci; +static NET_BUF_POOL(hci_pool, 8, BT_BUF_MAX_DATA, &avail_hci, NULL, + sizeof(struct bt_hci_data)); + +#if defined(CONFIG_BLUETOOTH_CONN) +static void report_completed_packet(struct net_buf *buf) +{ + + struct bt_hci_cp_host_num_completed_packets *cp; + struct bt_hci_handle_count *hc; + + BT_DBG("Reporting completed packet for handle %u\n", + bt_acl(buf)->handle); + + buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, + sizeof(*cp) + sizeof(*hc)); + if (!buf) { + BT_ERR("Unable to allocate new HCI command\n"); + return; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->num_handles = sys_cpu_to_le16(1); + + hc = net_buf_add(buf, sizeof(*hc)); + hc->handle = sys_cpu_to_le16(bt_acl(buf)->handle); + hc->count = sys_cpu_to_le16(1); + + bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf); +} + +static struct nano_fifo avail_acl_in; +static struct nano_fifo avail_acl_out; +static NET_BUF_POOL(acl_in_pool, BT_BUF_ACL_IN_MAX, BT_BUF_MAX_DATA, + &avail_acl_in, report_completed_packet, + sizeof(struct bt_acl_data)); +static NET_BUF_POOL(acl_out_pool, BT_BUF_ACL_OUT_MAX, BT_BUF_MAX_DATA, + &avail_acl_out, NULL, sizeof(struct bt_acl_data)); +#endif /* CONFIG_BLUETOOTH_CONN */ + +struct net_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head) +{ + struct net_buf *buf; + + switch (type) { + case BT_CMD: + case BT_EVT: + buf = net_buf_get(&avail_hci, reserve_head); + break; +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_ACL_IN: + buf = net_buf_get(&avail_acl_in, reserve_head); + break; + case BT_ACL_OUT: + buf = net_buf_get(&avail_acl_out, reserve_head); + break; +#endif /* CONFIG_BLUETOOTH_CONN */ + default: + return NULL; + } + + if (buf) { + uint8_t *buf_type = net_buf_user_data(buf); + *buf_type = type; + } + + return buf; +} + #if defined(CONFIG_BLUETOOTH_DEBUG) const char *bt_addr_str(const bt_addr_t *addr) { @@ -1525,7 +1595,12 @@ int bt_enable(bt_ready_cb_t cb) return -ENODEV; } - bt_buf_init(); + /* Initialize the buffer pools */ + net_buf_pool_init(hci_pool); +#if defined(CONFIG_BLUETOOTH_CONN) + net_buf_pool_init(acl_in_pool); + net_buf_pool_init(acl_out_pool); +#endif /* CONFIG_BLUETOOTH_CONN */ /* Give cmd_sem allowing to send first HCI_Reset cmd */ bt_dev.ncmd = 1; diff --git a/net/bluetooth/hci_core.h b/net/bluetooth/hci_core.h index 6d25be7abd5..7ec1efc8235 100644 --- a/net/bluetooth/hci_core.h +++ b/net/bluetooth/hci_core.h @@ -175,3 +175,71 @@ const char *bt_addr_le_str(const bt_addr_le_t *addr); #endif int bt_le_scan_update(void); + +/* Buffer handling */ + +/** @def BT_BUF_MAX_DATA + * @brief Maximum amount of data that can fit in a buffer. + * + * The biggest foreseeable buffer size requirement right now comes from + * the Bluetooth 4.2 SMP MTU which is 65. This then become 65 + 4 (L2CAP + * header) + 4 (ACL header) + 1 (H4 header) = 74. This also covers the + * biggest HCI commands and events which are a bit under the 70 byte + * mark. + */ +#define BT_BUF_MAX_DATA 74 + +#define BT_BUF_ACL_IN_MAX 7 +#define BT_BUF_ACL_OUT_MAX 7 + +enum bt_buf_type { + BT_CMD, /** HCI command */ + BT_EVT, /** HCI event */ + BT_ACL_OUT, /** Outgoing ACL data */ + BT_ACL_IN, /** Incoming ACL data */ + BT_DUMMY = BT_CMD, /** Only used for waking up fibers */ +}; + +struct bt_hci_data { + /** Type of data contained in a buffer (bt_buf_type) */ + uint8_t type; + + /** The command OpCode that the buffer contains */ + uint16_t opcode; + + /** Used by bt_hci_cmd_send_sync. Initially contains the waiting + * semaphore, as the semaphore is given back contains the bt_buf + * for the return parameters. + */ + void *sync; + +}; +struct bt_acl_data { + /** Type of data contained in a buffer (bt_buf_type) */ + uint8_t type; + + /** ACL connection handle */ + uint16_t handle; +}; + +#define bt_hci(buf) ((struct bt_hci_data *)net_buf_user_data(buf)) +#define bt_acl(buf) ((struct bt_acl_data *)net_buf_user_data(buf)) +#define bt_type(buf) (*((uint8_t *)net_buf_user_data(buf))) + +/** @brief Get a new buffer from the pool. + * + * Get buffer from the available buffers pool with specified type and + * reserved headroom. + * + * @param type Buffer type. + * @param reserve_head How much headroom to reserve. + * + * @return New buffer or NULL if out of buffers. + * + * @warning If there are no available buffers and the function is + * called from a task or fiber the call will block until a buffer + * becomes available in the pool. + */ +/* Temporary include for enum definition */ +#include +struct net_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fda48a6b9d0..db54c8231e5 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include