ble_mesh: Fix memory leak when node is reset
When node is being reset, the init functions of each sig-defined models will be invoked again, this will cause memory leak because some model internal data will be allocated again. Hence before trying to allocate memory for them, we add some check to make sure no memory has been allocated previously. And for client model, when the init functions are invoked again, we will clear the list items.
This commit is contained in:
parent
6c0044cc65
commit
3b9fe36494
9 changed files with 132 additions and 85 deletions
|
@ -1649,7 +1649,7 @@ int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(config_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("Allocate memory for Configuration Client internal data fail");
|
||||
|
@ -1662,6 +1662,9 @@ int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(cfg_op_pair);
|
||||
client->op_pair = cfg_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
cli = client;
|
||||
|
||||
|
|
|
@ -454,7 +454,7 @@ int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(health_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -467,6 +467,9 @@ int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(health_op_pair);
|
||||
client->op_pair = health_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_health_client_mutex_new();
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ int bt_mesh_client_init(struct bt_mesh_model *model)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked */
|
||||
if (!cli->internal_data) {
|
||||
data = osi_calloc(sizeof(bt_mesh_client_internal_data_t));
|
||||
if (!data) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -278,6 +278,9 @@ int bt_mesh_client_init(struct bt_mesh_model *model)
|
|||
|
||||
cli->model = model;
|
||||
cli->internal_data = data;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(cli->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_client_model_mutex_new();
|
||||
|
||||
|
@ -316,6 +319,28 @@ int bt_mesh_client_free_node(bt_mesh_client_node_t *node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_client_clear_list(void *data)
|
||||
{
|
||||
bt_mesh_client_internal_data_t *internal = NULL;
|
||||
bt_mesh_client_node_t *node = NULL;
|
||||
|
||||
if (!data) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
internal = (bt_mesh_client_internal_data_t *)data;
|
||||
|
||||
bt_mesh_list_lock();
|
||||
while (!sys_slist_is_empty(&internal->queue)) {
|
||||
node = (void *)sys_slist_get_not_empty(&internal->queue);
|
||||
osi_free(node);
|
||||
}
|
||||
bt_mesh_list_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_set_client_model_role(bt_mesh_role_param_t *common)
|
||||
{
|
||||
bt_mesh_client_user_data_t *client = NULL;
|
||||
|
|
|
@ -1172,7 +1172,7 @@ static int generic_client_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(generic_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -1185,6 +1185,9 @@ static int generic_client_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(gen_op_pair);
|
||||
client->op_pair = gen_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_generic_client_mutex_new();
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ int bt_mesh_client_send_msg(struct bt_mesh_model *model,
|
|||
|
||||
int bt_mesh_client_free_node(bt_mesh_client_node_t *node);
|
||||
|
||||
int bt_mesh_client_clear_list(void *data);
|
||||
|
||||
enum {
|
||||
NODE = 0,
|
||||
PROVISIONER,
|
||||
|
|
|
@ -1362,7 +1362,7 @@ static int light_client_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(light_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -1375,6 +1375,9 @@ static int light_client_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(light_op_pair);
|
||||
client->op_pair = light_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_light_client_mutex_new();
|
||||
|
||||
|
|
|
@ -604,7 +604,7 @@ int bt_mesh_sensor_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(sensor_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -617,6 +617,9 @@ int bt_mesh_sensor_cli_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(sensor_op_pair);
|
||||
client->op_pair = sensor_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_sensor_client_mutex_new();
|
||||
|
||||
|
|
|
@ -667,7 +667,7 @@ static int time_scene_client_init(struct bt_mesh_model *model, bool primary)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: call osi_free() when deinit function is invoked*/
|
||||
if (!client->internal_data) {
|
||||
internal = osi_calloc(sizeof(time_scene_internal_data_t));
|
||||
if (!internal) {
|
||||
BT_ERR("%s, Failed to allocate memory", __func__);
|
||||
|
@ -680,6 +680,9 @@ static int time_scene_client_init(struct bt_mesh_model *model, bool primary)
|
|||
client->op_pair_size = ARRAY_SIZE(time_scene_op_pair);
|
||||
client->op_pair = time_scene_op_pair;
|
||||
client->internal_data = internal;
|
||||
} else {
|
||||
bt_mesh_client_clear_list(client->internal_data);
|
||||
}
|
||||
|
||||
bt_mesh_time_scene_client_mutex_new();
|
||||
|
||||
|
|
|
@ -193,8 +193,10 @@ void bt_mesh_server_alloc_ctx(struct k_work *work)
|
|||
* Here we use the allocated heap memory to store the "struct bt_mesh_msg_ctx".
|
||||
*/
|
||||
__ASSERT(work, "%s, Invalid parameter", __func__);
|
||||
if (!work->_reserved) {
|
||||
work->_reserved = osi_calloc(sizeof(struct bt_mesh_msg_ctx));
|
||||
__ASSERT(work->_reserved, "%s, Failed to allocate memory", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last,
|
||||
|
|
Loading…
Reference in a new issue