From 52e648989bf63631b5a0ea2e98f38e6307774def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 29 Aug 2019 16:36:08 +0200 Subject: [PATCH] nimble/ll: Fix assert in ble_ll_adv_done This patch makes sure that periodic advertising uses its own scheduler type. It is needed to not confuse it with related extended advertising. Mentioned assert happend in the following scenario a) Nimble has configured and enabled connectable advertising b) Nimble has configured and enabled periodic advertising along with its extending advertising. c) Once Nimble connects and bonds with peer device, keys are storred and in that time GAP procedures are stopped i.e. advertising. In this moment periodic advertising and connection are ongoing. d) While advertising is OFF LL reschedules connection event. It might happen that periodic advertising is conflicting with this, and in this case connection has bigger prio. Scheduler wants to remove it but since periodic advertising uses BLE_LL_SCHED_TYPE_ADV, in fact it tries to stop already stopped advertising -> assert --- .../controller/include/controller/ble_ll_adv.h | 6 ++++++ nimble/controller/src/ble_ll_adv.c | 16 ++++++++++++++-- nimble/controller/src/ble_ll_sched.c | 5 +++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index 043d314b5..dbcf5ce5a 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -173,6 +173,12 @@ int ble_ll_adv_can_chg_whitelist(void); */ void ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm); +/* + * Called when a periodic event has been removed from the scheduler + * without being run. + */ +void ble_ll_adv_periodic_rmvd_from_sched(struct ble_ll_adv_sm *advsm); + /* Called to halt currently running advertising event */ void ble_ll_adv_halt(void); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 66e226d51..6ef43693d 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -973,6 +973,18 @@ ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm) ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +/* + * Called when a periodic event has been removed from the scheduler + * without being run. + */ +void +ble_ll_adv_periodic_rmvd_from_sched(struct ble_ll_adv_sm *advsm) +{ + ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_periodic_txdone_ev); +} +#endif + /** * This is the scheduler callback (called from interrupt context) which * transmits an advertisement. @@ -4743,10 +4755,10 @@ ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm) advsm->periodic_sync_active = 0; advsm->periodic_sync[0].sch.cb_arg = advsm; advsm->periodic_sync[0].sch.sched_cb = ble_ll_adv_sync_tx_start_cb; - advsm->periodic_sync[0].sch.sched_type = BLE_LL_SCHED_TYPE_ADV; + advsm->periodic_sync[0].sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; advsm->periodic_sync[1].sch.cb_arg = advsm; advsm->periodic_sync[1].sch.sched_cb = ble_ll_adv_sync_tx_start_cb; - advsm->periodic_sync[1].sch.sched_type = BLE_LL_SCHED_TYPE_ADV; + advsm->periodic_sync[1].sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; #endif #endif diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 3679c6ff7..fa9b013f3 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -251,6 +251,11 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) case BLE_LL_SCHED_TYPE_AUX_SCAN: ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)entry->cb_arg); break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) + case BLE_LL_SCHED_TYPE_SYNC: + ble_ll_adv_periodic_rmvd_from_sched((struct ble_ll_adv_sm *)entry->cb_arg); + break; +#endif #endif default: BLE_LL_ASSERT(0);