Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nimble/ll: Improve scheduling of 1st BIG event #1636

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nimble/controller/include/controller/ble_ll_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len,

/* Get advertising instance with periodic advertising configured */
struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle);
/* Get periodic advertising event scheduled time */
int ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm,
uint32_t *start_time, uint32_t *end_time);

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
struct ble_ll_iso_big;
Expand Down
2 changes: 1 addition & 1 deletion nimble/controller/include/controller/ble_ll_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ uint32_t ble_ll_sched_css_get_conn_interval_us(void);
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first);
int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed);
#endif /* BLE_LL_ISO_BROADCASTER */

#ifdef __cplusplus
Expand Down
18 changes: 18 additions & 0 deletions nimble/controller/src/ble_ll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -5309,6 +5309,24 @@ ble_ll_adv_sync_get(uint8_t handle)
return advsm;
}

int
ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time,
uint32_t *end_time)
{
struct ble_ll_adv_sync *sync;

if (!advsm || !advsm->periodic_adv_active) {
return -EIO;
}

sync = SYNC_CURRENT(advsm);

*start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks;
*end_time = sync->sch.end_time;

return 0;
}

int
ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm,
struct ble_ll_iso_big *big)
Expand Down
38 changes: 28 additions & 10 deletions nimble/controller/src/ble_ll_iso_big.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
}

/* XXX this should always succeed since we preempt anything for now */
rc = ble_ll_sched_iso_big(&big->sch, 0);
rc = ble_ll_sched_iso_big(&big->sch, 0, 0);
assert(rc == 0);
} while (rc < 0);

Expand Down Expand Up @@ -1029,18 +1029,36 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
* not enough for some phys to run scheduler item.
*/

/* Schedule 1st event a bit in future */
/* FIXME schedule 6ms in the future to avoid conflict with periodic
* advertising when both are started at the same time; we should
* select this value in some smart way later...
*/
big->sch.start_time = ble_ll_tmr_get() + ble_ll_tmr_u2t(6000);
uint32_t start_time, end_time, big_time;
uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay);
uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250);
int big_event_fixed;

rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time);
if (rc) {
/* Set 1st BIG one interval after "now", this ensures it's always
* scheduled in the future.
*/
big_time = ble_ll_tmr_get() + iso_interval_ticks;
big_event_fixed = 0;
} else {
/* Set 1st BIG event directly before periodic advertising event, this
* way it will not overlap it even if periodic advertising data changes.
* Make sure it's in the future.
*/
big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks - 1;
while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) {
big_time += iso_interval_ticks;
}
big_event_fixed = 1;
}

big->sch.start_time = big_time;
big->sch.remainder = 0;
big->sch.end_time = big->sch.start_time +
ble_ll_tmr_u2t_up(big->sync_delay) + 1;
big->sch.end_time = big->sch.start_time + sync_delay_ticks + 1;
big->sch.start_time -= g_ble_ll_sched_offset_ticks;

rc = ble_ll_sched_iso_big(&big->sch, 1);
rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
if (rc < 0) {
ble_ll_iso_big_free(big);
return -EFAULT;
Expand Down
4 changes: 2 additions & 2 deletions nimble/controller/src/ble_ll_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,14 +844,14 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch)

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
int
ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first)
ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed)
{
os_sr_t sr;
int rc;

OS_ENTER_CRITICAL(sr);

if (first) {
if (first && !fixed) {
rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, preempt_none);
} else {
/* XXX provide better strategy for preemption */
Expand Down
Loading