Merge branch 'fix/blemesh24_61_v5.3' into 'release/v5.3'

fix/blemesh24_61 (v5.3)

See merge request espressif/esp-idf!31564
This commit is contained in:
Jiang Jiang Jian
2024-07-26 11:38:30 +08:00
8 changed files with 74 additions and 21 deletions

View File

@@ -13,7 +13,7 @@
/* /*
* SPDX-FileCopyrightText: 2016 Intel Corporation * SPDX-FileCopyrightText: 2016 Intel Corporation
* SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc. * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -170,4 +170,18 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
return ret; return ret;
} }
bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
{
bt_mesh_atomic_lock();
if (*target == excepted) {
*target = new_val;
bt_mesh_atomic_unlock();
return true;
}
bt_mesh_atomic_unlock();
return false;
}
#endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */ #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */

View File

@@ -147,6 +147,33 @@ static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target,
extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value); extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
#endif #endif
/**
* @brief Atomic CAS operation.
*
* This compares the contents of @a *target
* with the contents of @a excepted. If equal,
* the operation is a read-modify-write operation
* that writes @a new_val into @a *target and return true.
* If they are not equal, the operation is a read
* and return false.
*
* @param target Address of atomic variable.
* @param excepted Value of excepted.
* @param new_val Write if target value is equal to expected one.
*
* @return
* - true: Target value updated.
* - false: Target value not updated.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
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)
{
return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
#else
extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val);
#endif
/** /**
* @cond INTERNAL_HIDDEN * @cond INTERNAL_HIDDEN
*/ */

View File

@@ -2,7 +2,7 @@
/* /*
* SPDX-FileCopyrightText: 2017 Intel Corporation * SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -335,8 +335,7 @@ static void adv_thread(void *p)
} }
/* busy == 0 means this was canceled */ /* busy == 0 means this was canceled */
if (BLE_MESH_ADV(*buf)->busy) { if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) {
BLE_MESH_ADV(*buf)->busy = 0U;
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF #if !CONFIG_BLE_MESH_RELAY_ADV_BUF
if (adv_send(*buf)) { if (adv_send(*buf)) {
BT_WARN("Failed to send adv packet"); BT_WARN("Failed to send adv packet");
@@ -449,7 +448,7 @@ static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
if (msg->arg) { if (msg->arg) {
buf = (struct net_buf *)msg->arg; buf = (struct net_buf *)msg->arg;
BLE_MESH_ADV(buf)->busy = 0U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
if (buf->ref > 1U) { if (buf->ref > 1U) {
buf->ref = 1U; buf->ref = 1U;
} }
@@ -490,7 +489,7 @@ void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data; BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
BLE_MESH_ADV(buf)->xmit = xmit; BLE_MESH_ADV(buf)->xmit = xmit;
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); 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,
BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data; BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
BLE_MESH_ADV(buf)->xmit = xmit; BLE_MESH_ADV(buf)->xmit = xmit;
msg.arg = (void *)net_buf_ref(buf); 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_
BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data; BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
@@ -772,7 +771,7 @@ static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref)
} }
bt_mesh_atomic_set(tx->flags, 0); bt_mesh_atomic_set(tx->flags, 0);
memset(&tx->param, 0, sizeof(tx->param)); memset(&tx->param, 0, sizeof(tx->param));
BLE_MESH_ADV(tx->buf)->busy = 0U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
if (unref) { if (unref) {
net_buf_unref(tx->buf); net_buf_unref(tx->buf);
} }
@@ -961,7 +960,8 @@ int bt_mesh_stop_ble_advertising(uint8_t index)
/* busy 1, ref 1; busy 1, ref 2; /* busy 1, ref 1; busy 1, ref 2;
* busy 0, ref 0; busy 0, ref 1; * busy 0, ref 0; busy 0, ref 1;
*/ */
if (BLE_MESH_ADV(tx->buf)->busy == 1U &&
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
tx->buf->ref == 1U) { tx->buf->ref == 1U) {
unref = false; unref = false;
} }

View File

@@ -10,6 +10,7 @@
#ifndef _ADV_H_ #ifndef _ADV_H_
#define _ADV_H_ #define _ADV_H_
#include "mesh/atomic.h"
#include "mesh/access.h" #include "mesh/access.h"
#include "mesh/adapter.h" #include "mesh/adapter.h"
@@ -24,6 +25,7 @@ extern "C" {
#define BLE_MESH_ADV_USER_DATA_SIZE 4 #define BLE_MESH_ADV_USER_DATA_SIZE 4
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) #define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy)
uint16_t bt_mesh_pdu_duration(uint8_t xmit); uint16_t bt_mesh_pdu_duration(uint8_t xmit);
@@ -48,8 +50,10 @@ struct bt_mesh_adv {
const struct bt_mesh_send_cb *cb; const struct bt_mesh_send_cb *cb;
void *cb_data; void *cb_data;
uint8_t type:3, uint8_t type:3;
busy:1;
bt_mesh_atomic_t busy;
uint8_t xmit; uint8_t xmit;
}; };

View File

@@ -183,7 +183,7 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason)
/* Cancel the sending if necessary */ /* Cancel the sending if necessary */
if (frnd->pending_buf) { if (frnd->pending_buf) {
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL); bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL);
BLE_MESH_ADV(frnd->last)->busy = 0U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0);
} else { } else {
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL); bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL);
} }

View File

@@ -359,7 +359,7 @@ static void free_segments(struct bt_mesh_prov_link *link)
link->tx.buf[i] = NULL; link->tx.buf[i] = NULL;
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
/* Mark as canceled */ /* Mark as canceled */
BLE_MESH_ADV(buf)->busy = 0U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
net_buf_unref(buf); net_buf_unref(buf);
} }
} }
@@ -474,7 +474,7 @@ static void prov_retransmit(struct k_work *work)
break; break;
} }
if (BLE_MESH_ADV(buf)->busy) { if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(buf))) {
continue; continue;
} }

View File

@@ -2,7 +2,7 @@
/* /*
* SPDX-FileCopyrightText: 2017 Intel Corporation * SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -310,7 +310,15 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
{ {
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL); bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL);
BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; /**
* When cancelling a segment that is still in the adv sending queue, `tx->seg_pending`
* must else be decremented by one. More detailed information
* can be found in BLEMESH24-26.
*/
if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) {
tx->seg_pending--;
}
net_buf_unref(tx->seg[seg_idx]); net_buf_unref(tx->seg[seg_idx]);
tx->seg[seg_idx] = NULL; tx->seg[seg_idx] = NULL;
tx->nack_count--; tx->nack_count--;
@@ -443,7 +451,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
continue; continue;
} }
if (BLE_MESH_ADV(seg)->busy) { if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
BT_DBG("Skipping segment that's still advertising"); BT_DBG("Skipping segment that's still advertising");
continue; continue;
} }

View File

@@ -350,7 +350,7 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
*/ */
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL); bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL);
BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 0);
net_buf_unref(tx->seg[seg_idx]); net_buf_unref(tx->seg[seg_idx]);
tx->seg[seg_idx] = NULL; tx->seg[seg_idx] = NULL;
@@ -498,7 +498,7 @@ static bool send_next_segment(struct seg_tx *tx, int *result)
/* The segment may have already been transmitted, for example, the /* The segment may have already been transmitted, for example, the
* Segment Retransmission timer is expired earlier. * Segment Retransmission timer is expired earlier.
*/ */
if (BLE_MESH_ADV(seg)->busy) { if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
return false; return false;
} }
@@ -768,7 +768,7 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result)
* A is still going to be retransmitted, but at this moment we could * A is still going to be retransmitted, but at this moment we could
* find that the "busy" flag of Segment A is 1. * find that the "busy" flag of Segment A is 1.
*/ */
if (BLE_MESH_ADV(seg)->busy) { if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
return false; return false;
} }