Skip to content

Commit 959eced

Browse files
LingaoMm-alperen-sener
authored andcommitted
[nrf fromtree] Bluetooth: Mesh: Remove START_PENDING flags
Remove START_PENDING flag, and replace with bt_mesh_adv_is_empty_by_tag not only make adv_ext.c more readable, but also enhancement In previous implementation, after proxy started, will check this flag, and when the flag is true, will direct stop proxy and re-enter schedule, but has one problem, this flag set true, but buf will be empty, such as when sending mesh relay messages will for-each every sets, until find not-active, but also set previous set START_PENDING flags, so will cause proxy advertising started->stop->started. Signed-off-by: Lingao Meng <[email protected]> (cherry picked from commit 2ebdcfa)
1 parent 1e9b005 commit 959eced

File tree

1 file changed

+72
-65
lines changed

1 file changed

+72
-65
lines changed

subsys/bluetooth/mesh/adv_ext.c

Lines changed: 72 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ enum {
5151
ADV_FLAG_SENT,
5252
/** Currently performing proxy advertising */
5353
ADV_FLAG_PROXY,
54-
/** The send-call has been pending. */
55-
ADV_FLAG_SCHEDULE_PENDING,
5654
/** Custom adv params have been set, we need to update the parameters on
5755
* the next send.
5856
*/
@@ -273,40 +271,72 @@ static int adv_send(struct bt_mesh_ext_adv *ext_adv, struct bt_mesh_adv *adv)
273271
return err;
274272
}
275273

276-
static const char * const adv_tag_to_str[] = {
277-
[BT_MESH_ADV_TAG_LOCAL] = "local adv",
278-
[BT_MESH_ADV_TAG_RELAY] = "relay adv",
279-
[BT_MESH_ADV_TAG_PROXY] = "proxy adv",
280-
[BT_MESH_ADV_TAG_FRIEND] = "friend adv",
281-
[BT_MESH_ADV_TAG_PROV] = "prov adv",
282-
};
283-
284-
static bool schedule_send_with_mask(struct bt_mesh_ext_adv *ext_adv, int ignore_mask)
274+
static bool stop_proxy_adv(struct bt_mesh_ext_adv *ext_adv)
285275
{
286276
if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
287-
(void)bt_le_ext_adv_stop(ext_adv->instance);
277+
int err = bt_le_ext_adv_stop(ext_adv->instance);
278+
279+
__ASSERT_NO_MSG(err == 0);
288280

289281
atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
290282
}
291283

284+
return true;
285+
}
286+
287+
static bool schedule_send_with_mask(struct bt_mesh_ext_adv *ext_adv, int ignore_mask)
288+
{
289+
(void)stop_proxy_adv(ext_adv);
290+
292291
if (atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
293-
atomic_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING);
294292
return false;
295293
} else if ((~ignore_mask) & k_work_busy_get(&ext_adv->work)) {
296294
return false;
297295
}
298296

299-
atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING);
300297
bt_mesh_wq_submit(&ext_adv->work);
301298

302299
return true;
303300
}
304301

302+
static bool adv_send_process(struct bt_mesh_adv *adv, struct bt_mesh_ext_adv *ext_adv)
303+
{
304+
int err;
305+
306+
while (adv || (adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT))) {
307+
/* busy == 0 means this was canceled */
308+
if (!adv->ctx.busy) {
309+
bt_mesh_adv_unref(adv);
310+
adv = NULL;
311+
continue;
312+
}
313+
314+
adv->ctx.busy = 0U;
315+
err = adv_send(ext_adv, adv);
316+
317+
bt_mesh_adv_unref(adv);
318+
adv = NULL;
319+
320+
if (!err) {
321+
return true;
322+
}
323+
}
324+
325+
return false;
326+
}
327+
305328
static void send_pending_adv(struct k_work *work)
306329
{
330+
static const char * const adv_tag_to_str[] = {
331+
[BT_MESH_ADV_TAG_LOCAL] = "local",
332+
[BT_MESH_ADV_TAG_RELAY] = "relay",
333+
[BT_MESH_ADV_TAG_PROXY] = "proxy",
334+
[BT_MESH_ADV_TAG_FRIEND] = "friend",
335+
[BT_MESH_ADV_TAG_PROV] = "prov",
336+
};
307337
struct bt_mesh_ext_adv *ext_adv;
308-
struct bt_mesh_adv *adv;
309-
int err;
338+
struct bt_mesh_adv *adv = NULL;
339+
bool sent;
310340

311341
ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work);
312342

