Bluetooth: ISO: Split ISO broadcast config

Splitt he ISO broadcast config into broadcaster and
sync receiver. This will allow a device that only
wants to one of the roles to have a much more optimized
configuration.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2021-10-14 20:36:53 +02:00 committed by Carles Cufí
commit a56cbed603
11 changed files with 80 additions and 34 deletions

View file

@ -1,10 +1,7 @@
CONFIG_BT=y
CONFIG_BT_ISO_BROADCAST=y
CONFIG_BT_ISO_BROADCASTER=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_DEVICE_NAME="Test ISO Broadcaster"
# Temporary, enable the following to meet BT_ISO dependencies
CONFIG_BT_OBSERVER=y
CONFIG_BT_BROADCASTER=y
# Just needs to send a uint32_t value
CONFIG_BT_ISO_TX_MTU=23

View file

@ -5,7 +5,8 @@ CONFIG_BT_DEVICE_NAME="ISO Broadcast Throughput"
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_ISO_BROADCAST=y
CONFIG_BT_ISO_BROADCASTER=y
CONFIG_BT_ISO_SYNC_RECEIVER=y
CONFIG_BT_ISO_MAX_CHAN=1
CONFIG_BT_ISO_TX_BUF_COUNT=2

View file

@ -1,7 +1,4 @@
CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_DEVICE_NAME="Test ISO Receive"
# Temporary, enable the following to meet BT_ISO dependencies
CONFIG_BT_ISO_BROADCAST=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_ISO_SYNC_RECEIVER=y

View file

@ -7,6 +7,7 @@
config BT_ISO
bool
# TODO: Split between client (central) and server (peripheral)
config BT_ISO_UNICAST
bool "Bluetooth Isochronous Channel Unicast Support [EXPERIMENTAL]"
depends on BT_CONN
@ -15,16 +16,27 @@ config BT_ISO_UNICAST
This option enables support for Bluetooth Broadcast
Isochronous channels.
# TODO: Split between broadcaster and observer for optimization
config BT_ISO_BROADCAST
bool "Bluetooth Isochronous Channel Broadcast Support [EXPERIMENTAL]"
bool
select BT_ISO
select BT_EXT_ADV
config BT_ISO_BROADCASTER
bool "Bluetooth Isochronous Broadcaster Support [EXPERIMENTAL]"
select BT_ISO_BROADCAST
select BT_BROADCASTER
select BT_PER_ADV
help
This option enables support for the Bluetooth Isochronous Broadcaster.
config BT_ISO_SYNC_RECEIVER
bool "Bluetooth Isochronous Synchronized Receiver Support [EXPERIMENTAL]"
select BT_ISO_BROADCAST
select BT_OBSERVER
select BT_PER_ADV_SYNC
help
This option enables support for Bluetooth Broadcast
Isochronous channels.
This option enables support for the Bluetooth Isochronous
Synchronized Receiver.
if BT_ISO

View file

@ -35,7 +35,8 @@ config BT_AUDIO_UNICAST
# TODO: Make BT_AUDIO_BROADCAST not depend on BT_CONN
config BT_AUDIO_BROADCAST
bool "Bluetooth Broadcast Audio Support"
select BT_ISO_BROADCAST
select BT_ISO_BROADCASTER
select BT_ISO_SYNC_RECEIVER
help
This option enables support for Bluetooth Broadcast Audio using
Isochronous channels.

View file

@ -66,7 +66,9 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
__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) {
if ((IS_ENABLED(CONFIG_BT_ISO_UNICAST) ||
IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER)) &&
type == BT_BUF_ISO_IN) {
return bt_iso_get_rx(timeout);
}

View file

