Skip to content

Commit 6cec495

Browse files
committed
bluetooth: mesh: adv: legacy: Check suspended flag in the adv thread
Instead of checking the `enabled` flag, check if BT_MESH_SUSPENDED is set in the legacy advertiser thread. BT_MESH_SUSPENDED is set earlier than advertiser is stopped and will prevent the advertiser send anything earlier. Signed-off-by: Pavel Vasilyev <[email protected]>
1 parent c22233a commit 6cec495

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

subsys/bluetooth/mesh/adv_legacy.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ LOG_MODULE_REGISTER(bt_mesh_adv_legacy);
3838
static struct k_thread adv_thread_data;
3939
static K_KERNEL_STACK_DEFINE(adv_thread_stack, CONFIG_BT_MESH_ADV_STACK_SIZE);
4040
static int32_t adv_timeout;
41-
static bool enabled;
41+
42+
static bool is_mesh_suspended(void)
43+
{
44+
return atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
45+
}
4246

4347
static int bt_data_send(uint8_t num_events, uint16_t adv_int,
4448
const struct bt_data *ad, size_t ad_len,
@@ -104,7 +108,7 @@ static int bt_data_send(uint8_t num_events, uint16_t adv_int,
104108
bt_mesh_adv_send_start(duration, err, ctx);
105109
}
106110

107-
if (enabled) {
111+
if (!is_mesh_suspended()) {
108112
k_sleep(K_MSEC(duration));
109113
}
110114

@@ -148,7 +152,7 @@ static void adv_thread(void *p1, void *p2, void *p3)
148152
LOG_DBG("started");
149153
struct bt_mesh_adv *adv;
150154

151-
while (enabled) {
155+
while (!is_mesh_suspended()) {
152156
if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER)) {
153157
adv = bt_mesh_adv_get(K_NO_WAIT);
154158
if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !adv) {
@@ -234,7 +238,13 @@ void bt_mesh_adv_init(void)
234238

235239
int bt_mesh_adv_enable(void)
236240
{
237-
enabled = true;
241+
/* The advertiser thread relies on BT_MESH_SUSPENDED flag. No point in starting the
242+
* advertiser thread if the flag is not set.
243+
*/
244+
if (is_mesh_suspended()) {
245+
return -EINVAL;
246+
}
247+
238248
k_thread_start(&adv_thread_data);
239249
return 0;
240250
}
@@ -243,12 +253,21 @@ int bt_mesh_adv_disable(void)
243253
{
244254
int err;
245255

246-
enabled = false;
256+
/* k_thread_join will sleep forever if BT_MESH_SUSPENDED flag is not set. The advertiser
257+
* thread will exit once the flag is set. The flag is set by the higher layer function. Here
258+
* we need to check that the flag is dropped and ensure that the thread is stopped.
259+
*/
260+
if (!is_mesh_suspended()) {
261+
return -EINVAL;
262+
}
247263

248264
err = k_thread_join(&adv_thread_data, K_FOREVER);
249265
LOG_DBG("Advertising disabled: %d", err);
250266

251-
return 0;
267+
/* Since the thread will immediately stop after this function call and won’t perform any
268+
* further operations, it’s safe to ignore the deadlock error (EDEADLK).
269+
*/
270+
return err == -EDEADLK ? 0 : err;
252271
}
253272

254273
int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration,

0 commit comments

Comments
 (0)