Skip to content

Commit

Permalink
Bluetooth: Controller: Add back the use of pre-transmissions
Browse files Browse the repository at this point in the history
Add back the implementation in the Controller that tries to
enable pre-transmissions to improve time diversity to aid a
remote ISO Sync Receiver role device.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information
cvinayak authored and kartben committed Jan 14, 2025
1 parent d58724d commit 9cd9f41
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 9 deletions.
4 changes: 4 additions & 0 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,10 @@ static void isr_tx_common(void *param,
(tx->payload_count < payload_count));
}
if (!link || (tx->payload_count != payload_count)) {
/* FIXME: Do not transmit on air an empty PDU if this is a Pre-Transmission
* subevent, instead use radio_tmr_start_us() to schedule next valid
* subevent.
*/
pdu = radio_pkt_empty_get();
pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED :
PDU_BIS_LLID_START_CONTINUE;
Expand Down
59 changes: 53 additions & 6 deletions subsys/bluetooth/controller/ll_sw/ull_adv_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@

#include "hal/debug.h"

/* Controller implementation dependent minimum Pre-Transmission Offset and
* Pre-Transmission Group Count to use when there is available time space in the
* BIG events.
* The number of Pre-Transmission Group Count configure how many future ISO SDUs
* from the Offset will be Pre-Transmitted in advance in the current BIG event.
*
* TODO: These could be a Kconfig option.
*/
#define BT_CTLR_ADV_ISO_PTO_MIN 1U
#define BT_CTLR_ADV_ISO_PTO_GROUP_COUNT 1U

static int init_reset(void);
static struct ll_adv_iso_set *adv_iso_get(uint8_t handle);
static struct stream *adv_iso_stream_acquire(void);
Expand Down Expand Up @@ -357,7 +368,12 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi
lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu);
}

/* FIXME: SDU per max latency */
/* FIXME: SDU per max latency, consider how to use Pre-transmission in the
* calculations.
* Take decision based on how ptc_calc function forces the use of
* Pre-Transmission when not using test command. Refer to comments in
* ptc_calc function.
*/
sdu_per_event = MAX((max_latency * USEC_PER_MSEC / sdu_interval), 2U) -
1U;

Expand Down Expand Up @@ -443,6 +459,9 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi
return BT_HCI_ERR_INVALID_PARAM;
}

/* Decision to use requested Pre-Transmission Offset or force Pre-Transmission when
* possible (Zephyr Controller decision).
*/
lll_adv_iso->ptc = ptc_calc(lll_adv_iso, event_spacing, event_spacing_max);

if (test_config) {
Expand All @@ -454,7 +473,7 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi
} else {
/* Pre-Transmission Offset (PTO) */
if (lll_adv_iso->ptc) {
lll_adv_iso->pto = bn / lll_adv_iso->bn;
lll_adv_iso->pto = MAX((bn / lll_adv_iso->bn), BT_CTLR_ADV_ISO_PTO_MIN);
} else {
lll_adv_iso->pto = 0U;
}
Expand Down Expand Up @@ -1154,15 +1173,43 @@ static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing,
uint32_t event_spacing_max)
{
if (event_spacing < event_spacing_max) {
uint8_t ptc;
uint32_t ptc;
uint8_t nse;

/* Possible maximum Pre-transmission Subevents per BIS */
/* Possible maximum Pre-transmission Subevents per BIS.
* sub_interval is at least T_MSS_150 + MPT (hence a value in 8 bits or more), i.e.
* the below division and the subsequent multiplication with lll->bn does not
* overflow.
*/
ptc = ((event_spacing_max - event_spacing) /
(lll->sub_interval * lll->bn * lll->num_bis)) *
lll->bn;

/* Restrict PTC to number of available subevents */
ptc = MIN(ptc, lll->nse - lll->bn * lll->irc);
/* Required NSE */
nse = lll->bn * lll->irc; /* 3 bits * 4 bits, total 7 bits */

/* Requested NSE is greater than Required NSE, Pre-Transmission offset has been
* provided.
*
* NOTE: This is the case under HCI test command use to create BIG, i.e. test_config
* variable is true.
*/
if (lll->nse > nse) {
/* Restrict PTC to number of available subevents */
ptc = MIN(ptc, lll->nse - nse);
} else {
/* No PTO requested, Zephyr Controller implementation here will try using
* Pre-Transmisson offset of BT_CTLR_ADV_ISO_PTO_MIN, i.e. restrict to a
* maximum of BN Pre-Transmission subevents per BIS. This allows for a
* better time diversity ensuring skipped or missing reception at the ISO
* Sync Receiver so it can still have another chance at receiving the ISO
* PDUs within the permitted maximum transport latency.
*
* Usecases where BAP Broadcast Audio Assistant role device has a drifting
* ACL Peripheral role active in the BAP Broadcast Audio Sink device.
*/
ptc = MIN(ptc, (lll->bn * BT_CTLR_ADV_ISO_PTO_GROUP_COUNT));
}

return ptc;
}
Expand Down
13 changes: 10 additions & 3 deletions subsys/bluetooth/controller/ll_sw/ull_sync_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,20 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso,
lll->sub_interval = PDU_BIG_INFO_SUB_INTERVAL_GET(bi);
lll->max_pdu = bi->max_pdu;
lll->pto = PDU_BIG_INFO_PTO_GET(bi);
lll->bis_spacing = PDU_BIG_INFO_SPACING_GET(bi);
lll->irc = PDU_BIG_INFO_IRC_GET(bi);
if (lll->pto) {
lll->ptc = lll->bn;
uint8_t nse;

nse = lll->irc * lll->bn; /* 4 bits * 3 bits, total 7 bits */
if (nse >= lll->nse) {
return;
}

lll->ptc = lll->nse - nse;
} else {
lll->ptc = 0U;
}
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);

/* Pick the 39-bit payload count, 1 MSb is framing bit */
Expand Down

0 comments on commit 9cd9f41

Please sign in to comment.