Bluetooth: Mesh: Fix Assert in bt_mesh_adv_unref when messages to a proxy

Fixes:https://github.com/zephyrproject-rtos/zephyr/issues/83904

This solution fix is to define a separate variable for the each proxy FIFO.

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
Lingao Meng 2025-01-14 09:54:13 +08:00 committed by Benjamin Cabé
parent f5565cfe4f
commit 6371080406
2 changed files with 26 additions and 4 deletions

View file

@ -58,7 +58,11 @@ struct bt_mesh_adv_ctx {
};
struct bt_mesh_adv {
sys_snode_t node;
void *adv_bearer;
#if defined(CONFIG_BT_MESH_GATT)
void *gatt_bearer[CONFIG_BT_MAX_CONN];
#endif
struct bt_mesh_adv_ctx ctx;

View file

@ -56,6 +56,24 @@ static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN];
static int conn_count;
static void proxy_queue_put(struct bt_mesh_proxy_role *role, struct bt_mesh_adv *adv)
{
k_fifo_put(&role->pending, &(adv->gatt_bearer[bt_conn_index(role->conn)]));
}
static struct bt_mesh_adv *proxy_queue_get(struct bt_mesh_proxy_role *role)
{
void *gatt_bearer;
gatt_bearer = k_fifo_get(&role->pending, K_NO_WAIT);
if (!gatt_bearer) {
return NULL;
}
return CONTAINER_OF(gatt_bearer, struct bt_mesh_adv,
gatt_bearer[bt_conn_index(role->conn)]);
}
static void proxy_sar_timeout(struct k_work *work)
{
struct bt_mesh_proxy_role *role;
@ -66,7 +84,7 @@ static void proxy_sar_timeout(struct k_work *work)
role = CONTAINER_OF(dwork, struct bt_mesh_proxy_role, sar_timer);
while (!k_fifo_is_empty(&role->pending)) {
struct bt_mesh_adv *adv = k_fifo_get(&role->pending, K_NO_WAIT);
struct bt_mesh_adv *adv = proxy_queue_get(role);
__ASSERT_NO_MSG(adv);
@ -243,7 +261,7 @@ int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv)
{
struct bt_mesh_proxy_role *role = &roles[bt_conn_index(conn)];
k_fifo_put(&role->pending, bt_mesh_adv_ref(adv));
proxy_queue_put(role, bt_mesh_adv_ref(adv));
bt_mesh_wq_submit(&role->work);
@ -259,7 +277,7 @@ static void proxy_msg_send_pending(struct k_work *work)
return;
}
adv = k_fifo_get(&role->pending, K_NO_WAIT);
adv = proxy_queue_get(role);
if (!adv) {
return;
}