Skip to content

Commit 1316c4b

Browse files
committed
Merge branch 'fix/blemesh24_61_v5.3' into 'release/v5.3'
fix/blemesh24_61 (v5.3) See merge request espressif/esp-idf!31564
2 parents 8e210e5 + 9b6b8ac commit 1316c4b

File tree

8 files changed

+74
-21
lines changed

8 files changed

+74
-21
lines changed

components/bt/esp_ble_mesh/common/atomic.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
/*
1414
* SPDX-FileCopyrightText: 2016 Intel Corporation
1515
* SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
16-
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
16+
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
1717
*
1818
* SPDX-License-Identifier: Apache-2.0
1919
*/
@@ -170,4 +170,18 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
170170
return ret;
171171
}
172172

173+
bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
174+
{
175+
bt_mesh_atomic_lock();
176+
177+
if (*target == excepted) {
178+
*target = new_val;
179+
bt_mesh_atomic_unlock();
180+
return true;
181+
}
182+
183+
bt_mesh_atomic_unlock();
184+
return false;
185+
}
186+
173187
#endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */

components/bt/esp_ble_mesh/common/include/mesh/atomic.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,33 @@ static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target,
147147
extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
148148
#endif
149149

150+
/**
151+
* @brief Atomic CAS operation.
152+
*
153+
* This compares the contents of @a *target
154+
* with the contents of @a excepted. If equal,
155+
* the operation is a read-modify-write operation
156+
* that writes @a new_val into @a *target and return true.
157+
* If they are not equal, the operation is a read
158+
* and return false.
159+
*
160+
* @param target Address of atomic variable.
161+
* @param excepted Value of excepted.
162+
* @param new_val Write if target value is equal to expected one.
163+
*
164+
* @return
165+
* - true: Target value updated.
166+
* - false: Target value not updated.
167+
*/
168+
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
169+
static inline bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
170+
{
171+
return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
172+
}
173+
#else
174+
extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val);
175+
#endif
176+
150177
/**
151178
* @cond INTERNAL_HIDDEN
152179
*/

components/bt/esp_ble_mesh/core/adv.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/*
44
* SPDX-FileCopyrightText: 2017 Intel Corporation
5-
* SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD
5+
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*/
@@ -335,8 +335,7 @@ static void adv_thread(void *p)
335335
}
336336

337337
/* busy == 0 means this was canceled */
338-
if (BLE_MESH_ADV(*buf)->busy) {
339-
BLE_MESH_ADV(*buf)->busy = 0U;
338+
if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) {
340339
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
341340
if (adv_send(*buf)) {
342341
BT_WARN("Failed to send adv packet");
@@ -449,7 +448,7 @@ static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
449448

450449
if (msg->arg) {
451450
buf = (struct net_buf *)msg->arg;
452-
BLE_MESH_ADV(buf)->busy = 0U;
451+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
453452
if (buf->ref > 1U) {
454453
buf->ref = 1U;
455454
}
@@ -490,7 +489,7 @@ void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
490489

491490
BLE_MESH_ADV(buf)->cb = cb;
492491
BLE_MESH_ADV(buf)->cb_data = cb_data;
493-
BLE_MESH_ADV(buf)->busy = 1U;
492+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
494493
BLE_MESH_ADV(buf)->xmit = xmit;
495494

496495
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
@@ -589,7 +588,7 @@ void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
589588

590589
BLE_MESH_ADV(buf)->cb = cb;
591590
BLE_MESH_ADV(buf)->cb_data = cb_data;
592-
BLE_MESH_ADV(buf)->busy = 1U;
591+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
593592
BLE_MESH_ADV(buf)->xmit = xmit;
594593

595594
msg.arg = (void *)net_buf_ref(buf);
@@ -753,7 +752,7 @@ static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_
753752

754753
BLE_MESH_ADV(buf)->cb = cb;
755754
BLE_MESH_ADV(buf)->cb_data = cb_data;
756-
BLE_MESH_ADV(buf)->busy = 1U;
755+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
757756

758757
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
759758

@@ -772,7 +771,7 @@ static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref)
772771
}
773772
bt_mesh_atomic_set(tx->flags, 0);
774773
memset(&tx->param, 0, sizeof(tx->param));
775-
BLE_MESH_ADV(tx->buf)->busy = 0U;
774+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
776775
if (unref) {
777776
net_buf_unref(tx->buf);
778777
}
@@ -961,7 +960,8 @@ int bt_mesh_stop_ble_advertising(uint8_t index)
961960
/* busy 1, ref 1; busy 1, ref 2;
962961
* busy 0, ref 0; busy 0, ref 1;
963962
*/
964-
if (BLE_MESH_ADV(tx->buf)->busy == 1U &&
963+
964+
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
965965
tx->buf->ref == 1U) {
966966
unref = false;
967967
}

components/bt/esp_ble_mesh/core/adv.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef _ADV_H_
1111
#define _ADV_H_
1212

13+
#include "mesh/atomic.h"
1314
#include "mesh/access.h"
1415
#include "mesh/adapter.h"
1516

@@ -24,6 +25,7 @@ extern "C" {
2425
#define BLE_MESH_ADV_USER_DATA_SIZE 4
2526

2627
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
28+
#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy)
2729

2830
uint16_t bt_mesh_pdu_duration(uint8_t xmit);
2931

@@ -48,8 +50,10 @@ struct bt_mesh_adv {
4850
const struct bt_mesh_send_cb *cb;
4951
void *cb_data;
5052

51-
uint8_t type:3,
52-
busy:1;
53+
uint8_t type:3;
54+
55+
bt_mesh_atomic_t busy;
56+
5357
uint8_t xmit;
5458
};
5559

components/bt/esp_ble_mesh/core/friend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason)
183183
/* Cancel the sending if necessary */
184184
if (frnd->pending_buf) {
185185
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL);
186-
BLE_MESH_ADV(frnd->last)->busy = 0U;
186+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0);
187187
} else {
188188
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL);
189189
}