@@ -316,7 +346,7 @@ static void send_pending_adv(struct k_work *work)
316346
}
317347

318348
if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SENT)) {
319-
LOG_DBG("Advertising stopped after %u ms for %s",
349+
LOG_DBG("Advertising stopped after %u ms for %s adv",
320350
k_uptime_get_32() - ext_adv->timestamp,
321351
ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag]
322352
: adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]);
@@ -335,45 +365,37 @@ static void send_pending_adv(struct k_work *work)
335365
}
336366
}
337367

338-
while ((adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT))) {
339-
/* busy == 0 means this was canceled */
340-
if (!adv->ctx.busy) {
341-
bt_mesh_adv_unref(adv);
342-
continue;
368+
do {
369+
sent = adv_send_process(adv, ext_adv);
370+
if (sent) {
371+
return;
343372
}
344373

345-
adv->ctx.busy = 0U;
346-
err = adv_send(ext_adv, adv);
347-
348-
bt_mesh_adv_unref(adv);
349-
350-
if (!err) {
351-
return; /* Wait for advertising to finish */
374+
if (ext_adv->instance == NULL) {
375+
LOG_DBG("Advertiser is suspended or deleted");
376+
return;
352377
}
353-
}
354-
355-
if (ext_adv->instance == NULL) {
356-
LOG_DBG("Advertiser is suspended or deleted");
357-
return;
358-
}
359378

360-
if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) &&
361-
!bt_mesh_sol_send()) {
362-
return;
363-
}
379+
if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) &&
380+
!bt_mesh_sol_send()) {
381+
return;
382+
}
364383

365-
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) ||
366-
!(ext_adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) {
367-
return;
368-
}
384+
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) ||
385+
!(ext_adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) {
386+
return;
387+
}
369388

370-
if (!bt_mesh_adv_gatt_send()) {
371-
atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY);
372-
}
389+
if (!bt_mesh_adv_gatt_send()) {
390+
atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY);
391+
}
373392

374-
if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING)) {
375-
schedule_send_with_mask(ext_adv, K_WORK_RUNNING);
376-
}
393+
/* If there is a pending adv during the process of starting the
394+
* proxy advertising, the proxy advertising needs to be stop and
395+
* sent pending advertising immediately.
396+
*/
397+
} while ((adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT)) &&
398+
stop_proxy_adv(ext_adv));
377399
}
378400

379401
static bool schedule_send(struct bt_mesh_ext_adv *ext_adv)
@@ -508,6 +530,7 @@ static void adv_sent(struct bt_le_ext_adv *instance,
508530
}
509531

510532
if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
533+
LOG_WRN("Advertiser %p ADV_FLAG_ACTIVE not set", ext_adv);
511534
return;
512535
}
513536

@@ -516,28 +539,12 @@ static void adv_sent(struct bt_le_ext_adv *instance,
516539
bt_mesh_wq_submit(&ext_adv->work);
517540
}
518541

519-
#if defined(CONFIG_BT_MESH_GATT_SERVER)
520-
static void connected(struct bt_le_ext_adv *instance,
521-
struct bt_le_ext_adv_connected_info *info)
522-
{
523-
struct bt_mesh_ext_adv *ext_adv = gatt_adv_get();
524-
525-
if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
526-
atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
527-
(void)schedule_send(ext_adv);
528-
}
529-
}
530-
#endif /* CONFIG_BT_MESH_GATT_SERVER */
531-
532542
int bt_mesh_adv_enable(void)
533543
{
534544
int err;
535545

536546
static const struct bt_le_ext_adv_cb adv_cb = {
537547
.sent = adv_sent,
538-
#if defined(CONFIG_BT_MESH_GATT_SERVER)
539-
.connected = connected,
540-
#endif /* CONFIG_BT_MESH_GATT_SERVER */
541548
};
542549

543550
if (advs[0].instance) {

0 commit comments

Comments
 (0)