diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 606fd1debd1..c50d604a73f 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -33,6 +33,8 @@ enum { /** Controller is currently advertising */ ADV_FLAG_ACTIVE, + /** Advertising sending completed */ + ADV_FLAG_SENT, /** Currently performing proxy advertising */ ADV_FLAG_PROXY, /** The send-call has been scheduled. */ @@ -208,6 +210,29 @@ static void send_pending_adv(struct k_work *work) int err; adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work.work); + + if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SENT)) { + /* Calling k_uptime_delta on a timestamp moves it to the current time. + * This is essential here, as schedule_send() uses the end of the event + * as a reference to avoid sending the next advertisement too soon. + */ + int64_t duration = k_uptime_delta(&adv->timestamp); + + BT_DBG("Advertising stopped after %u ms", (uint32_t)duration); + + atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); + + if (adv->buf) { + net_buf_unref(adv->buf); + adv->buf = NULL; + } + + (void)schedule_send(adv); + + return; + } + atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED); while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tag, K_NO_WAIT))) { @@ -334,23 +359,13 @@ static void adv_sent(struct bt_le_ext_adv *instance, return; } - /* Calling k_uptime_delta on a timestamp moves it to the current time. - * This is essential here, as schedule_send() uses the end of the event - * as a reference to avoid sending the next advertisement too soon. - */ - int64_t duration = k_uptime_delta(&adv->timestamp); - - BT_DBG("Advertising stopped after %u ms", (uint32_t)duration); - - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); - - if (adv->buf) { - net_buf_unref(adv->buf); - adv->buf = NULL; + if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { + return; } - (void)schedule_send(adv); + atomic_set_bit(adv->flags, ADV_FLAG_SENT); + + k_work_submit(&adv->work.work); } #if defined(CONFIG_BT_MESH_GATT_SERVER)