Bluetooth: controller: CIS/CIG teardown at ACL disconnect
When an ACL connection with active CISes terminates, inject CIS/CIG teardown to ensure CIS is stopped before ACL disconnection completes. This includes stopping CIG ticker when last CIS has stopped. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
01e7dd853f
commit
d1f71e93a0
8 changed files with 282 additions and 30 deletions
|
@ -43,13 +43,15 @@
|
||||||
|
|
||||||
#include "ll_sw/pdu.h"
|
#include "ll_sw/pdu.h"
|
||||||
#include "ll_sw/lll.h"
|
#include "ll_sw/lll.h"
|
||||||
|
#include "ll_sw/lll_conn.h"
|
||||||
#include "ll.h"
|
#include "ll.h"
|
||||||
|
|
||||||
#include "isoal.h"
|
#include "isoal.h"
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_iso_types.h"
|
#include "ull_iso_types.h"
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
|
|
||||||
#include "hci_internal.h"
|
#include "hci_internal.h"
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,11 @@
|
||||||
#include "ull_master_internal.h"
|
#include "ull_master_internal.h"
|
||||||
#include "ull_conn_internal.h"
|
#include "ull_conn_internal.h"
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_iso_types.h"
|
#include "ull_iso_types.h"
|
||||||
#include "ull_central_iso_internal.h"
|
#include "ull_central_iso_internal.h"
|
||||||
|
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "ull_peripheral_iso_internal.h"
|
#include "ull_peripheral_iso_internal.h"
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_USER_EXT)
|
#if defined(CONFIG_BT_CTLR_USER_EXT)
|
||||||
|
|
|
@ -34,12 +34,14 @@
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_internal.h"
|
#include "ull_internal.h"
|
||||||
#include "ull_iso_internal.h"
|
|
||||||
#include "ull_sched_internal.h"
|
#include "ull_sched_internal.h"
|
||||||
#include "ull_chan_internal.h"
|
#include "ull_chan_internal.h"
|
||||||
#include "ull_conn_internal.h"
|
#include "ull_conn_internal.h"
|
||||||
#include "ull_slave_internal.h"
|
#include "ull_slave_internal.h"
|
||||||
#include "ull_master_internal.h"
|
#include "ull_master_internal.h"
|
||||||
|
|
||||||
|
#include "ull_iso_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "ull_peripheral_iso_internal.h"
|
#include "ull_peripheral_iso_internal.h"
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_USER_EXT)
|
#if defined(CONFIG_BT_CTLR_USER_EXT)
|
||||||
|
@ -80,6 +82,7 @@ static void ticker_start_conn_op_cb(uint32_t status, void *param);
|
||||||
static void conn_setup_adv_scan_disabled_cb(void *param);
|
static void conn_setup_adv_scan_disabled_cb(void *param);
|
||||||
static inline void disable(uint16_t handle);
|
static inline void disable(uint16_t handle);
|
||||||
static void conn_cleanup(struct ll_conn *conn, uint8_t reason);
|
static void conn_cleanup(struct ll_conn *conn, uint8_t reason);
|
||||||
|
static void conn_cleanup_finalize(struct ll_conn *conn);
|
||||||
static void tx_ull_flush(struct ll_conn *conn);
|
static void tx_ull_flush(struct ll_conn *conn);
|
||||||
static void ticker_op_stop_cb(uint32_t status, void *param);
|
static void ticker_op_stop_cb(uint32_t status, void *param);
|
||||||
static void disabled_cb(void *param);
|
static void disabled_cb(void *param);
|
||||||
|
@ -1923,28 +1926,28 @@ static inline void disable(uint16_t handle)
|
||||||
conn->lll.link_tx_free = NULL;
|
conn->lll.link_tx_free = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_cleanup(struct ll_conn *conn, uint8_t reason)
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
|
||||||
|
static void conn_cleanup_iso_cis_released_cb(struct ll_conn *conn)
|
||||||
|
{
|
||||||
|
struct ll_conn_iso_stream *cis;
|
||||||
|
|
||||||
|
cis = ll_conn_iso_stream_get_by_acl(conn, NULL);
|
||||||
|
if (cis) {
|
||||||
|
/* More associated CISes - stop next */
|
||||||
|
ull_conn_iso_cis_stop(cis, conn_cleanup_iso_cis_released_cb);
|
||||||
|
} else {
|
||||||
|
/* No more CISes associated with conn - finalize */
|
||||||
|
conn_cleanup_finalize(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO || CONFIG_BT_CTLR_CENTRAL_ISO */
|
||||||
|
|
||||||
|
static void conn_cleanup_finalize(struct ll_conn *conn)
|
||||||
{
|
{
|
||||||
struct lll_conn *lll = &conn->lll;
|
struct lll_conn *lll = &conn->lll;
|
||||||
struct node_rx_pdu *rx;
|
struct node_rx_pdu *rx;
|
||||||
uint32_t ticker_status;
|
uint32_t ticker_status;
|
||||||
|
|
||||||
/* reset mutex */
|
|
||||||
if (conn == conn_upd_curr) {
|
|
||||||
ull_conn_upd_curr_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only termination structure is populated here in ULL context
|
|
||||||
* but the actual enqueue happens in the LLL context in
|
|
||||||
* tx_lll_flush. The reason being to avoid passing the reason
|
|
||||||
* value and handle through the mayfly scheduling of the
|
|
||||||
* tx_lll_flush.
|
|
||||||
*/
|
|
||||||
rx = (void *)&conn->llcp_terminate.node_rx;
|
|
||||||
rx->hdr.handle = conn->lll.handle;
|
|
||||||
rx->hdr.type = NODE_RX_TYPE_TERMINATE;
|
|
||||||
*((uint8_t *)rx->pdu) = reason;
|
|
||||||
|
|
||||||
/* release any llcp reserved rx node */
|
/* release any llcp reserved rx node */
|
||||||
rx = conn->llcp_rx;
|
rx = conn->llcp_rx;
|
||||||
while (rx) {
|
while (rx) {
|
||||||
|
@ -1979,6 +1982,42 @@ static void conn_cleanup(struct ll_conn *conn, uint8_t reason)
|
||||||
ull_conn_tx_demux(UINT8_MAX);
|
ull_conn_tx_demux(UINT8_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void conn_cleanup(struct ll_conn *conn, uint8_t reason)
|
||||||
|
{
|
||||||
|
struct node_rx_pdu *rx;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
|
||||||
|
struct ll_conn_iso_stream *cis;
|
||||||
|
#endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO || CONFIG_BT_CTLR_CENTRAL_ISO */
|
||||||
|
|
||||||
|
/* Reset mutex */
|
||||||
|
if (conn == conn_upd_curr) {
|
||||||
|
ull_conn_upd_curr_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only termination structure is populated here in ULL context
|
||||||
|
* but the actual enqueue happens in the LLL context in
|
||||||
|
* tx_lll_flush. The reason being to avoid passing the reason
|
||||||
|
* value and handle through the mayfly scheduling of the
|
||||||
|
* tx_lll_flush.
|
||||||
|
*/
|
||||||
|
rx = (void *)&conn->llcp_terminate.node_rx;
|
||||||
|
rx->hdr.handle = conn->lll.handle;
|
||||||
|
rx->hdr.type = NODE_RX_TYPE_TERMINATE;
|
||||||
|
*((uint8_t *)rx->pdu) = reason;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
|
||||||
|
cis = ll_conn_iso_stream_get_by_acl(conn, NULL);
|
||||||
|
if (cis) {
|
||||||
|
/* Stop CIS and defer cleanup to after teardown. */
|
||||||
|
ull_conn_iso_cis_stop(cis, conn_cleanup_iso_cis_released_cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO || CONFIG_BT_CTLR_CENTRAL_ISO */
|
||||||
|
|
||||||
|
conn_cleanup_finalize(conn);
|
||||||
|
}
|
||||||
|
|
||||||
static void tx_ull_flush(struct ll_conn *conn)
|
static void tx_ull_flush(struct ll_conn *conn)
|
||||||
{
|
{
|
||||||
while (conn->tx_head) {
|
while (conn->tx_head) {
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
#include "lll_conn.h"
|
#include "lll_conn.h"
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
|
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_conn_internal.h"
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "ull_internal.h"
|
#include "ull_internal.h"
|
||||||
#include "lll/lll_vendor.h"
|
#include "lll/lll_vendor.h"
|
||||||
|
|
||||||
|
@ -114,6 +114,51 @@ struct ll_conn_iso_stream *ll_iso_stream_connected_get(uint16_t handle)
|
||||||
return cis;
|
return cis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_acl(struct ll_conn *conn, uint16_t *cis_iter)
|
||||||
|
{
|
||||||
|
uint8_t cis_iter_start = (cis_iter == NULL) || (*cis_iter) == UINT16_MAX;
|
||||||
|
uint8_t cig_handle;
|
||||||
|
|
||||||
|
/* Find CIS associated with ACL conn */
|
||||||
|
for (cig_handle = 0; cig_handle < CONFIG_BT_CTLR_CONN_ISO_GROUPS; cig_handle++) {
|
||||||
|
struct ll_conn_iso_stream *cis;
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
uint16_t handle_iter;
|
||||||
|
int8_t cis_idx;
|
||||||
|
|
||||||
|
cig = ll_conn_iso_group_get(cig_handle);
|
||||||
|
if (!cig) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_iter = UINT16_MAX;
|
||||||
|
|
||||||
|
for (cis_idx = 0; cis_idx < cig->lll.num_cis; cis_idx++) {
|
||||||
|
cis = ll_conn_iso_stream_get_by_group(cig, &handle_iter);
|
||||||
|
LL_ASSERT(cis);
|
||||||
|
|
||||||
|
uint16_t cis_handle = cis->lll.handle;
|
||||||
|
|
||||||
|
cis = ll_iso_stream_connected_get(cis_handle);
|
||||||
|
if (!cis) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cis_iter_start) {
|
||||||
|
/* Look for iterator start handle */
|
||||||
|
cis_iter_start = cis_handle == (*cis_iter);
|
||||||
|
} else if (cis->lll.acl_handle == conn->lll.handle) {
|
||||||
|
if (cis_iter) {
|
||||||
|
(*cis_iter) = cis_handle;
|
||||||
|
}
|
||||||
|
return cis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_group *cig,
|
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_group *cig,
|
||||||
uint16_t *handle_iter)
|
uint16_t *handle_iter)
|
||||||
{
|
{
|
||||||
|
@ -127,7 +172,7 @@ struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_gr
|
||||||
for (handle = handle_start; handle <= LAST_VALID_CIS_HANDLE; handle++) {
|
for (handle = handle_start; handle <= LAST_VALID_CIS_HANDLE; handle++) {
|
||||||
cis = ll_conn_iso_stream_get(handle);
|
cis = ll_conn_iso_stream_get(handle);
|
||||||
if (cis->group == cig) {
|
if (cis->group == cig) {
|
||||||
if (*handle_iter) {
|
if (handle_iter) {
|
||||||
(*handle_iter) = handle;
|
(*handle_iter) = handle;
|
||||||
}
|
}
|
||||||
return cis;
|
return cis;
|
||||||
|
@ -349,3 +394,155 @@ void ull_conn_iso_resume_ticker_start(struct lll_event *resume_event,
|
||||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
||||||
(ret == TICKER_STATUS_BUSY));
|
(ret == TICKER_STATUS_BUSY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void disabled_cig_cb(void *param)
|
||||||
|
{
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
|
||||||
|
cig = param;
|
||||||
|
|
||||||
|
ll_conn_iso_group_release(cig);
|
||||||
|
|
||||||
|
/* TODO: Flush pending TX in LLL */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ticker_stop_op_cb(uint32_t status, void *param)
|
||||||
|
{
|
||||||
|
static memq_link_t link;
|
||||||
|
static struct mayfly mfy = {0, 0, &link, NULL, NULL};
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
struct ull_hdr *hdr;
|
||||||
|
uint32_t ret;
|
||||||
|
|
||||||
|
/* Assert if race between thread and ULL */
|
||||||
|
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
cig = param;
|
||||||
|
hdr = &cig->ull;
|
||||||
|
mfy.param = cig;
|
||||||
|
|
||||||
|
if (ull_ref_get(hdr)) {
|
||||||
|
/* Event active (prepare/done ongoing) - wait for done and
|
||||||
|
* disable there. Abort the ongoing event in LLL.
|
||||||
|
*/
|
||||||
|
LL_ASSERT(!hdr->disabled_cb);
|
||||||
|
hdr->disabled_param = mfy.param;
|
||||||
|
hdr->disabled_cb = disabled_cig_cb;
|
||||||
|
|
||||||
|
mfy.fp = lll_disable;
|
||||||
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
|
||||||
|
TICKER_USER_ID_LLL, 0, &mfy);
|
||||||
|
LL_ASSERT(!ret);
|
||||||
|
} else {
|
||||||
|
/* Disable now */
|
||||||
|
mfy.fp = disabled_cig_cb;
|
||||||
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
|
||||||
|
TICKER_USER_ID_ULL_HIGH, 0, &mfy);
|
||||||
|
LL_ASSERT(!ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disabled_cis_cb(void *param)
|
||||||
|
{
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
struct ll_conn_iso_stream *cis;
|
||||||
|
uint32_t ticker_status;
|
||||||
|
uint16_t handle_iter;
|
||||||
|
uint8_t cis_idx;
|
||||||
|
uint8_t num_cis;
|
||||||
|
|
||||||
|
cig = param;
|
||||||
|
num_cis = cig->lll.num_cis;
|
||||||
|
handle_iter = UINT16_MAX;
|
||||||
|
|
||||||
|
/* Remove all CISes marked for teardown */
|
||||||
|
for (cis_idx = 0; cis_idx < cig->lll.num_cis; cis_idx++) {
|
||||||
|
cis = ll_conn_iso_stream_get_by_group(cig, &handle_iter);
|
||||||
|
LL_ASSERT(cis);
|
||||||
|
|
||||||
|
if (cis->teardown) {
|
||||||
|
struct ll_conn *conn;
|
||||||
|
ll_iso_stream_released_cb_t cis_released_cb;
|
||||||
|
|
||||||
|
conn = ll_conn_get(cis->lll.acl_handle);
|
||||||
|
cis_released_cb = cis->released_cb;
|
||||||
|
|
||||||
|
ll_conn_iso_stream_release(cis);
|
||||||
|
cig->lll.num_cis--;
|
||||||
|
|
||||||
|
/* Check if removed CIS had an ACL disassociation callback. Invoke
|
||||||
|
* the callback to allow cleanup.
|
||||||
|
*/
|
||||||
|
if (cis_released_cb) {
|
||||||
|
/* CIS removed - notify caller */
|
||||||
|
cis_released_cb(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_cis && cig->lll.num_cis == 0) {
|
||||||
|
/* This was the last CIS of the CIG. Initiate CIG teardown by
|
||||||
|
* stopping ticker.
|
||||||
|
*/
|
||||||
|
ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR,
|
||||||
|
TICKER_USER_ID_ULL_HIGH,
|
||||||
|
TICKER_ID_CONN_ISO_BASE +
|
||||||
|
ll_conn_iso_group_handle_get(cig),
|
||||||
|
ticker_stop_op_cb,
|
||||||
|
cig);
|
||||||
|
|
||||||
|
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
|
||||||
|
(ticker_status == TICKER_STATUS_BUSY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop and tear down a connected ISO stream
|
||||||
|
* This function may be called to tear down a CIS. When the CIS teardown
|
||||||
|
* has completed and the stream is released and callback is provided, the
|
||||||
|
* cis_released_cb callback is invoked.
|
||||||
|
*
|
||||||
|
* @param cis Pointer to connected ISO stream to stop
|
||||||
|
* @param cis_relased_cb Callback to invoke when the CIS has been released.
|
||||||
|
* NULL to ignore.
|
||||||
|
*/
|
||||||
|
void ull_conn_iso_cis_stop(struct ll_conn_iso_stream *cis,
|
||||||
|
ll_iso_stream_released_cb_t cis_relased_cb)
|
||||||
|
{
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
struct ull_hdr *hdr;
|
||||||
|
|
||||||
|
cig = cis->group;
|
||||||
|
hdr = &cig->ull;
|
||||||
|
|
||||||
|
if (cis->teardown) {
|
||||||
|
/* Teardown already started */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cis->teardown = 1;
|
||||||
|
cis->released_cb = cis_relased_cb;
|
||||||
|
|
||||||
|
if (ull_ref_get(hdr)) {
|
||||||
|
/* Event is active (prepare/done ongoing) - wait for done and
|
||||||
|
* continue CIS teardown from there. The disabled_cb cannot be
|
||||||
|
* reserved for other use.
|
||||||
|
*/
|
||||||
|
LL_ASSERT(!hdr->disabled_cb || hdr->disabled_cb == disabled_cis_cb);
|
||||||
|
|
||||||
|
hdr->disabled_param = cig;
|
||||||
|
hdr->disabled_cb = disabled_cis_cb;
|
||||||
|
} else {
|
||||||
|
static memq_link_t link;
|
||||||
|
static struct mayfly mfy = {0, 0, &link, NULL, NULL};
|
||||||
|
|
||||||
|
/* Tear down CIS now in ULL_HIGH context. Ignore enqueue
|
||||||
|
* error (already enqueued) as all CISes marked for teardown
|
||||||
|
* will be handled in disabled_cis_cb. Use mayfly chaining to
|
||||||
|
* prevent recursive stop calls.
|
||||||
|
*/
|
||||||
|
mfy.fp = disabled_cis_cb;
|
||||||
|
mfy.param = cig;
|
||||||
|
mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
|
||||||
|
TICKER_USER_ID_ULL_HIGH, 1, &mfy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,11 +19,15 @@ void ll_conn_iso_stream_release(struct ll_conn_iso_stream *cis);
|
||||||
uint16_t ll_conn_iso_stream_handle_get(struct ll_conn_iso_stream *cis);
|
uint16_t ll_conn_iso_stream_handle_get(struct ll_conn_iso_stream *cis);
|
||||||
struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle);
|
struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle);
|
||||||
struct ll_conn_iso_stream *ll_iso_stream_connected_get(uint16_t handle);
|
struct ll_conn_iso_stream *ll_iso_stream_connected_get(uint16_t handle);
|
||||||
|
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_acl(struct ll_conn *conn,
|
||||||
|
uint16_t *cis_iter);
|
||||||
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_group *cig,
|
struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_group *cig,
|
||||||
uint16_t *handle_iter);
|
uint16_t *handle_iter);
|
||||||
|
|
||||||
void ull_conn_iso_done(struct node_rx_event_done *done);
|
void ull_conn_iso_done(struct node_rx_event_done *done);
|
||||||
void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis);
|
void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis);
|
||||||
|
void ull_conn_iso_cis_stop(struct ll_conn_iso_stream *cis,
|
||||||
|
ll_iso_stream_released_cb_t cis_released_cb);
|
||||||
|
|
||||||
void ull_conn_iso_resume_ticker_start(struct lll_event *resume_event,
|
void ull_conn_iso_resume_ticker_start(struct lll_event *resume_event,
|
||||||
uint16_t cis_handle,
|
uint16_t cis_handle,
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct ll_conn;
|
||||||
|
|
||||||
|
typedef void (*ll_iso_stream_released_cb_t)(struct ll_conn *conn);
|
||||||
|
|
||||||
#define LL_CIS_HANDLE_BASE CONFIG_BT_MAX_CONN
|
#define LL_CIS_HANDLE_BASE CONFIG_BT_MAX_CONN
|
||||||
|
|
||||||
#define LL_CIS_IDX_FROM_HANDLE(_handle) \
|
#define LL_CIS_IDX_FROM_HANDLE(_handle) \
|
||||||
|
@ -16,11 +20,13 @@ struct ll_conn_iso_stream {
|
||||||
uint8_t cis_id;
|
uint8_t cis_id;
|
||||||
struct ll_iso_datapath *datapath_in;
|
struct ll_iso_datapath *datapath_in;
|
||||||
struct ll_iso_datapath *datapath_out;
|
struct ll_iso_datapath *datapath_out;
|
||||||
uint32_t offset; /* Offset of CIS from ACL event in us */
|
uint32_t offset; /* Offset of CIS from ACL event in us */
|
||||||
uint8_t established; /* 0 if CIS has not yet been established.
|
ll_iso_stream_released_cb_t released_cb; /* CIS release callback */
|
||||||
* 1 if CIS has been established and host
|
uint8_t established : 1; /* 0 if CIS has not yet been established.
|
||||||
* notified.
|
* 1 if CIS has been established and host
|
||||||
*/
|
* notified.
|
||||||
|
*/
|
||||||
|
uint8_t teardown : 1; /* 1 if CIS teardown has been initiated */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ll_conn_iso_group {
|
struct ll_conn_iso_group {
|
||||||
|
|
|
@ -25,10 +25,11 @@
|
||||||
#include "hal/debug.h"
|
#include "hal/debug.h"
|
||||||
|
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "isoal.h"
|
#include "isoal.h"
|
||||||
#include "ull_iso_types.h"
|
#include "ull_iso_types.h"
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
|
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
|
||||||
/* Allocate data path pools for RX/TX directions for each stream */
|
/* Allocate data path pools for RX/TX directions for each stream */
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
|
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
#include "ull_conn_internal.h"
|
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
|
||||||
#include "ull_internal.h"
|
#include "ull_internal.h"
|
||||||
|
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "lll_peripheral_iso.h"
|
#include "lll_peripheral_iso.h"
|
||||||
|
|
||||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
||||||
|
@ -129,6 +129,8 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
cis->cis_id = req->cis_id;
|
cis->cis_id = req->cis_id;
|
||||||
cis->established = 0;
|
cis->established = 0;
|
||||||
cis->group = cig;
|
cis->group = cig;
|
||||||
|
cis->teardown = 0;
|
||||||
|
cis->released_cb = NULL;
|
||||||
|
|
||||||
cis->lll.handle = 0xFFFF;
|
cis->lll.handle = 0xFFFF;
|
||||||
cis->lll.acl_handle = acl->lll.handle;
|
cis->lll.acl_handle = acl->lll.handle;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue