2020-10-02 14:29:47 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020 Nordic Semiconductor ASA
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.
The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.
NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-25 09:58:46 +02:00
|
|
|
#include <zephyr/kernel.h>
|
2022-05-06 11:12:04 +02:00
|
|
|
#include <zephyr/sys/byteorder.h>
|
2023-06-09 13:33:53 +02:00
|
|
|
#include <zephyr/bluetooth/hci_types.h>
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "util/util.h"
|
|
|
|
#include "util/mem.h"
|
|
|
|
#include "util/memq.h"
|
|
|
|
#include "util/mayfly.h"
|
2022-09-11 07:03:13 +05:30
|
|
|
#include "util/dbuf.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
|
|
|
|
#include "hal/ccm.h"
|
|
|
|
#include "hal/radio.h"
|
|
|
|
#include "hal/ticker.h"
|
|
|
|
|
|
|
|
#include "ticker/ticker.h"
|
|
|
|
|
2023-01-20 18:07:24 +05:30
|
|
|
#include "pdu_df.h"
|
|
|
|
#include "lll/pdu_vendor.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "pdu.h"
|
|
|
|
|
|
|
|
#include "lll.h"
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "lll/lll_vendor.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "lll_clock.h"
|
|
|
|
#include "lll_scan.h"
|
2022-09-11 07:03:13 +05:30
|
|
|
#include "lll/lll_df_types.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "lll_sync.h"
|
|
|
|
#include "lll_sync_iso.h"
|
|
|
|
|
2022-02-22 10:58:24 +05:30
|
|
|
#include "isoal.h"
|
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "ull_scan_types.h"
|
|
|
|
#include "ull_sync_types.h"
|
2022-02-22 10:58:24 +05:30
|
|
|
#include "ull_iso_types.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
|
|
|
|
#include "ull_internal.h"
|
|
|
|
#include "ull_scan_internal.h"
|
|
|
|
#include "ull_sync_internal.h"
|
2021-11-23 21:57:16 +05:30
|
|
|
#include "ull_iso_internal.h"
|
2020-11-09 16:31:01 +01:00
|
|
|
#include "ull_sync_iso_internal.h"
|
|
|
|
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "ll.h"
|
|
|
|
|
2022-10-03 09:36:28 +05:30
|
|
|
#include "bt_crypto.h"
|
2022-11-02 14:31:13 +01:00
|
|
|
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "hal/debug.h"
|
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
static int init_reset(void);
|
2021-11-23 21:34:04 +05:30
|
|
|
static struct ll_sync_iso_set *sync_iso_get(uint8_t handle);
|
2024-03-11 14:41:21 +01:00
|
|
|
static struct ll_sync_iso_set *sync_iso_alloc(uint8_t handle);
|
2021-11-23 21:34:04 +05:30
|
|
|
static uint8_t sync_iso_handle_get(struct ll_sync_iso_set *sync);
|
2024-03-11 14:41:21 +01:00
|
|
|
static uint8_t sync_iso_handle_to_index(uint8_t handle);
|
2021-11-23 21:34:04 +05:30
|
|
|
static struct stream *sync_iso_stream_acquire(void);
|
|
|
|
static uint16_t sync_iso_stream_handle_get(struct lll_sync_iso_stream *stream);
|
2021-02-09 12:06:13 +05:30
|
|
|
static void timeout_cleanup(struct ll_sync_iso_set *sync_iso);
|
2021-09-15 11:48:21 +05:30
|
|
|
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
|
|
|
uint32_t remainder, uint16_t lazy, uint8_t force,
|
|
|
|
void *param);
|
2021-02-09 12:06:13 +05:30
|
|
|
static void ticker_start_op_cb(uint32_t status, void *param);
|
|
|
|
static void ticker_update_op_cb(uint32_t status, void *param);
|
|
|
|
static void ticker_stop_op_cb(uint32_t status, void *param);
|
2021-08-16 16:50:07 +05:30
|
|
|
static void sync_iso_disable(void *param);
|
2021-04-15 11:24:21 +05:30
|
|
|
static void disabled_cb(void *param);
|
2024-07-09 15:57:39 +02:00
|
|
|
static void lll_flush(void *param);
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
static memq_link_t link_lll_prepare;
|
2021-11-16 13:04:21 +05:30
|
|
|
static struct mayfly mfy_lll_prepare = {0U, 0U, &link_lll_prepare, NULL, NULL};
|
2021-02-18 13:02:24 +05:30
|
|
|
|
2021-01-06 13:32:08 +05:30
|
|
|
static struct ll_sync_iso_set ll_sync_iso[CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET];
|
2021-11-23 21:34:04 +05:30
|
|
|
static struct lll_sync_iso_stream
|
|
|
|
stream_pool[CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT];
|
2024-02-20 10:33:14 +01:00
|
|
|
static struct ll_iso_rx_test_mode
|
|
|
|
test_mode[CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT];
|
2021-11-23 21:34:04 +05:30
|
|
|
static void *stream_free;
|
2020-12-25 10:38:34 +05:30
|
|
|
|
2020-10-02 14:29:47 +02:00
|
|
|
uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
|
|
|
|
uint8_t encryption, uint8_t *bcode, uint8_t mse,
|
|
|
|
uint16_t sync_timeout, uint8_t num_bis,
|
|
|
|
uint8_t *bis)
|
|
|
|
{
|
2021-01-06 13:32:08 +05:30
|
|
|
struct ll_sync_iso_set *sync_iso;
|
2020-12-26 13:57:46 +05:30
|
|
|
memq_link_t *link_sync_estab;
|
|
|
|
memq_link_t *link_sync_lost;
|
2024-04-05 15:00:44 +02:00
|
|
|
struct node_rx_pdu *node_rx;
|
2020-12-26 13:57:46 +05:30
|
|
|
struct ll_sync_set *sync;
|
2021-02-18 13:02:24 +05:30
|
|
|
struct lll_sync_iso *lll;
|
2024-03-11 15:19:18 +01:00
|
|
|
int8_t last_index;
|
2020-10-02 14:29:47 +02:00
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
sync = ull_sync_is_enabled_get(sync_handle);
|
2024-03-11 14:41:21 +01:00
|
|
|
if (!sync) {
|
|
|
|
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sync->iso.sync_iso) {
|
2020-11-09 16:31:01 +01:00
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
sync_iso = sync_iso_get(big_handle);
|
2024-03-11 14:41:21 +01:00
|
|
|
if (sync_iso) {
|
|
|
|
/* BIG handle already in use */
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
2023-11-20 10:03:16 +01:00
|
|
|
}
|
|
|
|
|
2024-03-11 14:41:21 +01:00
|
|
|
sync_iso = sync_iso_alloc(big_handle);
|
|
|
|
if (!sync_iso) {
|
|
|
|
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
2024-03-11 15:19:18 +01:00
|
|
|
/* TODO: Check remaining parameters */
|
|
|
|
|
|
|
|
/* Check BIS indices */
|
|
|
|
last_index = -1;
|
|
|
|
for (uint8_t i = 0U; i < num_bis; i++) {
|
|
|
|
/* Stream index must be in valid range and in ascending order */
|
|
|
|
if (!IN_RANGE(bis[i], 0x01, 0x1F) || (bis[i] <= last_index)) {
|
|
|
|
return BT_HCI_ERR_INVALID_PARAM;
|
|
|
|
|
|
|
|
} else if (bis[i] > sync->num_bis) {
|
|
|
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
|
|
|
}
|
|
|
|
last_index = bis[i];
|
|
|
|
}
|
|
|
|
|
2024-05-20 09:46:28 +02:00
|
|
|
/* Check if encryption supported */
|
|
|
|
if (!IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
|
|
|
|
encryption) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
};
|
|
|
|
|
2024-03-11 15:19:18 +01:00
|
|
|
/* Check if requested encryption matches */
|
|
|
|
if (encryption != sync->enc) {
|
|
|
|
return BT_HCI_ERR_ENC_MODE_NOT_ACCEPTABLE;
|
|
|
|
}
|
2021-11-23 21:34:04 +05:30
|
|
|
|
|
|
|
/* Check if free BISes available */
|
|
|
|
if (mem_free_count_get(stream_free) < num_bis) {
|
2024-03-11 15:19:18 +01:00
|
|
|
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
2020-12-26 13:57:46 +05:30
|
|
|
link_sync_estab = ll_rx_link_alloc();
|
|
|
|
if (!link_sync_estab) {
|
|
|
|
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
link_sync_lost = ll_rx_link_alloc();
|
|
|
|
if (!link_sync_lost) {
|
|
|
|
ll_rx_link_release(link_sync_estab);
|
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
2020-12-26 13:57:46 +05:30
|
|
|
node_rx = ll_rx_alloc();
|
|
|
|
if (!node_rx) {
|
|
|
|
ll_rx_link_release(link_sync_lost);
|
|
|
|
ll_rx_link_release(link_sync_estab);
|
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
2020-12-26 13:57:46 +05:30
|
|
|
/* Initialize the ISO sync ULL context */
|
|
|
|
sync_iso->sync = sync;
|
2021-01-07 17:36:14 +05:30
|
|
|
sync_iso->timeout = sync_timeout;
|
|
|
|
sync_iso->timeout_reload = 0U;
|
|
|
|
sync_iso->timeout_expire = 0U;
|
2020-10-02 14:29:47 +02:00
|
|
|
|
2020-12-26 13:57:46 +05:30
|
|
|
/* Setup the periodic sync to establish ISO sync */
|
2024-04-05 15:00:44 +02:00
|
|
|
node_rx->hdr.link = link_sync_estab;
|
2020-12-26 13:57:46 +05:30
|
|
|
sync->iso.node_rx_estab = node_rx;
|
2024-04-05 15:00:44 +02:00
|
|
|
sync_iso->node_rx_lost.rx.hdr.link = link_sync_lost;
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
/* Initialize sync LLL context */
|
|
|
|
lll = &sync_iso->lll;
|
|
|
|
lll->latency_prepare = 0U;
|
|
|
|
lll->latency_event = 0U;
|
|
|
|
lll->window_widening_prepare_us = 0U;
|
|
|
|
lll->window_widening_event_us = 0U;
|
2021-11-18 21:57:09 +05:30
|
|
|
lll->ctrl = 0U;
|
|
|
|
lll->cssn_curr = 0U;
|
|
|
|
lll->cssn_next = 0U;
|
2022-09-12 06:37:30 +05:30
|
|
|
lll->term_reason = 0U;
|
2021-02-18 13:02:24 +05:30
|
|
|
|
2024-07-09 02:21:20 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) && encryption) {
|
2022-10-03 09:36:28 +05:30
|
|
|
const uint8_t BIG1[16] = {0x31, 0x47, 0x49, 0x42, };
|
|
|
|
const uint8_t BIG2[4] = {0x32, 0x47, 0x49, 0x42};
|
|
|
|
uint8_t igltk[16];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* Calculate GLTK */
|
|
|
|
err = bt_crypto_h7(BIG1, bcode, igltk);
|
|
|
|
LL_ASSERT(!err);
|
|
|
|
err = bt_crypto_h6(igltk, BIG2, sync_iso->gltk);
|
|
|
|
LL_ASSERT(!err);
|
|
|
|
|
|
|
|
lll->enc = 1U;
|
|
|
|
} else {
|
|
|
|
lll->enc = 0U;
|
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
/* TODO: Implement usage of MSE to limit listening to subevents */
|
|
|
|
|
|
|
|
/* Allocate streams */
|
|
|
|
lll->stream_count = num_bis;
|
|
|
|
for (uint8_t i = 0U; i < num_bis; i++) {
|
|
|
|
struct lll_sync_iso_stream *stream;
|
|
|
|
|
|
|
|
stream = (void *)sync_iso_stream_acquire();
|
|
|
|
stream->big_handle = big_handle;
|
2022-04-22 17:53:30 +05:30
|
|
|
stream->bis_index = bis[i];
|
2021-11-23 21:57:16 +05:30
|
|
|
stream->dp = NULL;
|
2024-02-20 10:33:14 +01:00
|
|
|
stream->test_mode = &test_mode[i];
|
|
|
|
memset(stream->test_mode, 0, sizeof(struct ll_iso_rx_test_mode));
|
2021-11-23 21:34:04 +05:30
|
|
|
lll->stream_handle[i] = sync_iso_stream_handle_get(stream);
|
|
|
|
}
|
|
|
|
|
2020-12-26 13:57:46 +05:30
|
|
|
/* Initialize ULL and LLL headers */
|
2020-11-09 16:31:01 +01:00
|
|
|
ull_hdr_init(&sync_iso->ull);
|
2021-02-18 13:02:24 +05:30
|
|
|
lll_hdr_init(lll, sync_iso);
|
2020-12-26 13:57:46 +05:30
|
|
|
|
|
|
|
/* Enable periodic advertising to establish ISO sync */
|
|
|
|
sync->iso.sync_iso = sync_iso;
|
2020-11-09 16:31:01 +01:00
|
|
|
|
|
|
|
return BT_HCI_ERR_SUCCESS;
|
|
|
|
}
|
2020-10-02 14:29:47 +02:00
|
|
|
|
2020-12-26 14:00:19 +05:30
|
|
|
uint8_t ll_big_sync_terminate(uint8_t big_handle, void **rx)
|
2020-10-02 14:29:47 +02:00
|
|
|
{
|
2024-07-09 15:57:39 +02:00
|
|
|
static memq_link_t link;
|
|
|
|
static struct mayfly mfy = {0, 0, &link, NULL, lll_flush};
|
|
|
|
|
2021-01-06 13:32:08 +05:30
|
|
|
struct ll_sync_iso_set *sync_iso;
|
2020-12-26 14:00:19 +05:30
|
|
|
memq_link_t *link_sync_estab;
|
2021-02-26 13:18:43 +05:30
|
|
|
struct node_rx_pdu *node_rx;
|
2020-12-26 14:00:19 +05:30
|
|
|
memq_link_t *link_sync_lost;
|
|
|
|
struct ll_sync_set *sync;
|
2024-07-09 15:57:39 +02:00
|
|
|
struct k_sem sem;
|
|
|
|
uint32_t ret;
|
2020-11-12 14:49:18 +01:00
|
|
|
int err;
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
sync_iso = sync_iso_get(big_handle);
|
2020-11-09 16:31:01 +01:00
|
|
|
if (!sync_iso) {
|
|
|
|
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
|
|
|
}
|
|
|
|
|
2020-12-26 14:00:19 +05:30
|
|
|
sync = sync_iso->sync;
|
2021-02-18 13:02:24 +05:30
|
|
|
if (sync && sync->iso.sync_iso) {
|
2020-12-26 14:00:19 +05:30
|
|
|
struct node_rx_sync_iso *se;
|
|
|
|
|
|
|
|
if (sync->iso.sync_iso != sync_iso) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
sync->iso.sync_iso = NULL;
|
2021-11-23 21:34:04 +05:30
|
|
|
|
2024-04-05 15:00:44 +02:00
|
|
|
node_rx = sync->iso.node_rx_estab;
|
2020-12-26 14:00:19 +05:30
|
|
|
link_sync_estab = node_rx->hdr.link;
|
2024-04-05 15:00:44 +02:00
|
|
|
link_sync_lost = sync_iso->node_rx_lost.rx.hdr.link;
|
2020-12-26 14:00:19 +05:30
|
|
|
|
|
|
|
ll_rx_link_release(link_sync_lost);
|
|
|
|
ll_rx_link_release(link_sync_estab);
|
|
|
|
ll_rx_release(node_rx);
|
|
|
|
|
|
|
|
node_rx = (void *)&sync_iso->node_rx_lost;
|
|
|
|
node_rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
|
2023-04-02 10:31:06 +05:30
|
|
|
node_rx->hdr.handle = big_handle;
|
2020-12-26 14:00:19 +05:30
|
|
|
|
2021-02-26 13:18:43 +05:30
|
|
|
/* NOTE: Since NODE_RX_TYPE_SYNC_ISO is only generated from ULL
|
|
|
|
* context, pass ULL context as parameter.
|
|
|
|
*/
|
2024-04-05 15:00:44 +02:00
|
|
|
node_rx->rx_ftr.param = sync_iso;
|
2021-02-26 13:18:43 +05:30
|
|
|
|
2024-04-05 15:00:44 +02:00
|
|
|
/* NOTE: struct node_rx_lost has uint8_t member store the reason.
|
2020-12-26 14:00:19 +05:30
|
|
|
*/
|
|
|
|
se = (void *)node_rx->pdu;
|
|
|
|
se->status = BT_HCI_ERR_OP_CANCELLED_BY_HOST;
|
|
|
|
|
|
|
|
*rx = node_rx;
|
|
|
|
|
|
|
|
return BT_HCI_ERR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ull_ticker_stop_with_mark((TICKER_ID_SCAN_SYNC_ISO_BASE +
|
2024-03-11 14:41:21 +01:00
|
|
|
sync_iso_handle_to_index(big_handle)),
|
|
|
|
sync_iso, &sync_iso->lll);
|
2024-05-06 12:50:11 +02:00
|
|
|
LL_ASSERT_INFO2(err == 0 || err == -EALREADY, big_handle, err);
|
2020-11-12 14:49:18 +01:00
|
|
|
if (err) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2024-07-09 15:57:39 +02:00
|
|
|
/* Do a blocking mayfly call to LLL context for flushing any outstanding
|
|
|
|
* operations.
|
|
|
|
*/
|
|
|
|
sync_iso->flush_sem = &sem;
|
|
|
|
k_sem_init(&sem, 0, 1);
|
|
|
|
mfy.param = &sync_iso->lll;
|
|
|
|
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_LLL, 0, &mfy);
|
|
|
|
LL_ASSERT(!ret);
|
|
|
|
k_sem_take(&sem, K_FOREVER);
|
|
|
|
sync_iso->flush_sem = NULL;
|
|
|
|
|
|
|
|
/* Release resources */
|
2021-11-23 21:34:04 +05:30
|
|
|
ull_sync_iso_stream_release(sync_iso);
|
|
|
|
|
2024-04-05 15:00:44 +02:00
|
|
|
link_sync_lost = sync_iso->node_rx_lost.rx.hdr.link;
|
2020-12-26 14:00:19 +05:30
|
|
|
ll_rx_link_release(link_sync_lost);
|
2020-11-09 16:31:01 +01:00
|
|
|
|
|
|
|
return BT_HCI_ERR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ull_sync_iso_init(void)
|
|
|
|
{
|
|
|
|
int err;
|
2020-10-02 14:29:47 +02:00
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
err = init_reset();
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ull_sync_iso_reset(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = init_reset();
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-03-11 14:41:21 +01:00
|
|
|
uint8_t ull_sync_iso_lll_index_get(struct lll_sync_iso *lll)
|
2020-11-09 16:31:01 +01:00
|
|
|
{
|
2024-03-11 14:41:21 +01:00
|
|
|
return ARRAY_INDEX(ll_sync_iso, HDR_LLL2ULL(lll));
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
struct ll_sync_iso_set *ull_sync_iso_by_stream_get(uint16_t handle)
|
|
|
|
{
|
|
|
|
if (handle >= CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT) {
|
2020-11-09 16:31:01 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
return sync_iso_get(stream_pool[handle].big_handle);
|
2020-11-09 16:31:01 +01:00
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
struct lll_sync_iso_stream *ull_sync_iso_stream_get(uint16_t handle)
|
2020-11-09 16:31:01 +01:00
|
|
|
{
|
2022-01-25 11:20:59 +05:30
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
|
|
|
|
/* Get the BIG Sync context and check for not being terminated */
|
|
|
|
sync_iso = ull_sync_iso_by_stream_get(handle);
|
|
|
|
if (!sync_iso || !sync_iso->sync) {
|
2021-11-23 21:34:04 +05:30
|
|
|
return NULL;
|
|
|
|
}
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
return &stream_pool[handle];
|
2020-11-09 16:31:01 +01:00
|
|
|
}
|
|
|
|
|
2022-04-22 17:53:30 +05:30
|
|
|
struct lll_sync_iso_stream *ull_sync_iso_lll_stream_get(uint16_t handle)
|
|
|
|
{
|
|
|
|
return ull_sync_iso_stream_get(handle);
|
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
void ull_sync_iso_stream_release(struct ll_sync_iso_set *sync_iso)
|
2020-11-09 16:31:01 +01:00
|
|
|
{
|
2021-11-23 21:34:04 +05:30
|
|
|
struct lll_sync_iso *lll;
|
|
|
|
|
|
|
|
lll = &sync_iso->lll;
|
|
|
|
while (lll->stream_count--) {
|
|
|
|
struct lll_sync_iso_stream *stream;
|
2021-11-23 21:57:16 +05:30
|
|
|
struct ll_iso_datapath *dp;
|
2022-11-07 11:17:37 -08:00
|
|
|
uint16_t stream_handle;
|
2021-11-23 21:34:04 +05:30
|
|
|
|
2022-11-07 11:17:37 -08:00
|
|
|
stream_handle = lll->stream_handle[lll->stream_count];
|
|
|
|
stream = ull_sync_iso_stream_get(stream_handle);
|
2022-01-25 11:20:59 +05:30
|
|
|
LL_ASSERT(stream);
|
2021-11-23 21:57:16 +05:30
|
|
|
|
|
|
|
dp = stream->dp;
|
|
|
|
if (dp) {
|
2022-02-22 10:58:24 +05:30
|
|
|
stream->dp = NULL;
|
|
|
|
isoal_sink_destroy(dp->sink_hdl);
|
2021-11-23 21:57:16 +05:30
|
|
|
ull_iso_datapath_release(dp);
|
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
mem_release(stream, &stream_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
sync_iso->sync = NULL;
|
2020-11-09 16:31:01 +01:00
|
|
|
}
|
|
|
|
|
2021-01-06 13:32:08 +05:30
|
|
|
void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso,
|
2024-04-05 15:00:44 +02:00
|
|
|
struct node_rx_pdu *node_rx,
|
2021-02-18 13:02:24 +05:30
|
|
|
uint8_t *acad, uint8_t acad_len)
|
2020-11-09 16:31:01 +01:00
|
|
|
{
|
2022-11-17 08:47:10 +05:30
|
|
|
struct lll_sync_iso_stream *stream;
|
2020-11-12 14:49:18 +01:00
|
|
|
uint32_t ticks_slot_overhead;
|
2021-02-18 13:02:24 +05:30
|
|
|
uint32_t sync_iso_offset_us;
|
2020-11-12 14:49:18 +01:00
|
|
|
uint32_t ticks_slot_offset;
|
2023-02-07 08:21:22 +05:30
|
|
|
uint32_t ticks_threshold;
|
2020-12-26 14:00:19 +05:30
|
|
|
struct lll_sync_iso *lll;
|
2020-11-12 14:49:18 +01:00
|
|
|
struct node_rx_ftr *ftr;
|
2021-02-18 13:02:24 +05:30
|
|
|
struct pdu_big_info *bi;
|
|
|
|
uint32_t ready_delay_us;
|
2023-02-07 08:21:22 +05:30
|
|
|
uint32_t ticks_expire;
|
2023-02-12 18:01:10 +05:30
|
|
|
uint32_t ctrl_spacing;
|
|
|
|
uint32_t pdu_spacing;
|
2020-12-26 14:00:19 +05:30
|
|
|
uint32_t interval_us;
|
2023-02-07 08:21:22 +05:30
|
|
|
uint32_t ticks_diff;
|
2021-02-18 13:02:24 +05:30
|
|
|
struct pdu_adv *pdu;
|
2023-02-12 18:01:10 +05:30
|
|
|
uint32_t slot_us;
|
|
|
|
uint8_t num_bis;
|
2021-02-18 13:02:24 +05:30
|
|
|
uint8_t bi_size;
|
2021-02-09 12:06:13 +05:30
|
|
|
uint8_t handle;
|
2020-12-26 14:00:19 +05:30
|
|
|
uint32_t ret;
|
2021-02-18 13:02:24 +05:30
|
|
|
uint8_t sca;
|
|
|
|
|
2022-10-03 09:32:20 +05:30
|
|
|
while (acad_len) {
|
|
|
|
const uint8_t hdr_len = acad[PDU_ADV_DATA_HEADER_LEN_OFFSET];
|
|
|
|
|
|
|
|
if ((hdr_len >= PDU_ADV_DATA_HEADER_TYPE_SIZE) &&
|
|
|
|
(acad[PDU_ADV_DATA_HEADER_TYPE_OFFSET] ==
|
|
|
|
BT_DATA_BIG_INFO)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (acad_len < (hdr_len + PDU_ADV_DATA_HEADER_LEN_SIZE)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
acad_len -= hdr_len + PDU_ADV_DATA_HEADER_LEN_SIZE;
|
|
|
|
acad += hdr_len + PDU_ADV_DATA_HEADER_LEN_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((acad_len < (PDU_BIG_INFO_CLEARTEXT_SIZE +
|
|
|
|
PDU_ADV_DATA_HEADER_SIZE)) ||
|
|
|
|
((acad[PDU_ADV_DATA_HEADER_LEN_OFFSET] !=
|
|
|
|
(PDU_ADV_DATA_HEADER_TYPE_SIZE + PDU_BIG_INFO_CLEARTEXT_SIZE)) &&
|
|
|
|
(acad[PDU_ADV_DATA_HEADER_LEN_OFFSET] !=
|
|
|
|
(PDU_ADV_DATA_HEADER_TYPE_SIZE + PDU_BIG_INFO_ENCRYPTED_SIZE)))) {
|
2021-02-18 13:02:24 +05:30
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-03 09:32:20 +05:30
|
|
|
bi_size = acad[PDU_ADV_DATA_HEADER_LEN_OFFSET] -
|
|
|
|
PDU_ADV_DATA_HEADER_TYPE_SIZE;
|
2021-11-16 12:45:40 +05:30
|
|
|
bi = (void *)&acad[PDU_ADV_DATA_HEADER_DATA_OFFSET];
|
2020-11-12 14:49:18 +01:00
|
|
|
|
|
|
|
lll = &sync_iso->lll;
|
2021-11-16 13:04:21 +05:30
|
|
|
(void)memcpy(lll->seed_access_addr, &bi->seed_access_addr,
|
|
|
|
sizeof(lll->seed_access_addr));
|
|
|
|
(void)memcpy(lll->base_crc_init, &bi->base_crc_init,
|
|
|
|
sizeof(lll->base_crc_init));
|
|
|
|
|
|
|
|
(void)memcpy(lll->data_chan_map, bi->chm_phy,
|
|
|
|
sizeof(lll->data_chan_map));
|
|
|
|
lll->data_chan_map[4] &= 0x1F;
|
|
|
|
lll->data_chan_count = util_ones_count_get(lll->data_chan_map,
|
2021-02-18 13:02:24 +05:30
|
|
|
sizeof(lll->data_chan_map));
|
2021-11-16 13:10:19 +05:30
|
|
|
if (lll->data_chan_count < CHM_USED_COUNT_MIN) {
|
2021-02-18 13:02:24 +05:30
|
|
|
return;
|
|
|
|
}
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
/* Reset ISO create BIG flag in the periodic advertising context */
|
|
|
|
sync_iso->sync->iso.sync_iso = NULL;
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
lll->phy = BIT(bi->chm_phy[4] >> 5);
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2023-10-18 08:50:21 +02:00
|
|
|
lll->num_bis = PDU_BIG_INFO_NUM_BIS_GET(bi);
|
|
|
|
lll->bn = PDU_BIG_INFO_BN_GET(bi);
|
|
|
|
lll->nse = PDU_BIG_INFO_NSE_GET(bi);
|
|
|
|
lll->sub_interval = PDU_BIG_INFO_SUB_INTERVAL_GET(bi);
|
2021-02-18 13:02:24 +05:30
|
|
|
lll->max_pdu = bi->max_pdu;
|
2023-10-18 08:50:21 +02:00
|
|
|
lll->pto = PDU_BIG_INFO_PTO_GET(bi);
|
2021-03-16 13:31:26 +05:30
|
|
|
if (lll->pto) {
|
|
|
|
lll->ptc = lll->bn;
|
|
|
|
} else {
|
|
|
|
lll->ptc = 0U;
|
|
|
|
}
|
2023-10-18 08:50:21 +02:00
|
|
|
lll->bis_spacing = PDU_BIG_INFO_SPACING_GET(bi);
|
|
|
|
lll->irc = PDU_BIG_INFO_IRC_GET(bi);
|
|
|
|
lll->sdu_interval = PDU_BIG_INFO_SDU_INTERVAL_GET(bi);
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2023-05-02 13:00:45 +05:30
|
|
|
/* Pick the 39-bit payload count, 1 MSb is framing bit */
|
2021-03-07 10:22:45 +05:30
|
|
|
lll->payload_count = (uint64_t)bi->payload_count_framing[0];
|
|
|
|
lll->payload_count |= (uint64_t)bi->payload_count_framing[1] << 8;
|
|
|
|
lll->payload_count |= (uint64_t)bi->payload_count_framing[2] << 16;
|
|
|
|
lll->payload_count |= (uint64_t)bi->payload_count_framing[3] << 24;
|
2023-05-02 13:00:45 +05:30
|
|
|
lll->payload_count |= (uint64_t)(bi->payload_count_framing[4] & 0x7f) << 32;
|
2024-02-12 15:41:47 +01:00
|
|
|
lll->framing = (bi->payload_count_framing[4] & 0x80) >> 7;
|
2021-03-07 10:22:45 +05:30
|
|
|
|
2024-02-23 15:33:42 +01:00
|
|
|
/* Set establishment event countdown */
|
|
|
|
lll->establish_events = CONN_ESTAB_COUNTDOWN;
|
|
|
|
|
2024-05-20 09:46:28 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
|
|
|
|
lll->enc && (bi_size == PDU_BIG_INFO_ENCRYPTED_SIZE)) {
|
2022-10-03 09:36:28 +05:30
|
|
|
const uint8_t BIG3[4] = {0x33, 0x47, 0x49, 0x42};
|
|
|
|
struct ccm *ccm_rx;
|
|
|
|
uint8_t gsk[16];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* Copy the GIV in BIGInfo */
|
|
|
|
(void)memcpy(lll->giv, bi->giv, sizeof(lll->giv));
|
|
|
|
|
|
|
|
/* Calculate GSK */
|
|
|
|
err = bt_crypto_h8(sync_iso->gltk, bi->gskd, BIG3, gsk);
|
|
|
|
LL_ASSERT(!err);
|
|
|
|
|
|
|
|
/* Prepare the CCM parameters */
|
|
|
|
ccm_rx = &lll->ccm_rx;
|
|
|
|
ccm_rx->direction = 1U;
|
|
|
|
(void)memcpy(&ccm_rx->iv[4], &lll->giv[4], 4U);
|
|
|
|
(void)mem_rcopy(ccm_rx->key, gsk, sizeof(ccm_rx->key));
|
|
|
|
|
|
|
|
/* NOTE: counter is filled in LLL */
|
|
|
|
} else {
|
|
|
|
lll->enc = 0U;
|
|
|
|
}
|
|
|
|
|
2021-03-16 13:31:26 +05:30
|
|
|
/* Initialize payload pointers */
|
|
|
|
lll->payload_count_max = PDU_BIG_PAYLOAD_COUNT_MAX;
|
|
|
|
lll->payload_tail = 0U;
|
2021-11-23 21:50:46 +05:30
|
|
|
for (int i = 0; i < CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX; i++) {
|
2023-09-26 22:41:33 +02:00
|
|
|
for (int j = 0; j < lll->payload_count_max; j++) {
|
2021-11-23 21:50:46 +05:30
|
|
|
lll->payload[i][j] = NULL;
|
|
|
|
}
|
2021-03-16 13:31:26 +05:30
|
|
|
}
|
|
|
|
|
2023-10-18 08:50:21 +02:00
|
|
|
lll->iso_interval = PDU_BIG_INFO_ISO_INTERVAL_GET(bi);
|
2022-02-16 11:00:11 +05:30
|
|
|
interval_us = lll->iso_interval * PERIODIC_INT_UNIT_US;
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
sync_iso->timeout_reload =
|
2021-11-16 13:04:21 +05:30
|
|
|
RADIO_SYNC_EVENTS((sync_iso->timeout * 10U * USEC_PER_MSEC),
|
2021-02-18 13:02:24 +05:30
|
|
|
interval_us);
|
|
|
|
|
|
|
|
sca = sync_iso->sync->lll.sca;
|
|
|
|
lll->window_widening_periodic_us =
|
2022-11-23 09:55:08 +01:00
|
|
|
DIV_ROUND_UP(((lll_clock_ppm_local_get() +
|
2021-11-17 10:55:13 +05:30
|
|
|
lll_clock_ppm_get(sca)) *
|
|
|
|
interval_us), USEC_PER_SEC);
|
2021-02-18 13:02:24 +05:30
|
|
|
lll->window_widening_max_us = (interval_us >> 1) - EVENT_IFS_US;
|
2023-10-18 08:50:21 +02:00
|
|
|
if (PDU_BIG_INFO_OFFS_UNITS_GET(bi)) {
|
2021-11-16 13:04:21 +05:30
|
|
|
lll->window_size_event_us = OFFS_UNIT_300_US;
|
2021-02-18 13:02:24 +05:30
|
|
|
} else {
|
2021-11-16 13:04:21 +05:30
|
|
|
lll->window_size_event_us = OFFS_UNIT_30_US;
|
2021-02-18 13:02:24 +05:30
|
|
|
}
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
ftr = &node_rx->rx_ftr;
|
|
|
|
pdu = (void *)((struct node_rx_pdu *)node_rx)->pdu;
|
|
|
|
|
2021-11-16 13:04:21 +05:30
|
|
|
ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);
|
2021-02-18 13:02:24 +05:30
|
|
|
|
2022-11-17 08:47:10 +05:30
|
|
|
/* Calculate the BIG Offset in microseconds */
|
2021-02-18 13:02:24 +05:30
|
|
|
sync_iso_offset_us = ftr->radio_end_us;
|
2023-10-18 08:50:21 +02:00
|
|
|
sync_iso_offset_us += PDU_BIG_INFO_OFFS_GET(bi) *
|
2021-11-16 13:00:47 +05:30
|
|
|
lll->window_size_event_us;
|
2022-11-17 08:47:10 +05:30
|
|
|
/* Skip to first selected BIS subevent */
|
|
|
|
/* FIXME: add support for interleaved packing */
|
|
|
|
stream = ull_sync_iso_stream_get(lll->stream_handle[0]);
|
|
|
|
sync_iso_offset_us += (stream->bis_index - 1U) * lll->sub_interval *
|
|
|
|
((lll->irc * lll->bn) + lll->ptc);
|
|
|
|
sync_iso_offset_us -= PDU_AC_US(pdu->len, sync_iso->sync->lll.phy,
|
|
|
|
ftr->phy_flags);
|
2021-03-15 13:24:54 +05:30
|
|
|
sync_iso_offset_us -= EVENT_TICKER_RES_MARGIN_US;
|
2021-02-18 13:02:24 +05:30
|
|
|
sync_iso_offset_us -= EVENT_JITTER_US;
|
|
|
|
sync_iso_offset_us -= ready_delay_us;
|
|
|
|
|
|
|
|
interval_us -= lll->window_widening_periodic_us;
|
|
|
|
|
2023-02-12 18:01:10 +05:30
|
|
|
/* Calculate ISO Receiver BIG event timings */
|
|
|
|
pdu_spacing = PDU_BIS_US(lll->max_pdu, lll->enc, lll->phy,
|
|
|
|
PHY_FLAGS_S8) +
|
|
|
|
EVENT_MSS_US;
|
|
|
|
ctrl_spacing = PDU_BIS_US(sizeof(struct pdu_big_ctrl), lll->enc,
|
|
|
|
lll->phy, PHY_FLAGS_S8);
|
|
|
|
|
|
|
|
/* Number of maximum BISes to sync from the first BIS to sync */
|
|
|
|
/* NOTE: When ULL scheduling is implemented for subevents, then update
|
|
|
|
* the time reservation as required.
|
|
|
|
*/
|
|
|
|
num_bis = lll->num_bis - (stream->bis_index - 1U);
|
|
|
|
|
|
|
|
/* 1. Maximum PDU transmission time in 1M/2M/S8 PHY is 17040 us, or
|
|
|
|
* represented in 15-bits.
|
|
|
|
* 2. NSE in the range 1 to 31 is represented in 5-bits
|
|
|
|
* 3. num_bis in the range 1 to 31 is represented in 5-bits
|
|
|
|
*
|
|
|
|
* Hence, worst case event time can be represented in 25-bits plus
|
|
|
|
* one each bit for added ctrl_spacing and radio event overheads. I.e.
|
|
|
|
* 27-bits required and sufficiently covered by using 32-bit data type
|
|
|
|
* for time_us.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_ISO_RESERVE_MAX)) {
|
|
|
|
/* Maximum time reservation for both sequential and interleaved
|
|
|
|
* packing.
|
|
|
|
*/
|
|
|
|
slot_us = (pdu_spacing * lll->nse * num_bis) + ctrl_spacing;
|
|
|
|
|
|
|
|
} else if (lll->bis_spacing >= (lll->sub_interval * lll->nse)) {
|
2024-02-21 00:24:09 +07:00
|
|
|
/* Time reservation omitting PTC subevents in sequential
|
2023-02-12 18:01:10 +05:30
|
|
|
* packing.
|
|
|
|
*/
|
|
|
|
slot_us = pdu_spacing * ((lll->nse * num_bis) - lll->ptc);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* Time reservation omitting PTC subevents in interleaved
|
|
|
|
* packing.
|
|
|
|
*/
|
|
|
|
slot_us = pdu_spacing * ((lll->nse - lll->ptc) * num_bis);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add radio ready delay */
|
|
|
|
slot_us += ready_delay_us;
|
|
|
|
|
|
|
|
/* Add implementation defined radio event overheads */
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX)) {
|
|
|
|
slot_us += EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US;
|
|
|
|
}
|
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
/* TODO: active_to_start feature port */
|
|
|
|
sync_iso->ull.ticks_active_to_start = 0U;
|
|
|
|
sync_iso->ull.ticks_prepare_to_start =
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
|
|
|
|
sync_iso->ull.ticks_preempt_to_start =
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
|
2023-02-12 18:01:10 +05:30
|
|
|
sync_iso->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(slot_us);
|
2021-02-18 13:02:24 +05:30
|
|
|
|
|
|
|
ticks_slot_offset = MAX(sync_iso->ull.ticks_active_to_start,
|
|
|
|
sync_iso->ull.ticks_prepare_to_start);
|
2020-11-12 14:49:18 +01:00
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
|
|
|
|
ticks_slot_overhead = ticks_slot_offset;
|
|
|
|
} else {
|
|
|
|
ticks_slot_overhead = 0U;
|
|
|
|
}
|
2021-05-18 10:41:03 +05:30
|
|
|
ticks_slot_offset += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2023-02-07 08:21:22 +05:30
|
|
|
/* Check and skip to next interval if CPU processing introduces latency
|
|
|
|
* that can delay scheduling the first ISO event.
|
|
|
|
*/
|
|
|
|
ticks_expire = ftr->ticks_anchor - ticks_slot_offset +
|
|
|
|
HAL_TICKER_US_TO_TICKS(sync_iso_offset_us);
|
|
|
|
ticks_threshold = ticker_ticks_now_get() +
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
|
|
|
|
ticks_diff = ticker_ticks_diff_get(ticks_expire, ticks_threshold);
|
|
|
|
if (ticks_diff & BIT(HAL_TICKER_CNTR_MSBIT)) {
|
|
|
|
sync_iso_offset_us += interval_us -
|
|
|
|
lll->window_widening_periodic_us;
|
|
|
|
lll->window_widening_event_us +=
|
|
|
|
lll->window_widening_periodic_us;
|
|
|
|
lll->payload_count += lll->bn;
|
|
|
|
}
|
|
|
|
|
2021-02-18 13:02:24 +05:30
|
|
|
/* setup to use ISO create prepare function until sync established */
|
|
|
|
mfy_lll_prepare.fp = lll_sync_iso_create_prepare;
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
handle = sync_iso_handle_get(sync_iso);
|
2020-11-12 14:49:18 +01:00
|
|
|
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
2024-03-11 14:41:21 +01:00
|
|
|
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
|
|
|
sync_iso_handle_to_index(handle)),
|
2020-11-12 14:49:18 +01:00
|
|
|
ftr->ticks_anchor - ticks_slot_offset,
|
2021-02-18 13:02:24 +05:30
|
|
|
HAL_TICKER_US_TO_TICKS(sync_iso_offset_us),
|
2020-11-12 14:49:18 +01:00
|
|
|
HAL_TICKER_US_TO_TICKS(interval_us),
|
|
|
|
HAL_TICKER_REMAINDER(interval_us),
|
2021-11-29 12:29:08 +05:30
|
|
|
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
|
|
|
|
!defined(CONFIG_BT_CTLR_LOW_LAT)
|
|
|
|
TICKER_LAZY_MUST_EXPIRE,
|
|
|
|
#else
|
2020-11-12 14:49:18 +01:00
|
|
|
TICKER_NULL_LAZY,
|
2021-11-29 12:29:08 +05:30
|
|
|
#endif /* !CONFIG_BT_TICKER_LOW_LAT && !CONFIG_BT_CTLR_LOW_LAT */
|
2021-02-18 13:02:24 +05:30
|
|
|
(sync_iso->ull.ticks_slot + ticks_slot_overhead),
|
2021-02-09 12:06:13 +05:30
|
|
|
ticker_cb, sync_iso,
|
|
|
|
ticker_start_op_cb, (void *)__LINE__);
|
2020-11-12 14:49:18 +01:00
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
2020-11-09 16:31:01 +01:00
|
|
|
}
|
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
void ull_sync_iso_estab_done(struct node_rx_event_done *done)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
2021-02-26 13:21:24 +05:30
|
|
|
struct node_rx_sync_iso *se;
|
|
|
|
struct node_rx_pdu *rx;
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2024-02-23 15:33:42 +01:00
|
|
|
if (done->extra.trx_cnt || done->extra.estab_failed) {
|
|
|
|
/* Switch to normal prepare */
|
|
|
|
mfy_lll_prepare.fp = lll_sync_iso_prepare;
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2024-02-23 15:33:42 +01:00
|
|
|
/* Get reference to ULL context */
|
|
|
|
sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2024-02-23 15:33:42 +01:00
|
|
|
/* Prepare BIG Sync Established */
|
|
|
|
rx = (void *)sync_iso->sync->iso.node_rx_estab;
|
|
|
|
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
|
|
|
|
rx->hdr.handle = sync_iso_handle_get(sync_iso);
|
|
|
|
rx->rx_ftr.param = sync_iso;
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2024-08-17 03:28:12 +02:00
|
|
|
/* status value is stored in the PDU member of the node rx */
|
2024-02-23 15:33:42 +01:00
|
|
|
se = (void *)rx->pdu;
|
2024-08-17 03:28:12 +02:00
|
|
|
if (done->extra.estab_failed) {
|
|
|
|
if (sync_iso->lll.term_reason != BT_HCI_ERR_SUCCESS) {
|
|
|
|
se->status = sync_iso->lll.term_reason;
|
|
|
|
} else {
|
|
|
|
se->status = BT_HCI_ERR_CONN_FAIL_TO_ESTAB;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
se->status = BT_HCI_ERR_SUCCESS;
|
|
|
|
}
|
2021-02-26 13:21:24 +05:30
|
|
|
|
2024-02-23 15:33:42 +01:00
|
|
|
ll_rx_put_sched(rx->hdr.link, rx);
|
|
|
|
}
|
2021-02-09 12:06:13 +05:30
|
|
|
|
|
|
|
ull_sync_iso_done(done);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ull_sync_iso_done(struct node_rx_event_done *done)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
uint32_t ticks_drift_minus;
|
|
|
|
uint32_t ticks_drift_plus;
|
|
|
|
struct lll_sync_iso *lll;
|
|
|
|
uint16_t elapsed_event;
|
|
|
|
uint16_t latency_event;
|
|
|
|
uint16_t lazy;
|
|
|
|
uint8_t force;
|
|
|
|
|
|
|
|
/* Get reference to ULL context */
|
|
|
|
sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
|
|
|
|
lll = &sync_iso->lll;
|
|
|
|
|
|
|
|
/* Events elapsed used in timeout checks below */
|
|
|
|
latency_event = lll->latency_event;
|
2022-09-08 07:21:14 +05:30
|
|
|
if (lll->latency_prepare) {
|
|
|
|
elapsed_event = latency_event + lll->latency_prepare;
|
|
|
|
} else {
|
|
|
|
elapsed_event = latency_event + 1U;
|
|
|
|
}
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2024-05-30 15:14:21 +02:00
|
|
|
/* Check for establishmet failure */
|
|
|
|
if (done->extra.estab_failed) {
|
|
|
|
uint8_t handle;
|
|
|
|
uint32_t ret;
|
|
|
|
|
|
|
|
/* Stop Sync ISO Ticker directly. Establishment failure has been
|
|
|
|
* notified.
|
|
|
|
*/
|
|
|
|
handle = sync_iso_handle_get(sync_iso);
|
|
|
|
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
|
|
|
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
|
|
|
sync_iso_handle_to_index(handle)), NULL, NULL);
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
/* Sync drift compensation and new skip calculation
|
|
|
|
*/
|
|
|
|
ticks_drift_plus = 0U;
|
|
|
|
ticks_drift_minus = 0U;
|
|
|
|
if (done->extra.trx_cnt) {
|
|
|
|
/* Calculate drift in ticks unit */
|
|
|
|
ull_drift_ticks_get(done, &ticks_drift_plus,
|
|
|
|
&ticks_drift_minus);
|
|
|
|
|
|
|
|
/* Reset latency */
|
|
|
|
lll->latency_event = 0U;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset supervision countdown */
|
|
|
|
if (done->extra.crc_valid) {
|
|
|
|
sync_iso->timeout_expire = 0U;
|
2021-11-16 13:04:21 +05:30
|
|
|
} else {
|
|
|
|
/* if anchor point not sync-ed, start timeout countdown */
|
2021-02-09 12:06:13 +05:30
|
|
|
if (!sync_iso->timeout_expire) {
|
|
|
|
sync_iso->timeout_expire = sync_iso->timeout_reload;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check timeout */
|
|
|
|
force = 0U;
|
|
|
|
if (sync_iso->timeout_expire) {
|
|
|
|
if (sync_iso->timeout_expire > elapsed_event) {
|
|
|
|
sync_iso->timeout_expire -= elapsed_event;
|
|
|
|
|
|
|
|
/* break skip */
|
|
|
|
lll->latency_event = 0U;
|
|
|
|
|
|
|
|
if (latency_event) {
|
|
|
|
force = 1U;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
timeout_cleanup(sync_iso);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if skip needs update */
|
|
|
|
lazy = 0U;
|
2021-11-16 13:04:21 +05:30
|
|
|
if (force || (latency_event != lll->latency_event)) {
|
2021-02-09 12:06:13 +05:30
|
|
|
lazy = lll->latency_event + 1U;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update Sync ticker instance */
|
|
|
|
if (ticks_drift_plus || ticks_drift_minus || lazy || force) {
|
2021-11-23 21:34:04 +05:30
|
|
|
uint8_t handle = sync_iso_handle_get(sync_iso);
|
2021-02-09 12:06:13 +05:30
|
|
|
uint32_t ticker_status;
|
|
|
|
|
|
|
|
/* Call to ticker_update can fail under the race
|
|
|
|
* condition where in the periodic sync role is being stopped
|
|
|
|
* but at the same time it is preempted by periodic sync event
|
|
|
|
* that gets into close state. Accept failure when periodic sync
|
|
|
|
* role is being stopped.
|
|
|
|
*/
|
|
|
|
ticker_status = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
|
|
|
TICKER_USER_ID_ULL_HIGH,
|
|
|
|
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
2024-03-11 14:41:21 +01:00
|
|
|
sync_iso_handle_to_index(handle)),
|
2021-02-09 12:06:13 +05:30
|
|
|
ticks_drift_plus,
|
2021-11-16 13:04:21 +05:30
|
|
|
ticks_drift_minus, 0U, 0U,
|
2021-02-09 12:06:13 +05:30
|
|
|
lazy, force,
|
|
|
|
ticker_update_op_cb,
|
|
|
|
sync_iso);
|
|
|
|
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ticker_status == TICKER_STATUS_BUSY) ||
|
|
|
|
((void *)sync_iso == ull_disable_mark_get()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-05 12:00:13 +05:30
|
|
|
void ull_sync_iso_done_terminate(struct node_rx_event_done *done)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
struct lll_sync_iso *lll;
|
|
|
|
struct node_rx_pdu *rx;
|
|
|
|
uint8_t handle;
|
|
|
|
uint32_t ret;
|
|
|
|
|
|
|
|
/* Get reference to ULL context */
|
|
|
|
sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
|
|
|
|
lll = &sync_iso->lll;
|
|
|
|
|
|
|
|
/* Populate the Sync Lost which will be enqueued in disabled_cb */
|
|
|
|
rx = (void *)&sync_iso->node_rx_lost;
|
2021-11-23 21:34:04 +05:30
|
|
|
rx->hdr.handle = sync_iso_handle_get(sync_iso);
|
2021-05-05 12:00:13 +05:30
|
|
|
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
|
2024-04-05 15:00:44 +02:00
|
|
|
rx->rx_ftr.param = sync_iso;
|
2021-05-05 12:00:13 +05:30
|
|
|
*((uint8_t *)rx->pdu) = lll->term_reason;
|
|
|
|
|
|
|
|
/* Stop Sync ISO Ticker */
|
2021-11-23 21:34:04 +05:30
|
|
|
handle = sync_iso_handle_get(sync_iso);
|
2021-05-05 12:00:13 +05:30
|
|
|
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
2024-03-11 14:41:21 +01:00
|
|
|
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
|
|
|
sync_iso_handle_to_index(handle)),
|
2021-05-05 12:00:13 +05:30
|
|
|
ticker_stop_op_cb, (void *)sync_iso);
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
|
|
|
}
|
|
|
|
|
2024-03-11 15:12:00 +01:00
|
|
|
static void disable(uint8_t sync_idx)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
sync_iso = &ll_sync_iso[sync_idx];
|
|
|
|
|
|
|
|
err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
|
|
|
sync_idx, sync_iso, &sync_iso->lll);
|
2024-05-06 12:50:11 +02:00
|
|
|
LL_ASSERT_INFO2(err == 0 || err == -EALREADY, sync_idx, err);
|
2024-03-11 15:12:00 +01:00
|
|
|
}
|
|
|
|
|
2020-11-09 16:31:01 +01:00
|
|
|
static int init_reset(void)
|
|
|
|
{
|
2024-03-11 15:12:00 +01:00
|
|
|
uint8_t idx;
|
|
|
|
|
|
|
|
/* Disable all active BIGs (uses blocking ull_ticker_stop_with_mark) */
|
|
|
|
for (idx = 0U; idx < CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET; idx++) {
|
|
|
|
disable(idx);
|
|
|
|
}
|
2021-11-23 21:34:04 +05:30
|
|
|
|
|
|
|
mem_init((void *)stream_pool, sizeof(struct lll_sync_iso_stream),
|
|
|
|
CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT, &stream_free);
|
2020-11-09 16:31:01 +01:00
|
|
|
|
2024-03-11 15:12:00 +01:00
|
|
|
memset(&ll_sync_iso, 0, sizeof(ll_sync_iso));
|
|
|
|
|
|
|
|
/* Initialize LLL */
|
|
|
|
return lll_sync_iso_init();
|
2020-11-09 16:31:01 +01:00
|
|
|
}
|
|
|
|
|
2021-11-23 21:34:04 +05:30
|
|
|
static struct ll_sync_iso_set *sync_iso_get(uint8_t handle)
|
|
|
|
{
|
2024-03-11 14:41:21 +01:00
|
|
|
for (uint8_t idx = 0; idx < CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET; idx++) {
|
|
|
|
if (ll_sync_iso[idx].sync && ll_sync_iso[idx].big_handle == handle) {
|
|
|
|
return &ll_sync_iso[idx];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ll_sync_iso_set *sync_iso_alloc(uint8_t handle)
|
|
|
|
{
|
|
|
|
for (uint8_t idx = 0; idx < CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET; idx++) {
|
|
|
|
if (!ll_sync_iso[idx].sync) {
|
|
|
|
ll_sync_iso[idx].big_handle = handle;
|
|
|
|
return &ll_sync_iso[idx];
|
|
|
|
}
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
2024-03-11 14:41:21 +01:00
|
|
|
return NULL;
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t sync_iso_handle_get(struct ll_sync_iso_set *sync)
|
|
|
|
{
|
2024-03-11 14:41:21 +01:00
|
|
|
return sync->big_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t sync_iso_handle_to_index(uint8_t handle)
|
|
|
|
{
|
|
|
|
return ARRAY_INDEX(ll_sync_iso, sync_iso_get(handle));
|
2021-11-23 21:34:04 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
static struct stream *sync_iso_stream_acquire(void)
|
|
|
|
{
|
|
|
|
return mem_acquire(&stream_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint16_t sync_iso_stream_handle_get(struct lll_sync_iso_stream *stream)
|
2020-11-09 16:31:01 +01:00
|
|
|
{
|
2021-11-23 21:34:04 +05:30
|
|
|
return mem_index_get(stream, stream_pool, sizeof(*stream));
|
2020-10-02 14:29:47 +02:00
|
|
|
}
|
2020-11-12 14:49:18 +01:00
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
static void timeout_cleanup(struct ll_sync_iso_set *sync_iso)
|
|
|
|
{
|
2021-05-05 12:00:13 +05:30
|
|
|
struct node_rx_pdu *rx;
|
|
|
|
uint8_t handle;
|
2021-02-09 12:06:13 +05:30
|
|
|
uint32_t ret;
|
|
|
|
|
2021-05-05 12:00:13 +05:30
|
|
|
/* Populate the Sync Lost which will be enqueued in disabled_cb */
|
|
|
|
rx = (void *)&sync_iso->node_rx_lost;
|
2021-11-23 21:34:04 +05:30
|
|
|
rx->hdr.handle = sync_iso_handle_get(sync_iso);
|
2024-04-05 15:00:44 +02:00
|
|
|
rx->rx_ftr.param = sync_iso;
|
2024-02-23 15:33:42 +01:00
|
|
|
|
|
|
|
if (mfy_lll_prepare.fp == lll_sync_iso_prepare) {
|
|
|
|
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
|
|
|
|
*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_TIMEOUT;
|
|
|
|
} else {
|
|
|
|
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
|
|
|
|
*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_FAIL_TO_ESTAB;
|
|
|
|
}
|
2021-04-15 11:24:21 +05:30
|
|
|
|
2021-05-05 12:00:13 +05:30
|
|
|
/* Stop Sync ISO Ticker */
|
2021-11-23 21:34:04 +05:30
|
|
|
handle = sync_iso_handle_get(sync_iso);
|
2021-02-09 12:06:13 +05:30
|
|
|
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
2024-03-11 14:41:21 +01:00
|
|
|
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
|
|
|
sync_iso_handle_to_index(handle)),
|
2021-02-09 12:06:13 +05:30
|
|
|
ticker_stop_op_cb, (void *)sync_iso);
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
|
|
|
}
|
|
|
|
|
2021-09-15 11:48:21 +05:30
|
|
|
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
|
|
|
uint32_t remainder, uint16_t lazy, uint8_t force,
|
|
|
|
void *param)
|
2020-11-12 14:49:18 +01:00
|
|
|
{
|
|
|
|
static struct lll_prepare_param p;
|
2021-04-15 11:24:21 +05:30
|
|
|
struct ll_sync_iso_set *sync_iso;
|
2021-02-18 13:02:24 +05:30
|
|
|
struct lll_sync_iso *lll;
|
2020-11-12 14:49:18 +01:00
|
|
|
uint32_t ret;
|
|
|
|
uint8_t ref;
|
|
|
|
|
|
|
|
DEBUG_RADIO_PREPARE_O(1);
|
|
|
|
|
2021-11-29 12:29:08 +05:30
|
|
|
if (!IS_ENABLED(CONFIG_BT_TICKER_LOW_LAT) &&
|
|
|
|
!IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) &&
|
|
|
|
(lazy == TICKER_LAZY_MUST_EXPIRE)) {
|
|
|
|
/* FIXME: generate ISO PDU with status set to invalid */
|
|
|
|
|
|
|
|
DEBUG_RADIO_PREPARE_O(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-04-15 11:24:21 +05:30
|
|
|
sync_iso = param;
|
2021-02-18 13:02:24 +05:30
|
|
|
lll = &sync_iso->lll;
|
2020-11-12 14:49:18 +01:00
|
|
|
|
|
|
|
/* Increment prepare reference count */
|
2021-02-18 13:02:24 +05:30
|
|
|
ref = ull_ref_inc(&sync_iso->ull);
|
2020-11-12 14:49:18 +01:00
|
|
|
LL_ASSERT(ref);
|
|
|
|
|
|
|
|
/* Append timing parameters */
|
|
|
|
p.ticks_at_expire = ticks_at_expire;
|
|
|
|
p.remainder = remainder;
|
|
|
|
p.lazy = lazy;
|
2021-03-03 15:41:55 +01:00
|
|
|
p.force = force;
|
2020-11-12 14:49:18 +01:00
|
|
|
p.param = lll;
|
2021-02-18 13:02:24 +05:30
|
|
|
mfy_lll_prepare.param = &p;
|
2020-11-12 14:49:18 +01:00
|
|
|
|
|
|
|
/* Kick LLL prepare */
|
2021-11-16 13:04:21 +05:30
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0U,
|
2021-02-18 13:02:24 +05:30
|
|
|
&mfy_lll_prepare);
|
2020-11-12 14:49:18 +01:00
|
|
|
LL_ASSERT(!ret);
|
|
|
|
|
|
|
|
DEBUG_RADIO_PREPARE_O(1);
|
|
|
|
}
|
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
static void ticker_start_op_cb(uint32_t status, void *param)
|
2020-11-12 14:49:18 +01:00
|
|
|
{
|
|
|
|
ARG_UNUSED(param);
|
|
|
|
|
|
|
|
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
|
|
|
|
}
|
2021-02-09 12:06:13 +05:30
|
|
|
|
|
|
|
static void ticker_update_op_cb(uint32_t status, void *param)
|
|
|
|
{
|
|
|
|
LL_ASSERT(status == TICKER_STATUS_SUCCESS ||
|
|
|
|
param == ull_disable_mark_get());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ticker_stop_op_cb(uint32_t status, void *param)
|
|
|
|
{
|
|
|
|
static memq_link_t link;
|
2021-11-16 13:04:21 +05:30
|
|
|
static struct mayfly mfy = {0U, 0U, &link, NULL, sync_iso_disable};
|
2021-08-16 16:50:07 +05:30
|
|
|
uint32_t ret;
|
2021-02-09 12:06:13 +05:30
|
|
|
|
|
|
|
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
/* Check if any pending LLL events that need to be aborted */
|
|
|
|
mfy.param = param;
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
|
2021-11-16 13:04:21 +05:30
|
|
|
TICKER_USER_ID_ULL_HIGH, 0U, &mfy);
|
2021-08-16 16:50:07 +05:30
|
|
|
LL_ASSERT(!ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sync_iso_disable(void *param)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
struct ull_hdr *hdr;
|
|
|
|
|
|
|
|
/* Check ref count to determine if any pending LLL events in pipeline */
|
2021-04-15 11:24:21 +05:30
|
|
|
sync_iso = param;
|
|
|
|
hdr = &sync_iso->ull;
|
|
|
|
if (ull_ref_get(hdr)) {
|
2021-08-16 16:50:07 +05:30
|
|
|
static memq_link_t link;
|
2021-11-16 13:04:21 +05:30
|
|
|
static struct mayfly mfy = {0U, 0U, &link, NULL, lll_disable};
|
2021-04-15 11:24:21 +05:30
|
|
|
uint32_t ret;
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
mfy.param = &sync_iso->lll;
|
|
|
|
|
|
|
|
/* Setup disabled callback to be called when ref count
|
|
|
|
* returns to zero.
|
|
|
|
*/
|
2021-04-15 11:24:21 +05:30
|
|
|
LL_ASSERT(!hdr->disabled_cb);
|
|
|
|
hdr->disabled_param = mfy.param;
|
|
|
|
hdr->disabled_cb = disabled_cb;
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
/* Trigger LLL disable */
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
2021-11-16 13:04:21 +05:30
|
|
|
TICKER_USER_ID_LLL, 0U, &mfy);
|
2021-04-15 11:24:21 +05:30
|
|
|
LL_ASSERT(!ret);
|
|
|
|
} else {
|
2021-08-16 16:50:07 +05:30
|
|
|
/* No pending LLL events */
|
|
|
|
disabled_cb(&sync_iso->lll);
|
2021-04-15 11:24:21 +05:30
|
|
|
}
|
2021-02-09 12:06:13 +05:30
|
|
|
}
|
|
|
|
|
2024-07-09 15:57:39 +02:00
|
|
|
static void lll_flush(void *param)
|
|
|
|
{
|
|
|
|
struct ll_sync_iso_set *sync_iso;
|
|
|
|
uint8_t handle;
|
|
|
|
|
|
|
|
/* Get reference to ULL context */
|
|
|
|
sync_iso = HDR_LLL2ULL(param);
|
|
|
|
handle = sync_iso_handle_get(sync_iso);
|
|
|
|
|
|
|
|
lll_sync_iso_flush(handle, param);
|
|
|
|
|
|
|
|
if (sync_iso->flush_sem) {
|
|
|
|
k_sem_give(sync_iso->flush_sem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-15 11:24:21 +05:30
|
|
|
static void disabled_cb(void *param)
|
2021-02-09 12:06:13 +05:30
|
|
|
{
|
2024-07-09 15:57:39 +02:00
|
|
|
static memq_link_t mfy_link;
|
|
|
|
static struct mayfly mfy = {0U, 0U, &mfy_link, NULL, lll_flush};
|
2021-04-15 11:24:21 +05:30
|
|
|
struct ll_sync_iso_set *sync_iso;
|
2021-02-09 12:06:13 +05:30
|
|
|
struct node_rx_pdu *rx;
|
2021-05-05 12:00:13 +05:30
|
|
|
memq_link_t *link;
|
2024-07-09 15:57:39 +02:00
|
|
|
uint32_t ret;
|
2021-02-09 12:06:13 +05:30
|
|
|
|
2021-04-15 11:24:21 +05:30
|
|
|
/* Get reference to ULL context */
|
|
|
|
sync_iso = HDR_LLL2ULL(param);
|
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
/* Generate BIG sync lost */
|
|
|
|
rx = (void *)&sync_iso->node_rx_lost;
|
2021-05-05 12:00:13 +05:30
|
|
|
LL_ASSERT(rx->hdr.link);
|
|
|
|
link = rx->hdr.link;
|
|
|
|
rx->hdr.link = NULL;
|
2021-02-26 13:21:24 +05:30
|
|
|
|
2021-02-09 12:06:13 +05:30
|
|
|
/* Enqueue the BIG sync lost towards ULL context */
|
2022-11-15 09:31:44 +01:00
|
|
|
ll_rx_put_sched(link, rx);
|
2024-07-09 15:57:39 +02:00
|
|
|
|
|
|
|
mfy.param = param;
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
|
|
|
TICKER_USER_ID_LLL, 0U, &mfy);
|
|
|
|
LL_ASSERT(!ret);
|
2021-02-09 12:06:13 +05:30
|
|
|
}
|