Bluetooth: host: Add ISO support for num_completed_packets event

Change so that num_completed_packets event handling is also
enabled for broadcast ISO only builds. This is because sending
data on a broadcast ISO still generates this event.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2021-08-13 10:36:52 +02:00 committed by Anas Nashif
commit 96dfad0eef
3 changed files with 72 additions and 57 deletions

View file

@ -63,11 +63,13 @@ static inline uint8_t bt_hci_evt_get_flags(uint8_t evt)
case BT_HCI_EVT_DISCONN_COMPLETE: case BT_HCI_EVT_DISCONN_COMPLETE:
return BT_HCI_EVT_FLAG_RECV | BT_HCI_EVT_FLAG_RECV_PRIO; return BT_HCI_EVT_FLAG_RECV | BT_HCI_EVT_FLAG_RECV_PRIO;
/* fallthrough */ /* fallthrough */
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
#if defined(CONFIG_BT_CONN)
case BT_HCI_EVT_DATA_BUF_OVERFLOW: case BT_HCI_EVT_DATA_BUF_OVERFLOW:
__fallthrough; __fallthrough;
#endif /* defined(CONFIG_BT_CONN) */ #endif /* defined(CONFIG_BT_CONN) */
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
case BT_HCI_EVT_CMD_COMPLETE: case BT_HCI_EVT_CMD_COMPLETE:
case BT_HCI_EVT_CMD_STATUS: case BT_HCI_EVT_CMD_STATUS:
return BT_HCI_EVT_FLAG_RECV_PRIO; return BT_HCI_EVT_FLAG_RECV_PRIO;

View file

@ -17,16 +17,26 @@
#include "common/log.h" #include "common/log.h"
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN)
#if defined(CONFIG_BT_ISO)
#define MAX_EVENT_COUNT CONFIG_BT_MAX_CONN + CONFIG_BT_ISO_MAX_CHAN
#else
#define MAX_EVENT_COUNT CONFIG_BT_MAX_CONN
#endif /* CONFIG_BT_ISO */
#elif defined(CONFIG_BT_ISO)
#define MAX_EVENT_COUNT CONFIG_BT_ISO_MAX_CHAN
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
#define NUM_COMLETE_EVENT_SIZE BT_BUF_EVT_SIZE( \ #define NUM_COMLETE_EVENT_SIZE BT_BUF_EVT_SIZE( \
sizeof(struct bt_hci_cp_host_num_completed_packets) + \ sizeof(struct bt_hci_cp_host_num_completed_packets) + \
CONFIG_BT_MAX_CONN * sizeof(struct bt_hci_handle_count)) MAX_EVENT_COUNT * sizeof(struct bt_hci_handle_count))
/* Dedicated pool for HCI_Number_of_Completed_Packets. This event is always /* Dedicated pool for HCI_Number_of_Completed_Packets. This event is always
* consumed synchronously by bt_recv_prio() so a single buffer is enough. * 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 * Having a dedicated pool for it ensures that exhaustion of the RX pool
* cannot block the delivery of this priority event. * cannot block the delivery of this priority event.
*/ */
NET_BUF_POOL_FIXED_DEFINE(num_complete_pool, 1, NUM_COMLETE_EVENT_SIZE, NULL); NET_BUF_POOL_FIXED_DEFINE(num_complete_pool, 1, NUM_COMLETE_EVENT_SIZE, NULL);
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
#if defined(CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT) #if defined(CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT)
NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT, NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT,
@ -105,7 +115,7 @@ struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable,
k_timeout_t timeout) k_timeout_t timeout)
{ {
switch (evt) { switch (evt) {
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
{ {
struct net_buf *buf; struct net_buf *buf;
@ -118,7 +128,7 @@ struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable,
return buf; return buf;
} }
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
case BT_HCI_EVT_CMD_COMPLETE: case BT_HCI_EVT_CMD_COMPLETE:
case BT_HCI_EVT_CMD_STATUS: case BT_HCI_EVT_CMD_STATUS:
return bt_buf_get_cmd_complete(timeout); return bt_buf_get_cmd_complete(timeout);

View file

@ -362,54 +362,7 @@ uint8_t bt_get_phy(uint8_t hci_phy)
} }
} }
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
static void hci_acl(struct net_buf *buf)
{
struct bt_hci_acl_hdr *hdr;
uint16_t handle, len;
struct bt_conn *conn;
uint8_t flags;
BT_DBG("buf %p", buf);
BT_ASSERT(buf->len >= sizeof(*hdr));
hdr = net_buf_pull_mem(buf, sizeof(*hdr));
len = sys_le16_to_cpu(hdr->len);
handle = sys_le16_to_cpu(hdr->handle);
flags = bt_acl_flags(handle);
acl(buf)->handle = bt_acl_handle(handle);
acl(buf)->index = BT_CONN_INDEX_INVALID;
BT_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags);
if (buf->len != len) {
BT_ERR("ACL data length mismatch (%u != %u)", buf->len, len);
net_buf_unref(buf);
return;
}
conn = bt_conn_lookup_handle(acl(buf)->handle);
if (!conn) {
BT_ERR("Unable to find conn for handle %u", acl(buf)->handle);
net_buf_unref(buf);
return;
}
acl(buf)->index = bt_conn_index(conn);
bt_conn_recv(conn, buf, flags);
bt_conn_unref(conn);
}
static void hci_data_buf_overflow(struct net_buf *buf)
{
struct bt_hci_evt_data_buf_overflow *evt = (void *)buf->data;
BT_WARN("Data buffer overflow (link type 0x%02x)", evt->link_type);
}
static void hci_num_completed_packets(struct net_buf *buf) static void hci_num_completed_packets(struct net_buf *buf)
{ {
struct bt_hci_evt_num_completed_packets *evt = (void *)buf->data; struct bt_hci_evt_num_completed_packets *evt = (void *)buf->data;
@ -469,6 +422,55 @@ static void hci_num_completed_packets(struct net_buf *buf)
bt_conn_unref(conn); bt_conn_unref(conn);
} }
} }
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
#if defined(CONFIG_BT_CONN)
static void hci_acl(struct net_buf *buf)
{
struct bt_hci_acl_hdr *hdr;
uint16_t handle, len;
struct bt_conn *conn;
uint8_t flags;
BT_DBG("buf %p", buf);
BT_ASSERT(buf->len >= sizeof(*hdr));
hdr = net_buf_pull_mem(buf, sizeof(*hdr));
len = sys_le16_to_cpu(hdr->len);
handle = sys_le16_to_cpu(hdr->handle);
flags = bt_acl_flags(handle);
acl(buf)->handle = bt_acl_handle(handle);
acl(buf)->index = BT_CONN_INDEX_INVALID;
BT_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags);
if (buf->len != len) {
BT_ERR("ACL data length mismatch (%u != %u)", buf->len, len);
net_buf_unref(buf);
return;
}
conn = bt_conn_lookup_handle(acl(buf)->handle);
if (!conn) {
BT_ERR("Unable to find conn for handle %u", acl(buf)->handle);
net_buf_unref(buf);
return;
}
acl(buf)->index = bt_conn_index(conn);
bt_conn_recv(conn, buf, flags);
bt_conn_unref(conn);
}
static void hci_data_buf_overflow(struct net_buf *buf)
{
struct bt_hci_evt_data_buf_overflow *evt = (void *)buf->data;
BT_WARN("Data buffer overflow (link type 0x%02x)", evt->link_type);
}
#if defined(CONFIG_BT_CENTRAL) #if defined(CONFIG_BT_CENTRAL)
static void set_phy_conn_param(const struct bt_conn *conn, static void set_phy_conn_param(const struct bt_conn *conn,
@ -3314,13 +3316,14 @@ static const struct event_handler prio_events[] = {
EVENT_HANDLER(BT_HCI_EVT_DATA_BUF_OVERFLOW, EVENT_HANDLER(BT_HCI_EVT_DATA_BUF_OVERFLOW,
hci_data_buf_overflow, hci_data_buf_overflow,
sizeof(struct bt_hci_evt_data_buf_overflow)), sizeof(struct bt_hci_evt_data_buf_overflow)),
EVENT_HANDLER(BT_HCI_EVT_DISCONN_COMPLETE, hci_disconn_complete_prio,
sizeof(struct bt_hci_evt_disconn_complete)),
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
EVENT_HANDLER(BT_HCI_EVT_NUM_COMPLETED_PACKETS, EVENT_HANDLER(BT_HCI_EVT_NUM_COMPLETED_PACKETS,
hci_num_completed_packets, hci_num_completed_packets,
sizeof(struct bt_hci_evt_num_completed_packets)), sizeof(struct bt_hci_evt_num_completed_packets)),
EVENT_HANDLER(BT_HCI_EVT_DISCONN_COMPLETE, hci_disconn_complete_prio, #endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
sizeof(struct bt_hci_evt_disconn_complete)),
#endif /* CONFIG_BT_CONN */
}; };
void hci_event_prio(struct net_buf *buf) void hci_event_prio(struct net_buf *buf)