Bluetooth: host: Refactor out buffer handling to new file
Refactor out implementation of functions defined in buf.h to its own source file buf.c Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
parent
4978c19c05
commit
431dd9f25b
5 changed files with 153 additions and 130 deletions
|
@ -31,6 +31,7 @@ if(CONFIG_BT_HCI_HOST)
|
||||||
zephyr_library_sources(
|
zephyr_library_sources(
|
||||||
uuid.c
|
uuid.c
|
||||||
addr.c
|
addr.c
|
||||||
|
buf.c
|
||||||
hci_core.c
|
hci_core.c
|
||||||
hci_common.c
|
hci_common.c
|
||||||
)
|
)
|
||||||
|
|
137
subsys/bluetooth/host/buf.c
Normal file
137
subsys/bluetooth/host/buf.c
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||||
|
* Copyright (c) 2015 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bluetooth/buf.h>
|
||||||
|
#include <bluetooth/l2cap.h>
|
||||||
|
|
||||||
|
#include "hci_core.h"
|
||||||
|
#include "conn_internal.h"
|
||||||
|
#include "audio/iso_internal.h"
|
||||||
|
|
||||||
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
|
||||||
|
#define LOG_MODULE_NAME bt_buf
|
||||||
|
#include "common/log.h"
|
||||||
|
|
||||||
|
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
|
||||||
|
BT_BUF_RX_SIZE, NULL);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CONN)
|
||||||
|
#define NUM_COMLETE_EVENT_SIZE BT_BUF_SIZE(\
|
||||||
|
sizeof(struct bt_hci_evt_hdr) + \
|
||||||
|
sizeof(struct bt_hci_cp_host_num_completed_packets) + \
|
||||||
|
CONFIG_BT_MAX_CONN * sizeof(struct bt_hci_handle_count))
|
||||||
|
/* Dedicated pool for HCI_Number_of_Completed_Packets. This event is always
|
||||||
|
* consumed synchronously by bt_recv_prio() so a single buffer is enough.
|
||||||
|
* Having a dedicated pool for it ensures that exhaustion of the RX pool
|
||||||
|
* cannot block the delivery of this priority event.
|
||||||
|
*/
|
||||||
|
NET_BUF_POOL_FIXED_DEFINE(num_complete_pool, 1, NUM_COMLETE_EVENT_SIZE, NULL);
|
||||||
|
#endif /* CONFIG_BT_CONN */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DISCARDABLE_BUF_COUNT)
|
||||||
|
#define DISCARDABLE_EVENT_SIZE BT_BUF_SIZE(CONFIG_BT_DISCARDABLE_BUF_SIZE)
|
||||||
|
NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_DISCARDABLE_BUF_COUNT,
|
||||||
|
DISCARDABLE_EVENT_SIZE, NULL);
|
||||||
|
#endif /* CONFIG_BT_DISCARDABLE_BUF_COUNT */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
||||||
|
#define ACL_IN_SIZE BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_RX_MTU)
|
||||||
|
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BT_ACL_RX_COUNT, ACL_IN_SIZE,
|
||||||
|
sizeof(struct acl_data), bt_hci_host_num_completed_packets);
|
||||||
|
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
|
||||||
|
|
||||||
|
struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
|
||||||
|
{
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
__ASSERT(type == BT_BUF_EVT || type == BT_BUF_ACL_IN ||
|
||||||
|
type == BT_BUF_ISO_IN, "Invalid buffer type requested");
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_ISO) && type == BT_BUF_ISO_IN) {
|
||||||
|
return bt_iso_get_rx(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
||||||
|
if (type == BT_BUF_EVT) {
|
||||||
|
buf = net_buf_alloc(&hci_rx_pool, timeout);
|
||||||
|
} else {
|
||||||
|
buf = net_buf_alloc(&acl_in_pool, timeout);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
buf = net_buf_alloc(&hci_rx_pool, timeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
||||||
|
bt_buf_set_type(buf, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_buf *bt_buf_get_cmd_complete(k_timeout_t timeout)
|
||||||
|
{
|
||||||
|
struct net_buf *buf;
|
||||||
|
unsigned int key;
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
|
buf = bt_dev.sent_cmd;
|
||||||
|
bt_dev.sent_cmd = NULL;
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
BT_DBG("sent_cmd %p", buf);
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
bt_buf_set_type(buf, BT_BUF_EVT);
|
||||||
|
buf->len = 0U;
|
||||||
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_buf_get_rx(BT_BUF_EVT, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable,
|
||||||
|
k_timeout_t timeout)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
#if defined(CONFIG_BT_CONN)
|
||||||
|
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
|
||||||
|
{
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
buf = net_buf_alloc(&num_complete_pool, timeout);
|
||||||
|
if (buf) {
|
||||||
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
||||||
|
bt_buf_set_type(buf, BT_BUF_EVT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CONN */
|
||||||
|
case BT_HCI_EVT_CMD_COMPLETE:
|
||||||
|
case BT_HCI_EVT_CMD_STATUS:
|
||||||
|
return bt_buf_get_cmd_complete(timeout);
|
||||||
|
default:
|
||||||
|
#if defined(CONFIG_BT_DISCARDABLE_BUF_COUNT)
|
||||||
|
if (discardable) {
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
buf = net_buf_alloc(&discardable_pool, timeout);
|
||||||
|
if (buf) {
|
||||||
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
||||||
|
bt_buf_set_type(buf, BT_BUF_EVT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DISCARDABLE_BUF_COUNT */
|
||||||
|
|
||||||
|
return bt_buf_get_rx(BT_BUF_EVT, timeout);
|
||||||
|
}
|
||||||
|
}
|
|
@ -117,6 +117,17 @@ struct bt_conn_tx {
|
||||||
uint32_t pending_no_cb;
|
uint32_t pending_no_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acl_data {
|
||||||
|
/** BT_BUF_ACL_IN */
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
/* Index into the bt_conn storage array */
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
/** ACL connection handle */
|
||||||
|
uint16_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
struct bt_conn {
|
struct bt_conn {
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
|
@ -148,17 +148,6 @@ struct cmd_data {
|
||||||
struct k_sem *sync;
|
struct k_sem *sync;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acl_data {
|
|
||||||
/** BT_BUF_ACL_IN */
|
|
||||||
uint8_t type;
|
|
||||||
|
|
||||||
/* Index into the bt_conn storage array */
|
|
||||||
uint8_t index;
|
|
||||||
|
|
||||||
/** ACL connection handle */
|
|
||||||
uint16_t handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct cmd_data cmd_data[CONFIG_BT_HCI_CMD_COUNT];
|
static struct cmd_data cmd_data[CONFIG_BT_HCI_CMD_COUNT];
|
||||||
|
|
||||||
#define cmd(buf) (&cmd_data[net_buf_id(buf)])
|
#define cmd(buf) (&cmd_data[net_buf_id(buf)])
|
||||||
|
@ -171,28 +160,6 @@ static struct cmd_data cmd_data[CONFIG_BT_HCI_CMD_COUNT];
|
||||||
NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_HCI_CMD_COUNT,
|
NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_HCI_CMD_COUNT,
|
||||||
CMD_BUF_SIZE, NULL);
|
CMD_BUF_SIZE, NULL);
|
||||||
|
|
||||||
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
|
|
||||||
BT_BUF_RX_SIZE, NULL);
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CONN)
|
|
||||||
#define NUM_COMLETE_EVENT_SIZE BT_BUF_SIZE(\
|
|
||||||
sizeof(struct bt_hci_evt_hdr) + \
|
|
||||||
sizeof(struct bt_hci_cp_host_num_completed_packets) + \
|
|
||||||
CONFIG_BT_MAX_CONN * sizeof(struct bt_hci_handle_count))
|
|
||||||
/* Dedicated pool for HCI_Number_of_Completed_Packets. This event is always
|
|
||||||
* consumed synchronously by bt_recv_prio() so a single buffer is enough.
|
|
||||||
* Having a dedicated pool for it ensures that exhaustion of the RX pool
|
|
||||||
* cannot block the delivery of this priority event.
|
|
||||||
*/
|
|
||||||
NET_BUF_POOL_FIXED_DEFINE(num_complete_pool, 1, NUM_COMLETE_EVENT_SIZE, NULL);
|
|
||||||
#endif /* CONFIG_BT_CONN */
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_DISCARDABLE_BUF_COUNT)
|
|
||||||
#define DISCARDABLE_EVENT_SIZE BT_BUF_SIZE(CONFIG_BT_DISCARDABLE_BUF_SIZE)
|
|
||||||
NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_DISCARDABLE_BUF_COUNT,
|
|
||||||
DISCARDABLE_EVENT_SIZE, NULL);
|
|
||||||
#endif /* CONFIG_BT_DISCARDABLE_BUF_COUNT */
|
|
||||||
|
|
||||||
struct event_handler {
|
struct event_handler {
|
||||||
uint8_t event;
|
uint8_t event;
|
||||||
uint8_t min_len;
|
uint8_t min_len;
|
||||||
|
@ -234,7 +201,7 @@ static inline void handle_event(uint8_t event, struct net_buf *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
||||||
static void report_completed_packet(struct net_buf *buf)
|
void bt_hci_host_num_completed_packets(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct bt_hci_cp_host_num_completed_packets *cp;
|
struct bt_hci_cp_host_num_completed_packets *cp;
|
||||||
|
@ -282,11 +249,7 @@ static void report_completed_packet(struct net_buf *buf)
|
||||||
|
|
||||||
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
|
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
|
||||||
}
|
}
|
||||||
|
#endif /* defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) */
|
||||||
#define ACL_IN_SIZE BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_RX_MTU)
|
|
||||||
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BT_ACL_RX_COUNT, ACL_IN_SIZE,
|
|
||||||
sizeof(struct acl_data), report_completed_packet);
|
|
||||||
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
|
|
||||||
|
|
||||||
struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
|
struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
|
||||||
{
|
{
|
||||||
|
@ -9122,97 +9085,6 @@ int bt_le_set_chan_map(uint8_t chan_map[5])
|
||||||
buf, NULL);
|
buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
|
|
||||||
{
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
__ASSERT(type == BT_BUF_EVT || type == BT_BUF_ACL_IN ||
|
|
||||||
type == BT_BUF_ISO_IN, "Invalid buffer type requested");
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_ISO) && type == BT_BUF_ISO_IN) {
|
|
||||||
return bt_iso_get_rx(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
|
||||||
if (type == BT_BUF_EVT) {
|
|
||||||
buf = net_buf_alloc(&hci_rx_pool, timeout);
|
|
||||||
} else {
|
|
||||||
buf = net_buf_alloc(&acl_in_pool, timeout);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
buf = net_buf_alloc(&hci_rx_pool, timeout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
||||||
bt_buf_set_type(buf, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_buf *bt_buf_get_cmd_complete(k_timeout_t timeout)
|
|
||||||
{
|
|
||||||
struct net_buf *buf;
|
|
||||||
unsigned int key;
|
|
||||||
|
|
||||||
key = irq_lock();
|
|
||||||
buf = bt_dev.sent_cmd;
|
|
||||||
bt_dev.sent_cmd = NULL;
|
|
||||||
irq_unlock(key);
|
|
||||||
|
|
||||||
BT_DBG("sent_cmd %p", buf);
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
bt_buf_set_type(buf, BT_BUF_EVT);
|
|
||||||
buf->len = 0U;
|
|
||||||
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bt_buf_get_rx(BT_BUF_EVT, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout)
|
|
||||||
{
|
|
||||||
switch (evt) {
|
|
||||||
#if defined(CONFIG_BT_CONN)
|
|
||||||
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
|
|
||||||
{
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
buf = net_buf_alloc(&num_complete_pool, timeout);
|
|
||||||
if (buf) {
|
|
||||||
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
||||||
bt_buf_set_type(buf, BT_BUF_EVT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BT_CONN */
|
|
||||||
case BT_HCI_EVT_CMD_COMPLETE:
|
|
||||||
case BT_HCI_EVT_CMD_STATUS:
|
|
||||||
return bt_buf_get_cmd_complete(timeout);
|
|
||||||
default:
|
|
||||||
#if defined(CONFIG_BT_DISCARDABLE_BUF_COUNT)
|
|
||||||
if (discardable) {
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
buf = net_buf_alloc(&discardable_pool, timeout);
|
|
||||||
if (buf) {
|
|
||||||
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
||||||
bt_buf_set_type(buf, BT_BUF_EVT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BT_DISCARDABLE_BUF_COUNT */
|
|
||||||
|
|
||||||
return bt_buf_get_rx(BT_BUF_EVT, timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_BREDR)
|
#if defined(CONFIG_BT_BREDR)
|
||||||
static int br_start_inquiry(const struct bt_br_discovery_param *param)
|
static int br_start_inquiry(const struct bt_br_discovery_param *param)
|
||||||
{
|
{
|
||||||
|
|
|
@ -340,6 +340,8 @@ int bt_le_adv_start_internal(const struct bt_le_adv_param *param,
|
||||||
void bt_le_adv_resume(void);
|
void bt_le_adv_resume(void);
|
||||||
bool bt_le_scan_random_addr_check(void);
|
bool bt_le_scan_random_addr_check(void);
|
||||||
|
|
||||||
|
void bt_hci_host_num_completed_packets(struct net_buf *buf);
|
||||||
|
|
||||||
/* HCI event handlers */
|
/* HCI event handlers */
|
||||||
void hci_evt_pin_code_req(struct net_buf *buf);
|
void hci_evt_pin_code_req(struct net_buf *buf);
|
||||||
void hci_evt_link_key_notify(struct net_buf *buf);
|
void hci_evt_link_key_notify(struct net_buf *buf);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue