component/ble_mesh: fix duplicate memory free during client model receiving status

This commit is contained in:
lly
2019-09-08 16:00:59 +08:00
parent 3617160c39
commit c76c87c1d7
8 changed files with 268 additions and 49 deletions

View File

@@ -12,6 +12,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL)
@@ -82,6 +83,28 @@ static const bt_mesh_client_op_pair_t cfg_op_pair[] = {
{ OP_NET_TRANSMIT_SET, OP_NET_TRANSMIT_STATUS },
};
static osi_mutex_t cfg_client_mutex;
static void bt_mesh_cfg_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&cfg_client_mutex);
init = true;
}
}
static void bt_mesh_cfg_client_lock(void)
{
osi_mutex_lock(&cfg_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_cfg_client_unlock(void)
{
osi_mutex_unlock(&cfg_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
config_internal_data_t *internal = NULL;
@@ -108,10 +131,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_config_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_cfg_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_config_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_cfg_client_unlock();
return;
}
@@ -139,6 +168,9 @@ static void cfg_client_cancel(struct bt_mesh_model *model,
/* If it is a publish message, sent to the user directly. */
buf.data = (u8_t *)status;
buf.len = (u16_t)len;
bt_mesh_cfg_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, &buf, true);
if (!node) {
BT_DBG("Unexpected config status message 0x%x", ctx->recv_op);
@@ -199,12 +231,16 @@ static void cfg_client_cancel(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_config_status_to_btc(node->opcode, evt_type, model,
ctx, (const u8_t *)status, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&data->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_config_status_to_btc(node->opcode, evt_type, model,
ctx, (const u8_t *)status, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&data->queue, node);
}
}
bt_mesh_cfg_client_unlock();
switch (ctx->recv_op) {
case OP_DEV_COMP_DATA_STATUS: {
struct bt_mesh_cfg_comp_data_status *val;
@@ -1658,5 +1694,7 @@ int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary)
/* Configuration Model security is device-key based */
model->keys[0] = BLE_MESH_KEY_DEV;
bt_mesh_cfg_client_mutex_new();
return 0;
}

View File

@@ -12,6 +12,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL)
@@ -38,6 +39,28 @@ static const bt_mesh_client_op_pair_t health_op_pair[] = {
{ OP_ATTENTION_SET, OP_ATTENTION_STATUS },
};
static osi_mutex_t health_client_mutex;
static void bt_mesh_health_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&health_client_mutex);
init = true;
}
}
static void bt_mesh_health_client_lock(void)
{
osi_mutex_lock(&health_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_health_client_unlock(void)
{
osi_mutex_unlock(&health_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
health_internal_data_t *internal = NULL;
@@ -64,10 +87,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_health_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_health_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_health_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_health_client_unlock();
return;
}
@@ -95,6 +124,9 @@ static void health_client_cancel(struct bt_mesh_model *model,
/* If it is a publish message, sent to the user directly. */
buf.data = (u8_t *)status;
buf.len = (u16_t)len;
bt_mesh_health_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, &buf, true);
if (!node) {
BT_DBG("Unexpected health status message 0x%x", ctx->recv_op);
@@ -115,12 +147,16 @@ static void health_client_cancel(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_health_status_to_btc(node->opcode, evt_type, model,
ctx, (const u8_t *)status, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&data->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_health_status_to_btc(node->opcode, evt_type, model,
ctx, (const u8_t *)status, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&data->queue, node);
}
}
bt_mesh_health_client_unlock();
switch (ctx->recv_op) {
case OP_HEALTH_FAULT_STATUS: {
struct bt_mesh_health_fault_status *val;
@@ -454,6 +490,8 @@ int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary)
client->op_pair = health_op_pair;
client->internal_data = internal;
bt_mesh_health_client_mutex_new();
/* Set the default health client pointer */
if (!health_cli) {
health_cli = client;

View File

@@ -38,14 +38,6 @@ typedef struct alarm_t {
int64_t deadline_us;
} osi_alarm_t;
static void bt_mesh_alarm_cb(void *data)
{
assert(data != NULL);
struct k_delayed_work *work = (struct k_delayed_work *)data;
work->work.handler(&work->work);
return;
}
unsigned int bt_mesh_irq_lock(void)
{
#if defined(CONFIG_BLE_MESH_IRQ_LOCK) && CONFIG_BLE_MESH_IRQ_LOCK
@@ -111,7 +103,7 @@ void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
osi_mutex_lock(&bm_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) {
alarm = osi_alarm_new("bt_mesh", bt_mesh_alarm_cb, (void *)work, 0);
alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)work, 0);
if (alarm == NULL) {
BT_ERR("%s, Unable to create alarm", __func__);
return;

View File

@@ -17,6 +17,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#include "mesh_types.h"
@@ -119,6 +120,28 @@ static const bt_mesh_client_op_pair_t gen_op_pair[] = {
{ BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS },
};
static osi_mutex_t generic_client_mutex;
static void bt_mesh_generic_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&generic_client_mutex);
init = true;
}
}
static void bt_mesh_generic_client_lock(void)
{
osi_mutex_lock(&generic_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_generic_client_unlock(void)
{
osi_mutex_unlock(&generic_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
generic_internal_data_t *internal = NULL;
@@ -145,10 +168,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_generic_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_generic_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_generic_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_generic_client_unlock();
return;
}
@@ -542,6 +571,9 @@ static void generic_status(struct bt_mesh_model *model,
buf->data = val;
buf->len = len;
bt_mesh_generic_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected generic status message 0x%x", rsp);
@@ -587,11 +619,15 @@ static void generic_status(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_generic_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_generic_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
}
bt_mesh_generic_client_unlock();
switch (rsp) {
case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS: {
struct bt_mesh_gen_user_properties_status *status;
@@ -1188,6 +1224,8 @@ static int generic_client_init(struct bt_mesh_model *model, bool primary)
client->op_pair = gen_op_pair;
client->internal_data = internal;
bt_mesh_generic_client_mutex_new();
return 0;
}

View File

@@ -17,6 +17,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#include "mesh_types.h"
@@ -128,6 +129,28 @@ static const bt_mesh_client_op_pair_t light_op_pair[] = {
{ BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET, BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS },
};
static osi_mutex_t light_client_mutex;
static void bt_mesh_light_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&light_client_mutex);
init = true;
}
}
static void bt_mesh_light_client_lock(void)
{
osi_mutex_lock(&light_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_light_client_unlock(void)
{
osi_mutex_unlock(&light_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
light_internal_data_t *internal = NULL;
@@ -154,10 +177,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_light_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_light_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_light_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_light_client_unlock();
return;
}
@@ -651,6 +680,9 @@ static void light_status(struct bt_mesh_model *model,
buf->data = val;
buf->len = len;
bt_mesh_light_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected light status message 0x%x", rsp);
@@ -707,11 +739,15 @@ static void light_status(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_light_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_light_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
}
bt_mesh_light_client_unlock();
switch (rsp) {
case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS: {
struct bt_mesh_light_lc_property_status *status;
@@ -1372,6 +1408,8 @@ static int light_client_init(struct bt_mesh_model *model, bool primary)
client->op_pair = light_op_pair;
client->internal_data = internal;
bt_mesh_light_client_mutex_new();
return 0;
}

View File

@@ -262,11 +262,10 @@ int bt_mesh_client_init(struct bt_mesh_model *model)
int bt_mesh_client_free_node(sys_slist_t *queue, bt_mesh_client_node_t *node)
{
if (!queue || !node) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
// Free the node timer
k_delayed_work_free(&node->timer);
// Release the client node from the queue
sys_slist_find_and_remove(queue, &node->client_node);
// Free the node

View File

@@ -17,6 +17,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#include "mesh_types.h"
@@ -57,6 +58,28 @@ static const bt_mesh_client_op_pair_t sensor_op_pair[] = {
{ BLE_MESH_MODEL_OP_SENSOR_SERIES_GET, BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS },
};
static osi_mutex_t sensor_client_mutex;
static void bt_mesh_sensor_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&sensor_client_mutex);
init = true;
}
}
static void bt_mesh_sensor_client_lock(void)
{
osi_mutex_lock(&sensor_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_sensor_client_unlock(void)
{
osi_mutex_unlock(&sensor_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
sensor_internal_data_t *internal = NULL;
@@ -83,10 +106,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_sensor_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_sensor_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_sensor_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_sensor_client_unlock();
return;
}
@@ -269,6 +298,9 @@ static void sensor_status(struct bt_mesh_model *model,
buf->data = val;
buf->len = len;
bt_mesh_sensor_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected sensor status message 0x%x", rsp);
@@ -291,11 +323,15 @@ static void sensor_status(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_sensor_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_sensor_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
}
bt_mesh_sensor_client_unlock();
switch (rsp) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS: {
struct bt_mesh_sensor_descriptor_status *status;
@@ -619,5 +655,7 @@ int bt_mesh_sensor_cli_init(struct bt_mesh_model *model, bool primary)
client->op_pair = sensor_op_pair;
client->internal_data = internal;
bt_mesh_sensor_client_mutex_new();
return 0;
}

View File

@@ -17,6 +17,7 @@
#include <stdbool.h>
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "sdkconfig.h"
#include "mesh_types.h"
@@ -73,6 +74,28 @@ static const bt_mesh_client_op_pair_t time_scene_op_pair[] = {
{ BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET, BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS },
};
static osi_mutex_t time_scene_client_mutex;
static void bt_mesh_time_scene_client_mutex_new(void)
{
static bool init;
if (!init) {
osi_mutex_new(&time_scene_client_mutex);
init = true;
}
}
static void bt_mesh_time_scene_client_lock(void)
{
osi_mutex_lock(&time_scene_client_mutex, OSI_MUTEX_MAX_TIMEOUT);
}
static void bt_mesh_time_scene_client_unlock(void)
{
osi_mutex_unlock(&time_scene_client_mutex);
}
static void timeout_handler(struct k_work *work)
{
time_scene_internal_data_t *internal = NULL;
@@ -99,10 +122,16 @@ static void timeout_handler(struct k_work *work)
return;
}
bt_mesh_callback_time_scene_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_time_scene_client_lock();
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_time_scene_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
bt_mesh_time_scene_client_unlock();
return;
}
@@ -300,6 +329,9 @@ static void time_scene_status(struct bt_mesh_model *model,
buf->data = val;
buf->len = len;
bt_mesh_time_scene_client_lock();
node = bt_mesh_is_model_message_publish(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected time scene status message 0x%x", rsp);
@@ -329,11 +361,15 @@ static void time_scene_status(struct bt_mesh_model *model,
break;
}
bt_mesh_callback_time_scene_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_callback_time_scene_status_to_btc(node->opcode, evt, model, ctx, val, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&internal->queue, node);
}
}
bt_mesh_time_scene_client_unlock();
switch (rsp) {
case BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS: {
struct bt_mesh_scene_register_status *status;
@@ -676,6 +712,8 @@ static int time_scene_client_init(struct bt_mesh_model *model, bool primary)
client->op_pair = time_scene_op_pair;
client->internal_data = internal;
bt_mesh_time_scene_client_mutex_new();
return 0;
}