@@ -271,58 +271,84 @@ static int adv_send(struct bt_mesh_ext_adv *ext_adv, struct bt_mesh_adv *adv)
271271 return err ;
272272}
273273
274- static bool stop_proxy_adv (struct bt_mesh_ext_adv * ext_adv )
274+ static int stop_proxy_adv (struct bt_mesh_ext_adv * ext_adv )
275275{
276- if (atomic_test_and_clear_bit (ext_adv -> flags , ADV_FLAG_PROXY )) {
277- int err = bt_le_ext_adv_stop (ext_adv -> instance );
276+ int err ;
278277
279- __ASSERT_NO_MSG (err == 0 );
278+ if (atomic_test_bit (ext_adv -> flags , ADV_FLAG_PROXY )) {
279+ err = bt_le_ext_adv_stop (ext_adv -> instance );
280+ if (err ) {
281+ LOG_ERR ("Failed to stop proxy advertising: %d" , err );
282+ return err ;
283+ }
280284
285+ atomic_clear_bit (ext_adv -> flags , ADV_FLAG_PROXY );
281286 atomic_clear_bit (ext_adv -> flags , ADV_FLAG_ACTIVE );
282287 }
283288
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-
291- if (atomic_test_bit (ext_adv -> flags , ADV_FLAG_ACTIVE )) {
292- return false;
293- } else if ((~ignore_mask ) & k_work_busy_get (& ext_adv -> work )) {
294- return false;
295- }
296-
297- bt_mesh_wq_submit (& ext_adv -> work );
298-
299- return true;
289+ return 0 ;
300290}
301291
302- static bool adv_send_process ( struct bt_mesh_adv * adv , struct bt_mesh_ext_adv * ext_adv )
292+ static int adv_queue_send_process ( struct bt_mesh_ext_adv * ext_adv )
303293{
304- int err ;
294+ struct bt_mesh_adv * adv ;
295+ int err = - ENOENT ;
305296
306- while (adv || (adv = bt_mesh_adv_get_by_tag (ext_adv -> tags , K_NO_WAIT ))) {
297+ while ((adv = bt_mesh_adv_get_by_tag (ext_adv -> tags , K_NO_WAIT ))) {
307298 /* busy == 0 means this was canceled */
308299 if (!adv -> ctx .busy ) {
309300 bt_mesh_adv_unref (adv );
310- adv = NULL ;
301+ continue ;
302+ }
303+
304+ if (stop_proxy_adv (ext_adv )) {
305+ LOG_WRN ("Advertising %p canceled due to proxy adv failed to stop" , adv );
306+ bt_mesh_adv_send_start (0 , - ECANCELED , & adv -> ctx );
307+ bt_mesh_adv_unref (adv );
311308 continue ;
312309 }
313310
314311 adv -> ctx .busy = 0U ;
315312 err = adv_send (ext_adv , adv );
316313
317314 bt_mesh_adv_unref (adv );
318- adv = NULL ;
319315
320316 if (!err ) {
321- return true;
317+ return 0 ; /* Wait for advertising to finish */
318+ }
319+ }
320+
321+ return err ;
322+ }
323+
324+ static void start_proxy_sol_or_proxy_adv (struct bt_mesh_ext_adv * ext_adv )
325+ {
326+ if (ext_adv -> instance == NULL ) {
327+ LOG_DBG ("Advertiser is suspended or deleted" );
328+ return ;
329+ }
330+
331+ if (!(ext_adv -> tags & BT_MESH_ADV_TAG_BIT_PROXY )) {
332+ return ;
333+ }
334+
335+ if (IS_ENABLED (CONFIG_BT_MESH_PROXY_SOLICITATION )) {
336+ if (stop_proxy_adv (ext_adv )) {
337+ return ;
338+ }
339+
340+ if (!bt_mesh_sol_send ()) {
341+ return ;
322342 }
323343 }
324344
325- return false;
345+ if (IS_ENABLED (CONFIG_BT_MESH_GATT_SERVER ) &&
346+ !atomic_test_and_set_bit (ext_adv -> flags , ADV_FLAG_PROXY )) {
347+ if (bt_mesh_adv_gatt_send ()) {
348+ atomic_clear_bit (ext_adv -> flags , ADV_FLAG_PROXY );
349+ return ;
350+ }
351+ }
326352}
327353
328354static void send_pending_adv (struct k_work * work )
@@ -335,8 +361,7 @@ static void send_pending_adv(struct k_work *work)
335361 [BT_MESH_ADV_TAG_PROV ] = "prov" ,
336362 };
337363 struct bt_mesh_ext_adv * ext_adv ;
338- struct bt_mesh_adv * adv = NULL ;
339- bool sent ;
364+ int err ;
340365
341366 ext_adv = CONTAINER_OF (work , struct bt_mesh_ext_adv , work );
342367
@@ -365,42 +390,32 @@ static void send_pending_adv(struct k_work *work)
365390 }
366391 }
367392
368- do {
369- sent = adv_send_process (adv , ext_adv );
370- if (sent ) {
371- return ;
372- }
373-
374- if (ext_adv -> instance == NULL ) {
375- LOG_DBG ("Advertiser is suspended or deleted" );
376- return ;
377- }
378-
379- if (IS_ENABLED (CONFIG_BT_MESH_PROXY_SOLICITATION ) &&
380- !bt_mesh_sol_send ()) {
381- return ;
382- }
383-
384- if (!IS_ENABLED (CONFIG_BT_MESH_GATT_SERVER ) ||
385- !(ext_adv -> tags & BT_MESH_ADV_TAG_BIT_PROXY )) {
386- return ;
387- }
388-
389- if (!bt_mesh_adv_gatt_send ()) {
390- atomic_set_bit (ext_adv -> flags , ADV_FLAG_PROXY );
391- }
393+ err = adv_queue_send_process (ext_adv );
394+ if (!err ) {
395+ return ;
396+ }
392397
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 ));
398+ start_proxy_sol_or_proxy_adv (ext_adv );
399399}
400400
401401static bool schedule_send (struct bt_mesh_ext_adv * ext_adv )
402402{
403- return schedule_send_with_mask (ext_adv , 0 );
403+ if (atomic_test_bit (ext_adv -> flags , ADV_FLAG_ACTIVE )) {
404+ /* We don't need to resubmit the `send_pending_adv` work if the mesh advertiser
405+ * is sending a mesh packet. The `send_pending_adv` work is resubmitted when the
406+ * current advertising is finished, which is done through the `adv_sent` callback.
407+ *
408+ * The proxy advertisement in turns doesn't timeout or stop quickly and has less
409+ * priority than regular mesh messages, thus needs to be stopped immeditaly.
410+ */
411+ if (!atomic_test_bit (ext_adv -> flags , ADV_FLAG_PROXY )) {
412+ return false;
413+ }
414+ }
415+
416+ bt_mesh_wq_submit (& ext_adv -> work );
417+
418+ return true;
404419}
405420
406421void bt_mesh_adv_gatt_update (void )
@@ -530,7 +545,7 @@ static void adv_sent(struct bt_le_ext_adv *instance,
530545 }
531546
532547 if (!atomic_test_bit (ext_adv -> flags , ADV_FLAG_ACTIVE )) {
533- LOG_WRN ("Advertiser %p ADV_FLAG_ACTIVE not set" , ext_adv );
548+ LOG_DBG ("Advertiser %p ADV_FLAG_ACTIVE not set" , ext_adv );
534549 return ;
535550 }
536551
0 commit comments