components/bt/esp_ble_mesh/core/prov_common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ static void free_segments(struct bt_mesh_prov_link *link)
359359
link->tx.buf[i] = NULL;
360360
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
361361
/* Mark as canceled */
362-
BLE_MESH_ADV(buf)->busy = 0U;
362+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
363363
net_buf_unref(buf);
364364
}
365365
}
@@ -474,7 +474,7 @@ static void prov_retransmit(struct k_work *work)
474474
break;
475475
}
476476

477-
if (BLE_MESH_ADV(buf)->busy) {
477+
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(buf))) {
478478
continue;
479479
}
480480

components/bt/esp_ble_mesh/core/transport.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/*
44
* SPDX-FileCopyrightText: 2017 Intel Corporation
5-
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
5+
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*/
@@ -310,7 +310,15 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
310310
{
311311
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL);
312312

313-
BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U;
313+
/**
314+
* When cancelling a segment that is still in the adv sending queue, `tx->seg_pending`
315+
* must else be decremented by one. More detailed information
316+
* can be found in BLEMESH24-26.
317+
*/
318+
if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) {
319+
tx->seg_pending--;
320+
}
321+
314322
net_buf_unref(tx->seg[seg_idx]);
315323
tx->seg[seg_idx] = NULL;
316324
tx->nack_count--;
@@ -443,7 +451,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
443451
continue;
444452
}
445453

446-
if (BLE_MESH_ADV(seg)->busy) {
454+
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
447455
BT_DBG("Skipping segment that's still advertising");
448456
continue;
449457
}

components/bt/esp_ble_mesh/core/transport.enh.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
350350
*/
351351
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL);
352352

353-
BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U;
353+
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 0);
354354
net_buf_unref(tx->seg[seg_idx]);
355355

356356
tx->seg[seg_idx] = NULL;
@@ -498,7 +498,7 @@ static bool send_next_segment(struct seg_tx *tx, int *result)
498498
/* The segment may have already been transmitted, for example, the
499499
* Segment Retransmission timer is expired earlier.
500500
*/
501-
if (BLE_MESH_ADV(seg)->busy) {
501+
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
502502
return false;
503503
}
504504

@@ -768,7 +768,7 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result)
768768
* A is still going to be retransmitted, but at this moment we could
769769
* find that the "busy" flag of Segment A is 1.
770770
*/
771-
if (BLE_MESH_ADV(seg)->busy) {
771+
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
772772
return false;
773773
}
774774

0 commit comments

Comments
 (0)