Bluetooth: controller: Allow any valid ISO sync receiver BIG handle
The BIG handle for an ISO sync receiver is provided by the host. The valid range is [0x00..0xEF], and this requires the controller to allow non-consecutive handle numbering. This means that even if only one sync set is supported, a BIG handle of ex. value 2 must be supported. As the code uses indexing and range checking directly by handle, this needs to be changed. Introducing the handle index, which sequnces the handles such that index = 0 is always the "first handle", regardless of value. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
ffe79b5522
commit
06870146e6
4 changed files with 50 additions and 24 deletions
|
@ -90,7 +90,7 @@ int lll_sync_iso_reset(void);
|
|||
void lll_sync_iso_create_prepare(void *param);
|
||||
void lll_sync_iso_prepare(void *param);
|
||||
|
||||
extern uint8_t ull_sync_iso_lll_handle_get(struct lll_sync_iso *lll);
|
||||
extern uint8_t ull_sync_iso_lll_index_get(struct lll_sync_iso *lll);
|
||||
extern struct lll_sync_iso_stream *ull_sync_iso_lll_stream_get(uint16_t handle);
|
||||
extern void ll_iso_rx_put(memq_link_t *link, void *rx);
|
||||
extern void ll_rx_sched(void);
|
||||
|
|
|
@ -375,7 +375,7 @@ static int prepare_cb_common(struct lll_prepare_param *p)
|
|||
uint32_t overhead;
|
||||
|
||||
overhead = lll_preempt_calc(ull, (TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
ull_sync_iso_lll_handle_get(lll)), ticks_at_event);
|
||||
ull_sync_iso_lll_index_get(lll)), ticks_at_event);
|
||||
/* check if preempt to start has changed */
|
||||
if (overhead) {
|
||||
LL_ASSERT_OVERHEAD(overhead);
|
||||
|
|
|
@ -52,7 +52,9 @@
|
|||
|
||||
static int init_reset(void);
|
||||
static struct ll_sync_iso_set *sync_iso_get(uint8_t handle);
|
||||
static struct ll_sync_iso_set *sync_iso_alloc(uint8_t handle);
|
||||
static uint8_t sync_iso_handle_get(struct ll_sync_iso_set *sync);
|
||||
static uint8_t sync_iso_handle_to_index(uint8_t handle);
|
||||
static struct stream *sync_iso_stream_acquire(void);
|
||||
static uint16_t sync_iso_stream_handle_get(struct lll_sync_iso_stream *stream);
|
||||
static void timeout_cleanup(struct ll_sync_iso_set *sync_iso);
|
||||
|
@ -89,23 +91,23 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
|
|||
int8_t last_index;
|
||||
|
||||
sync = ull_sync_is_enabled_get(sync_handle);
|
||||
if (!sync || sync->iso.sync_iso) {
|
||||
if (!sync) {
|
||||
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
||||
}
|
||||
|
||||
if (sync->iso.sync_iso) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
sync_iso = sync_iso_get(big_handle);
|
||||
if (!sync_iso) {
|
||||
/* Host requested more than supported number of ISO Synchronized
|
||||
* Receivers.
|
||||
* Or probably HCI handles where not translated to zero-indexed
|
||||
* controller handles?
|
||||
*/
|
||||
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
||||
if (sync_iso) {
|
||||
/* BIG handle already in use */
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
/* Check if this ISO already is associated with a Periodic Sync */
|
||||
if (sync_iso->sync) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
sync_iso = sync_iso_alloc(big_handle);
|
||||
if (!sync_iso) {
|
||||
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* TODO: Check remaining parameters */
|
||||
|
@ -269,7 +271,8 @@ uint8_t ll_big_sync_terminate(uint8_t big_handle, void **rx)
|
|||
}
|
||||
|
||||
err = ull_ticker_stop_with_mark((TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
big_handle), sync_iso, &sync_iso->lll);
|
||||
sync_iso_handle_to_index(big_handle)),
|
||||
sync_iso, &sync_iso->lll);
|
||||
LL_ASSERT_INFO2(err == 0 || err == -EALREADY, big_handle, err);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
|
@ -307,9 +310,9 @@ int ull_sync_iso_reset(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ull_sync_iso_lll_handle_get(struct lll_sync_iso *lll)
|
||||
uint8_t ull_sync_iso_lll_index_get(struct lll_sync_iso *lll)
|
||||
{
|
||||
return sync_iso_handle_get(HDR_LLL2ULL(lll));
|
||||
return ARRAY_INDEX(ll_sync_iso, HDR_LLL2ULL(lll));
|
||||
}
|
||||
|
||||
struct ll_sync_iso_set *ull_sync_iso_by_stream_get(uint16_t handle)
|
||||
|
@ -630,7 +633,8 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso,
|
|||
|
||||
handle = sync_iso_handle_get(sync_iso);
|
||||
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
||||
(TICKER_ID_SCAN_SYNC_ISO_BASE + handle),
|
||||
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
sync_iso_handle_to_index(handle)),
|
||||
ftr->ticks_anchor - ticks_slot_offset,
|
||||
HAL_TICKER_US_TO_TICKS(sync_iso_offset_us),
|
||||
HAL_TICKER_US_TO_TICKS(interval_us),
|
||||
|
@ -762,7 +766,7 @@ void ull_sync_iso_done(struct node_rx_event_done *done)
|
|||
ticker_status = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
||||
TICKER_USER_ID_ULL_HIGH,
|
||||
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
handle),
|
||||
sync_iso_handle_to_index(handle)),
|
||||
ticks_drift_plus,
|
||||
ticks_drift_minus, 0U, 0U,
|
||||
lazy, force,
|
||||
|
@ -796,7 +800,8 @@ void ull_sync_iso_done_terminate(struct node_rx_event_done *done)
|
|||
/* Stop Sync ISO Ticker */
|
||||
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 + handle),
|
||||
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
sync_iso_handle_to_index(handle)),
|
||||
ticker_stop_op_cb, (void *)sync_iso);
|
||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
||||
(ret == TICKER_STATUS_BUSY));
|
||||
|
@ -846,16 +851,35 @@ static int init_reset(void)
|
|||
|
||||
static struct ll_sync_iso_set *sync_iso_get(uint8_t handle)
|
||||
{
|
||||
if (handle >= CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET) {
|
||||
return NULL;
|
||||
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 &ll_sync_iso[handle];
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t sync_iso_handle_get(struct ll_sync_iso_set *sync)
|
||||
{
|
||||
return mem_index_get(sync, ll_sync_iso, sizeof(*sync));
|
||||
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));
|
||||
}
|
||||
|
||||
static struct stream *sync_iso_stream_acquire(void)
|
||||
|
@ -890,7 +914,8 @@ static void timeout_cleanup(struct ll_sync_iso_set *sync_iso)
|
|||
/* Stop Sync ISO Ticker */
|
||||
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 + handle),
|
||||
(TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
sync_iso_handle_to_index(handle)),
|
||||
ticker_stop_op_cb, (void *)sync_iso);
|
||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
||||
(ret == TICKER_STATUS_BUSY));
|
||||
|
|
|
@ -115,6 +115,7 @@ struct ll_sync_iso_set {
|
|||
uint16_t timeout;
|
||||
uint16_t volatile timeout_reload; /* Non-zero when sync established */
|
||||
uint16_t timeout_expire; /* timeout countdown */
|
||||
uint8_t big_handle;
|
||||
|
||||
/* Encryption */
|
||||
uint8_t gltk[16];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue