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 <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-10-28 15:14:46 +02:00 committed by Anas Nashif
commit 3822aecd24
10 changed files with 147 additions and 231 deletions

View file

@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
#include <bluetooth/buf.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>

View file

@ -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 <stddef.h>
#include <stdint.h>
#include <net/buf.h>
/** @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 */

View file

@ -35,6 +35,7 @@
#define __BT_L2CAP_H
#if defined(CONFIG_BLUETOOTH_CENTRAL) || defined(CONFIG_BLUETOOTH_PERIPHERAL)
#include <net/buf.h>
#include <bluetooth/conn.h>
/** @brief L2CAP Endpoint structure. */

View file

@ -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"

View file

@ -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 \

View file

@ -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 <nanokernel.h>
#include <toolchain.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <atomic.h>
#include <misc/byteorder.h>
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/buf.h>
#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;
}

View file

@ -28,7 +28,6 @@
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/buf.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt.h>
#include <bluetooth/driver.h>

View file

@ -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;

View file

@ -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 <bluetooth/driver.h>
struct net_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head);

View file

@ -28,6 +28,7 @@
#include <misc/util.h>
#include <misc/byteorder.h>
#include <net/buf.h>
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>