Bluetooth: ISO: Add BIG callbacks
Add callbacks that is called for the entire BIG. The BIG state is from an HCI perspective a single state change that we previously only propagated as a state change for each channel. However it may be simpler for applications and higher layers to use BIG changes to trigger their behavior. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
b3ffaf4441
commit
e8bcb29f3f
2 changed files with 88 additions and 0 deletions
|
@ -34,6 +34,7 @@
|
||||||
#include <zephyr/sys/atomic.h>
|
#include <zephyr/sys/atomic.h>
|
||||||
#include <zephyr/sys/slist.h>
|
#include <zephyr/sys/slist.h>
|
||||||
#include <zephyr/sys/util_macro.h>
|
#include <zephyr/sys/util_macro.h>
|
||||||
|
#include <zephyr/sys/slist.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -1102,6 +1103,42 @@ int bt_iso_chan_get_info(const struct bt_iso_chan *chan, struct bt_iso_info *inf
|
||||||
*/
|
*/
|
||||||
int bt_iso_chan_get_tx_sync(const struct bt_iso_chan *chan, struct bt_iso_tx_info *info);
|
int bt_iso_chan_get_tx_sync(const struct bt_iso_chan *chan, struct bt_iso_tx_info *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Struct to hold the Broadcast Isochronous Group callbacks
|
||||||
|
*
|
||||||
|
* These can be registered for usage with bt_iso_big_register_cb().
|
||||||
|
*/
|
||||||
|
struct bt_iso_big_cb {
|
||||||
|
/**
|
||||||
|
* @brief The BIG has started and all of the streams are ready for data
|
||||||
|
*
|
||||||
|
* @param big The started BIG
|
||||||
|
*/
|
||||||
|
void (*started)(struct bt_iso_big *big);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The BIG has stopped and none of the streams are ready for data
|
||||||
|
*
|
||||||
|
* @param big The stopped BIG
|
||||||
|
* @param reason The reason why the BIG stopped (see the BT_HCI_ERR_* values)
|
||||||
|
*/
|
||||||
|
void (*stopped)(struct bt_iso_big *big, uint8_t reason);
|
||||||
|
|
||||||
|
/** @internal Internally used field for list handling */
|
||||||
|
sys_snode_t _node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers callbacks for Broadcast Sources
|
||||||
|
*
|
||||||
|
* @param cb Pointer to the callback structure.
|
||||||
|
*
|
||||||
|
* @retval 0 on success
|
||||||
|
* @retval -EINVAL if @p cb is NULL
|
||||||
|
* @retval -EEXIST if @p cb is already registered
|
||||||
|
*/
|
||||||
|
int bt_iso_big_register_cb(struct bt_iso_big_cb *cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a BIG as a broadcaster
|
* @brief Creates a BIG as a broadcaster
|
||||||
*
|
*
|
||||||
|
|
|
@ -2525,6 +2525,8 @@ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count)
|
||||||
#endif /* CONFIG_BT_ISO_UNICAST */
|
#endif /* CONFIG_BT_ISO_UNICAST */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_ISO_BROADCAST)
|
#if defined(CONFIG_BT_ISO_BROADCAST)
|
||||||
|
static sys_slist_t iso_big_cbs = SYS_SLIST_STATIC_INIT(&iso_big_cbs);
|
||||||
|
|
||||||
static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle)
|
static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle)
|
||||||
{
|
{
|
||||||
return &bigs[big_handle];
|
return &bigs[big_handle];
|
||||||
|
@ -2587,6 +2589,16 @@ static void big_disconnect(struct bt_iso_big *big, uint8_t reason)
|
||||||
|
|
||||||
bt_iso_chan_disconnected(bis, reason);
|
bt_iso_chan_disconnected(bis, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sys_slist_is_empty(&iso_big_cbs)) {
|
||||||
|
struct bt_iso_big_cb *listener;
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
|
||||||
|
if (listener->stopped != NULL) {
|
||||||
|
listener->stopped(big, reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan **bis_channels, uint8_t num_bis,
|
static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan **bis_channels, uint8_t num_bis,
|
||||||
|
@ -2617,6 +2629,25 @@ static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan **bis_channel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bt_iso_big_register_cb(struct bt_iso_big_cb *cb)
|
||||||
|
{
|
||||||
|
CHECKIF(cb == NULL) {
|
||||||
|
LOG_DBG("cb is NULL");
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sys_slist_find(&iso_big_cbs, &cb->_node, NULL)) {
|
||||||
|
LOG_DBG("cb %p is already registered", cb);
|
||||||
|
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_slist_append(&iso_big_cbs, &cb->_node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_ISO_BROADCASTER)
|
#if defined(CONFIG_BT_ISO_BROADCASTER)
|
||||||
static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big,
|
static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big,
|
||||||
struct bt_iso_big_create_param *param)
|
struct bt_iso_big_create_param *param)
|
||||||
|
@ -3006,6 +3037,16 @@ void hci_le_big_complete(struct net_buf *buf)
|
||||||
store_bis_broadcaster_info(evt, &iso_conn->iso.info);
|
store_bis_broadcaster_info(evt, &iso_conn->iso.info);
|
||||||
bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
|
bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sys_slist_is_empty(&iso_big_cbs)) {
|
||||||
|
struct bt_iso_big_cb *listener;
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
|
||||||
|
if (listener->started != NULL) {
|
||||||
|
listener->started(big);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hci_le_big_terminate(struct net_buf *buf)
|
void hci_le_big_terminate(struct net_buf *buf)
|
||||||
|
@ -3186,6 +3227,16 @@ void hci_le_big_sync_established(struct net_buf *buf)
|
||||||
store_bis_sync_receiver_info(evt, &iso_conn->iso.info);
|
store_bis_sync_receiver_info(evt, &iso_conn->iso.info);
|
||||||
bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
|
bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sys_slist_is_empty(&iso_big_cbs)) {
|
||||||
|
struct bt_iso_big_cb *listener;
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
|
||||||
|
if (listener->started != NULL) {
|
||||||
|
listener->started(big);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hci_le_big_sync_lost(struct net_buf *buf)
|
void hci_le_big_sync_lost(struct net_buf *buf)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue