mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-06 05:14:45 +00:00
nimble/ll: Fix BIG event scheduling relative to padv
This fixes scheduling of BIG events relative to padv. The start time of a BIG event should be relative to padv event start, not padv sched start time which in theory may be different if that's not for the 1st AUX_SYNC_IND. Also if padv event start time is in the past, we still need to schedule BIG event in the future instead of just failing.
This commit is contained in:
@@ -201,9 +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);
|
||||
int ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm,
|
||||
uint32_t *event_start,
|
||||
uint8_t *event_start_rem_us);
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
|
||||
struct ble_ll_iso_big;
|
||||
|
||||
@@ -5337,19 +5337,18 @@ ble_ll_adv_sync_get(uint8_t handle)
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time,
|
||||
uint32_t *end_time)
|
||||
ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm,
|
||||
uint32_t *event_start,
|
||||
uint8_t *event_start_rem_us)
|
||||
{
|
||||
struct ble_ll_adv_sync *sync;
|
||||
|
||||
if (!advsm || !advsm->periodic_adv_active) {
|
||||
return -EIO;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sync = SYNC_CURRENT(advsm);
|
||||
|
||||
*start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks;
|
||||
*end_time = sync->sch.end_time;
|
||||
*event_start = advsm->padv_event_start;
|
||||
if (event_start_rem_us) {
|
||||
*event_start_rem_us = advsm->padv_event_start_rem_us;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1111,41 +1111,40 @@ 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.
|
||||
*/
|
||||
|
||||
uint32_t start_time, end_time, big_time;
|
||||
uint32_t padv_start_time, big_start_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);
|
||||
rc = ble_ll_adv_padv_event_start_get(big->advsm, &padv_start_time, NULL);
|
||||
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;
|
||||
/* 1st event will be moved by 1 interval before scheduling so this will
|
||||
* be always in the future */
|
||||
big_start_time = ble_ll_tmr_get();
|
||||
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_start_time = padv_start_time - g_ble_ll_sched_offset_ticks -
|
||||
sync_delay_ticks - 1;
|
||||
big_event_fixed = 1;
|
||||
}
|
||||
|
||||
big->anchor_base_ticks = big_time;
|
||||
big->anchor_base_ticks = big_start_time;
|
||||
big->anchor_base_rem_us = 0;
|
||||
big->anchor_offset = 0;
|
||||
|
||||
big_sched_set(big);
|
||||
do {
|
||||
big->anchor_offset++;
|
||||
big_sched_set(big);
|
||||
|
||||
rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
|
||||
if (rc < 0) {
|
||||
ble_ll_iso_big_free(big);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (LL_TMR_LEQ(big->sch.start_time, ble_ll_tmr_get())) {
|
||||
rc = -1;
|
||||
} else {
|
||||
rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
|
||||
}
|
||||
} while (rc < 0);
|
||||
|
||||
ble_ll_iso_big_update_event_start(big);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user