diff --git a/components/bt/ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/ble_mesh/btc/btc_ble_mesh_prov.c index 9def1f83c7..8fe1ac6a3d 100644 --- a/components/bt/ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/ble_mesh/btc/btc_ble_mesh_prov.c @@ -317,6 +317,8 @@ static void btc_ble_mesh_client_model_op_cb(struct bt_mesh_model *model, return; } + bt_mesh_client_model_lock(); + node = bt_mesh_is_model_message_publish(model, ctx, buf, false); if (node == NULL) { msg.act = ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT; @@ -336,12 +338,21 @@ static void btc_ble_mesh_client_model_op_cb(struct bt_mesh_model *model, msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_MODEL; - if (msg.act != ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT) { - // Don't forget to release the node at the end. - bt_mesh_client_free_node(&data->queue, node); + if (msg.act == ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT) { + ret = btc_transfer_context(&msg, &mesh_param, + sizeof(esp_ble_mesh_model_cb_param_t), btc_ble_mesh_copy_req_data); + } else { + if (!k_delayed_work_free(&node->timer)) { + ret = btc_transfer_context(&msg, &mesh_param, + sizeof(esp_ble_mesh_model_cb_param_t), btc_ble_mesh_copy_req_data); + // Don't forget to release the node at the end. + bt_mesh_client_free_node(&data->queue, node); + } else { + ret = BT_STATUS_SUCCESS; + } } - ret = btc_transfer_context(&msg, &mesh_param, - sizeof(esp_ble_mesh_model_cb_param_t), btc_ble_mesh_copy_req_data); + + bt_mesh_client_model_unlock(); if (ret != BT_STATUS_SUCCESS) { LOG_ERROR("%s, btc_transfer_context failed", __func__); @@ -613,21 +624,29 @@ static void btc_client_model_timeout_cb(struct k_work *work) return; } - mesh_param.client_send_timeout.opcode = node->opcode; - mesh_param.client_send_timeout.model = (esp_ble_mesh_model_t *)node->ctx.model; - mesh_param.client_send_timeout.ctx = (esp_ble_mesh_msg_ctx_t *)&node->ctx; + bt_mesh_client_model_lock(); - msg.sig = BTC_SIG_API_CB; - msg.pid = BTC_PID_MODEL; - msg.act = ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT; - ret = btc_transfer_context(&msg, &mesh_param, - sizeof(esp_ble_mesh_model_cb_param_t), btc_ble_mesh_copy_req_data); + if (!k_delayed_work_free(&node->timer)) { + mesh_param.client_send_timeout.opcode = node->opcode; + mesh_param.client_send_timeout.model = (esp_ble_mesh_model_t *)node->ctx.model; + mesh_param.client_send_timeout.ctx = (esp_ble_mesh_msg_ctx_t *)&node->ctx; - if (ret != BT_STATUS_SUCCESS) { - LOG_ERROR("%s btc_transfer_context failed", __func__); + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_MODEL; + msg.act = ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT; + + ret = btc_transfer_context(&msg, &mesh_param, + sizeof(esp_ble_mesh_model_cb_param_t), btc_ble_mesh_copy_req_data); + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed", __func__); + } + + // Don't forget to release the node at the end. + bt_mesh_client_free_node(&data->queue, node); } - // Don't forget to release the node at the end. - bt_mesh_client_free_node(&data->queue, node); + + bt_mesh_client_model_unlock(); + return; } diff --git a/components/bt/ble_mesh/mesh_models/include/model_common.h b/components/bt/ble_mesh/mesh_models/include/model_common.h index fd9cc6dfda..ace6d0da2b 100644 --- a/components/bt/ble_mesh/mesh_models/include/model_common.h +++ b/components/bt/ble_mesh/mesh_models/include/model_common.h @@ -56,6 +56,10 @@ typedef struct { struct k_delayed_work timer; /* Message send Timer. Only for stack-internal use. */ } bt_mesh_client_node_t; +void bt_mesh_client_model_lock(void); + +void bt_mesh_client_model_unlock(void); + int bt_mesh_client_init(struct bt_mesh_model *model); /** diff --git a/components/bt/ble_mesh/mesh_models/model_common.c b/components/bt/ble_mesh/mesh_models/model_common.c index da86e8c17b..763b68794a 100644 --- a/components/bt/ble_mesh/mesh_models/model_common.c +++ b/components/bt/ble_mesh/mesh_models/model_common.c @@ -16,6 +16,7 @@ #include #include "osi/allocator.h" +#include "osi/mutex.h" #include "mesh_access.h" #include "mesh_buf.h" @@ -222,6 +223,28 @@ int bt_mesh_client_send_msg(struct bt_mesh_model *model, return err; } +static osi_mutex_t client_model_mutex; + +static void bt_mesh_client_model_mutex_new(void) +{ + static bool init; + + if (!init) { + osi_mutex_new(&client_model_mutex); + init = true; + } +} + +void bt_mesh_client_model_lock(void) +{ + osi_mutex_lock(&client_model_mutex, OSI_MUTEX_MAX_TIMEOUT); +} + +void bt_mesh_client_model_unlock(void) +{ + osi_mutex_unlock(&client_model_mutex); +} + int bt_mesh_client_init(struct bt_mesh_model *model) { bt_mesh_internal_data_t *data = NULL; @@ -256,6 +279,8 @@ int bt_mesh_client_init(struct bt_mesh_model *model) cli->model = model; cli->internal_data = data; + bt_mesh_client_model_mutex_new(); + return 0; }