@ -320,7 +320,8 @@ void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
BT_DBG("handle %u len %u flags %02x", conn->handle, buf->len, flags);
if (IS_ENABLED(CONFIG_BT_ISO) &&
if ((IS_ENABLED(CONFIG_BT_ISO_UNICAST) ||
IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER)) &&
conn->type == BT_CONN_TYPE_ISO) {
bt_iso_recv(conn, buf, flags);
return;

View file

@ -2203,13 +2203,15 @@ static const struct event_handler meta_events[] = {
EVENT_HANDLER(BT_HCI_EVT_LE_CIS_REQ, hci_le_cis_req,
sizeof(struct bt_hci_evt_le_cis_req)),
#endif /* (CONFIG_BT_ISO_UNICAST) */
#if defined(CONFIG_BT_ISO_BROADCAST)
#if defined(CONFIG_BT_ISO_BROADCASTER)
EVENT_HANDLER(BT_HCI_EVT_LE_BIG_COMPLETE,
hci_le_big_complete,
sizeof(struct bt_hci_evt_le_big_complete)),
EVENT_HANDLER(BT_HCI_EVT_LE_BIG_TERMINATE,
hci_le_big_terminate,
sizeof(struct bt_hci_evt_le_big_terminate)),
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
EVENT_HANDLER(BT_HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
hci_le_big_sync_established,
sizeof(struct bt_hci_evt_le_big_sync_established)),
@ -2219,7 +2221,7 @@ static const struct event_handler meta_events[] = {
EVENT_HANDLER(BT_HCI_EVT_LE_BIGINFO_ADV_REPORT,
bt_hci_le_biginfo_adv_report,
sizeof(struct bt_hci_evt_le_biginfo_adv_report)),
#endif /* (CONFIG_BT_ISO_BROADCAST) */
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
EVENT_HANDLER(BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT, bt_hci_le_df_connectionless_iq_report,
sizeof(struct bt_hci_evt_le_connectionless_iq_report)),
@ -2764,13 +2766,14 @@ static int le_set_event_mask(void)
}
/* Enable BIS events for broadcaster and/or receiver */
if (IS_ENABLED(CONFIG_BT_ISO_BROADCAST) &&
BT_FEAT_LE_BIS(bt_dev.le.features)) {
if (BT_FEAT_LE_ISO_BROADCASTER(bt_dev.le.features)) {
if (IS_ENABLED(CONFIG_BT_ISO) && BT_FEAT_LE_BIS(bt_dev.le.features)) {
if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) &&
BT_FEAT_LE_ISO_BROADCASTER(bt_dev.le.features)) {
mask |= BT_EVT_MASK_LE_BIG_COMPLETE;
mask |= BT_EVT_MASK_LE_BIG_TERMINATED;
}
if (BT_FEAT_LE_SYNC_RECEIVER(bt_dev.le.features)) {
if (IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER) &&
BT_FEAT_LE_SYNC_RECEIVER(bt_dev.le.features)) {
mask |= BT_EVT_MASK_LE_BIG_SYNC_ESTABLISHED;
mask |= BT_EVT_MASK_LE_BIG_SYNC_LOST;
mask |= BT_EVT_MASK_LE_BIGINFO_ADV_REPORT;

View file

@ -24,19 +24,26 @@
#define LOG_MODULE_NAME bt_iso
#include "common/log.h"
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_BROADCAST)
NET_BUF_POOL_FIXED_DEFINE(iso_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), NULL);
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_BROADCAST */
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_SYNC_RECEIVER)
NET_BUF_POOL_FIXED_DEFINE(iso_rx_pool, CONFIG_BT_ISO_RX_BUF_COUNT,
CONFIG_BT_ISO_RX_MTU, NULL);
static struct bt_iso_recv_info iso_info_data[CONFIG_BT_ISO_RX_BUF_COUNT];
#define iso_info(buf) (&iso_info_data[net_buf_id(buf)])
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_SYNC_RECEIVER */
#define iso_chan(_iso) ((_iso)->iso.chan);
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_BROADCAST)
#if CONFIG_BT_ISO_TX_FRAG_COUNT > 0
NET_BUF_POOL_FIXED_DEFINE(iso_frag_pool, CONFIG_BT_ISO_TX_FRAG_COUNT,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), NULL);
#endif /* CONFIG_BT_ISO_TX_FRAG_COUNT > 0 */
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_BROADCAST */
struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN];
@ -49,11 +56,12 @@ static struct bt_iso_server *iso_server;
struct bt_iso_big bigs[CONFIG_BT_ISO_MAX_BIG];
static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle);
#endif /* defined(CONFIG_BT_ISO_BROADCAST) */
#endif /* CONFIG_BT_ISO_BROADCAST */
/* Prototype */
int hci_le_remove_cig(uint8_t cig_id);
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_SYNC_RECEIVER)
struct net_buf *bt_iso_get_rx(k_timeout_t timeout)
{
struct net_buf *buf = net_buf_alloc(&iso_rx_pool, timeout);
@ -65,7 +73,9 @@ struct net_buf *bt_iso_get_rx(k_timeout_t timeout)
return buf;
}
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_BROADCASTER)
static void bt_iso_send_cb(struct bt_conn *iso, void *user_data)
{
struct bt_iso_chan *chan = iso->iso.chan;
@ -79,6 +89,7 @@ static void bt_iso_send_cb(struct bt_conn *iso, void *user_data)
ops->sent(chan);
}
}
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_BROADCASTER */
void hci_iso(struct net_buf *buf)
{
@ -530,6 +541,7 @@ void bt_iso_chan_set_state(struct bt_iso_chan *chan, uint8_t state)
}
#endif /* CONFIG_BT_DEBUG_ISO */
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_SYNC_RECEIVER)
void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags)
{
struct bt_hci_iso_data_hdr *hdr;
@ -671,7 +683,9 @@ void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags)
bt_conn_reset_rx_state(iso);
}
#endif /* CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_ISO_UNICAST) || defined(CONFIG_BT_ISO_BROADCASTER)
int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf)
{
struct bt_hci_iso_data_hdr *hdr;
@ -697,6 +711,7 @@ int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf)
return bt_conn_send_cb(chan->iso, buf, bt_iso_send_cb, NULL);
}
#endif /* CONFIG_BT_ISO_UNICAST) || CONFIG_BT_ISO_BROADCASTER */
static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos,
bool is_tx)
@ -1484,13 +1499,13 @@ static int big_init_bis(struct bt_iso_big *big, bool broadcaster)
return -EINVAL;
}
if (broadcaster) {
if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && broadcaster) {
CHECKIF(bis->qos->tx == NULL ||
!valid_chan_io_qos(bis->qos->tx, true)) {
BT_DBG("Invalid BIS QOS");
return -EINVAL;
}
} else {
} else if (IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER)) {
CHECKIF(bis->qos->rx == NULL) {
BT_DBG("Invalid BIS QOS");
return -EINVAL;
@ -1514,6 +1529,7 @@ static int big_init_bis(struct bt_iso_big *big, bool broadcaster)
return 0;
}
#if defined(CONFIG_BT_ISO_BROADCASTER)
static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big,
struct bt_iso_big_create_param *param)
{
@ -1649,6 +1665,7 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param
return err;
}
#endif /* CONFIG_BT_ISO_BROADCASTER */
static int hci_le_terminate_big(struct bt_iso_big *big)
{
@ -1717,7 +1734,7 @@ int bt_iso_big_terminate(struct bt_iso_big *big)
/* They all have the same QOS dir so we can just check the first */
broadcaster = big->bis[0]->qos->tx ? true : false;
if (broadcaster) {
if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && broadcaster) {
err = hci_le_terminate_big(big);
/* Wait for BT_HCI_EVT_LE_BIG_TERMINATE before cleaning up
@ -1728,13 +1745,15 @@ int bt_iso_big_terminate(struct bt_iso_big *big)
bt_iso_chan_set_state(big->bis[i], BT_ISO_DISCONNECT);
}
}
} else {
} else if (IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER)) {
err = hci_le_big_sync_term(big);
if (!err) {
big_disconnect(big, BT_HCI_ERR_LOCALHOST_TERM_CONN);
cleanup_big(big);
}
} else {
err = -EINVAL;
}
if (err) {
@ -1744,6 +1763,7 @@ int bt_iso_big_terminate(struct bt_iso_big *big)
return err;
}
#if defined(CONFIG_BT_ISO_BROADCASTER)
void hci_le_big_complete(struct net_buf *buf)
{
struct bt_hci_evt_le_big_complete *evt = (void *)buf->data;
@ -1801,7 +1821,9 @@ void hci_le_big_terminate(struct net_buf *buf)
big_disconnect(big, evt->reason);
cleanup_big(big);
}
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
void hci_le_big_sync_established(struct net_buf *buf)
{
struct bt_hci_evt_le_big_sync_established *evt = (void *)buf->data;
@ -1989,4 +2011,5 @@ int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_para
return 0;
}
#endif /* defined(CONFIG_BT_ISO_BROADCAST) */
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
#endif /* CONFIG_BT_ISO_BROADCAST */

View file

@ -893,7 +893,7 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf)
}
}
}
#endif /* defined(CONFIG_BT_ISO_BROADCAST) */
#endif /* CONFIG_BT_ISO_BROADCAST */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf)
{

View file

@ -336,6 +336,7 @@ static int cmd_disconnect(const struct shell *sh, size_t argc,
#if defined(CONFIG_BT_ISO_BROADCAST)
#define BIS_ISO_CHAN_COUNT 1
static struct bt_iso_big *big;
static struct bt_iso_chan_qos bis_iso_qos;
@ -346,8 +347,7 @@ static struct bt_iso_chan bis_iso_chan = {
static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan };
static struct bt_iso_big *big;
#if defined(CONFIG_BT_ISO_BROADCASTER)
NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, BIS_ISO_CHAN_COUNT,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), NULL);
@ -443,7 +443,9 @@ static int cmd_big_create(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[])
{
int err;
@ -503,6 +505,7 @@ static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
static int cmd_big_term(const struct shell *sh, size_t argc, char *argv[])
{
@ -532,14 +535,20 @@ SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds,
SHELL_CMD_ARG(disconnect, NULL, "Disconnect ISO Channel",
cmd_disconnect, 1, 0),
#endif /* CONFIG_BT_ISO_UNICAST */
#if defined(CONFIG_BT_ISO_BROADCAST)
#if defined(CONFIG_BT_ISO_BROADCASTER)
SHELL_CMD_ARG(create-big, NULL, "Create a BIG as a broadcaster [enc <broadcast code>]",
cmd_big_create, 1, 2),
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
SHELL_CMD_ARG(sync-big, NULL, "Synchronize to a BIG as a receiver <BIS bitfield> [mse] "
"[timeout] [enc <broadcast code>]", cmd_big_sync, 2, 4),
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_ISO_BROADCAST)
SHELL_CMD_ARG(term-big, NULL, "Terminate a BIG", cmd_big_term, 1, 0),
SHELL_CMD_ARG(broadcast, NULL, "Broadcast on ISO channels", cmd_broadcast, 1, 1),
#endif /* CONFIG_BT_ISO_BROADCAST */
#if defined(CONFIG_BT_ISO_BROADCASTER)
SHELL_CMD_ARG(broadcast, NULL, "Broadcast on ISO channels", cmd_broadcast, 1, 1),
#endif /* CONFIG_BT_ISO_BROADCASTER */
SHELL_SUBCMD_SET_END
);