diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c index fcba1f4b51..935918e7b1 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c @@ -107,9 +107,11 @@ esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param) btc_msg_t msg = {0}; if (!scan_param) { - return ESP_FAIL; + return ESP_ERR_INVALID_ARG; } + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_BLE_MESH_BLE_COEX; msg.act = BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS; diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c index eaa1868133..f96c29046e 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c @@ -35,6 +35,7 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp // Create a semaphore if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) { BT_ERR("Failed to create semaphore"); + bt_mesh_host_deinit(); return ESP_ERR_NO_MEM; } @@ -50,6 +51,7 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) != BT_STATUS_SUCCESS) { vSemaphoreDelete(semaphore); BT_ERR("Failed to start mesh init"); + bt_mesh_host_deinit(); return ESP_FAIL; } diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c index daa7e00ab0..ac8ecece65 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c @@ -121,7 +121,7 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model, bt_mesh_model_msg_init(model->pub->msg, opcode); net_buf_simple_add_mem(model->pub->msg, data, length); } else { - msg_data = (uint8_t *)bt_mesh_malloc(op_len + length); + msg_data = (uint8_t *)bt_mesh_calloc(op_len + length); if (msg_data == NULL) { return ESP_ERR_NO_MEM; } diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 01ade02668..a2ffb4309e 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -1249,7 +1249,7 @@ typedef union { * @brief ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT */ struct ble_mesh_output_str_evt_param { - char string[8]; /*!< String of Output OOB Authentication */ + char string[ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN + 1]; /*!< String of Output OOB Authentication */ } node_prov_output_str; /*!< Event parameter of ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT */ /** * @brief ESP_BLE_MESH_NODE_PROV_INPUT_EVT @@ -1402,7 +1402,7 @@ typedef union { uint8_t link_idx; /*!< Index of the provisioning link */ /** Union of output OOB */ union { - char string[8]; /*!< String output by the Provisioner */ + char string[ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN + 1]; /*!< String output by the Provisioner */ uint32_t number; /*!< Number output by the Provisioner */ }; } provisioner_prov_output; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_PROV_OUTPUT_EVT */ diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c index c1802e1137..3d6f53f556 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c @@ -38,7 +38,10 @@ void btc_ble_mesh_config_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void switch (msg->act) { case BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE: { - dst->cfg_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + dst->cfg_client_get_state.params = NULL; + dst->cfg_client_get_state.get_state = NULL; + + dst->cfg_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->cfg_client_get_state.params) { memcpy(dst->cfg_client_get_state.params, src->cfg_client_get_state.params, sizeof(esp_ble_mesh_client_common_param_t)); @@ -47,18 +50,24 @@ void btc_ble_mesh_config_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void break; } if (src->cfg_client_get_state.get_state) { - dst->cfg_client_get_state.get_state = (esp_ble_mesh_cfg_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_cfg_client_get_state_t)); + dst->cfg_client_get_state.get_state = (esp_ble_mesh_cfg_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_cfg_client_get_state_t)); if (dst->cfg_client_get_state.get_state) { memcpy(dst->cfg_client_get_state.get_state, src->cfg_client_get_state.get_state, sizeof(esp_ble_mesh_cfg_client_get_state_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->cfg_client_get_state.params); + dst->cfg_client_get_state.params = NULL; } } break; } case BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE: { - dst->cfg_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + dst->cfg_client_set_state.params = NULL; + dst->cfg_client_set_state.set_state = NULL; + + dst->cfg_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->cfg_client_set_state.params) { memcpy(dst->cfg_client_set_state.params, src->cfg_client_set_state.params, sizeof(esp_ble_mesh_client_common_param_t)); @@ -67,12 +76,15 @@ void btc_ble_mesh_config_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void break; } if (src->cfg_client_set_state.set_state) { - dst->cfg_client_set_state.set_state = (esp_ble_mesh_cfg_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_cfg_client_set_state_t)); + dst->cfg_client_set_state.set_state = (esp_ble_mesh_cfg_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_cfg_client_set_state_t)); if (dst->cfg_client_set_state.set_state) { memcpy(dst->cfg_client_set_state.set_state, src->cfg_client_set_state.set_state, sizeof(esp_ble_mesh_cfg_client_set_state_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->cfg_client_set_state.params); + dst->cfg_client_set_state.params = NULL; } } break; @@ -128,7 +140,7 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -150,6 +162,9 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.comp_data_status.composition_data = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.comp_data_status.composition_data) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.comp_data_status.composition_data, @@ -166,6 +181,9 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.model_sub_list.sub_addr = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.model_sub_list.sub_addr) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.model_sub_list.sub_addr, @@ -180,6 +198,9 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.netkey_list.net_idx = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.netkey_list.net_idx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.netkey_list.net_idx, @@ -194,6 +215,9 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.appkey_list.app_idx = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.appkey_list.app_idx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.appkey_list.app_idx, @@ -210,6 +234,9 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.model_app_list.app_idx = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.model_app_list.app_idx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.model_app_list.app_idx, diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_generic_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_generic_model.c index b6680f9978..3826eba012 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_generic_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_generic_model.c @@ -39,7 +39,10 @@ void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, voi switch (msg->act) { case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE: { - dst->generic_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + dst->generic_client_get_state.params = NULL; + dst->generic_client_get_state.get_state = NULL; + + dst->generic_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->generic_client_get_state.params) { memcpy(dst->generic_client_get_state.params, src->generic_client_get_state.params, sizeof(esp_ble_mesh_client_common_param_t)); @@ -48,57 +51,82 @@ void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, voi break; } if (src->generic_client_get_state.get_state) { - dst->generic_client_get_state.get_state = (esp_ble_mesh_generic_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_generic_client_get_state_t)); + dst->generic_client_get_state.get_state = (esp_ble_mesh_generic_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_generic_client_get_state_t)); if (dst->generic_client_get_state.get_state) { memcpy(dst->generic_client_get_state.get_state, src->generic_client_get_state.get_state, sizeof(esp_ble_mesh_generic_client_get_state_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->generic_client_get_state.params); + dst->generic_client_get_state.params = NULL; } } break; } case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE: { - dst->generic_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->generic_client_set_state.set_state = (esp_ble_mesh_generic_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_generic_client_set_state_t)); - if (dst->generic_client_set_state.params && dst->generic_client_set_state.set_state) { - memcpy(dst->generic_client_set_state.params, src->generic_client_set_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->generic_client_set_state.set_state, src->generic_client_set_state.set_state, - sizeof(esp_ble_mesh_generic_client_set_state_t)); + dst->generic_client_set_state.params = NULL; + dst->generic_client_set_state.set_state = NULL; - switch (src->generic_client_set_state.params->opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET: - if (src->generic_client_set_state.set_state->user_property_set.property_value) { - length = src->generic_client_set_state.set_state->user_property_set.property_value->len; - dst->generic_client_set_state.set_state->user_property_set.property_value = bt_mesh_alloc_buf(length); - if (!dst->generic_client_set_state.set_state->user_property_set.property_value) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->generic_client_set_state.set_state->user_property_set.property_value, - src->generic_client_set_state.set_state->user_property_set.property_value->data, - src->generic_client_set_state.set_state->user_property_set.property_value->len); - } - break; - case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET: - if (src->generic_client_set_state.set_state->admin_property_set.property_value) { - length = src->generic_client_set_state.set_state->admin_property_set.property_value->len; - dst->generic_client_set_state.set_state->admin_property_set.property_value = bt_mesh_alloc_buf(length); - if (!dst->generic_client_set_state.set_state->admin_property_set.property_value) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->generic_client_set_state.set_state->admin_property_set.property_value, - src->generic_client_set_state.set_state->admin_property_set.property_value->data, - src->generic_client_set_state.set_state->admin_property_set.property_value->len); - } - break; - default: - break; - } - } else { + dst->generic_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->generic_client_set_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; + } + + dst->generic_client_set_state.set_state = (esp_ble_mesh_generic_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_generic_client_set_state_t)); + if (!dst->generic_client_set_state.set_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->generic_client_set_state.params); + dst->generic_client_set_state.params = NULL; + break; + } + + memcpy(dst->generic_client_set_state.params, src->generic_client_set_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->generic_client_set_state.set_state, src->generic_client_set_state.set_state, + sizeof(esp_ble_mesh_generic_client_set_state_t)); + + switch (src->generic_client_set_state.params->opcode) { + case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET: + if (src->generic_client_set_state.set_state->user_property_set.property_value) { + length = src->generic_client_set_state.set_state->user_property_set.property_value->len; + dst->generic_client_set_state.set_state->user_property_set.property_value = bt_mesh_alloc_buf(length); + if (!dst->generic_client_set_state.set_state->user_property_set.property_value) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->generic_client_set_state.params); + dst->generic_client_set_state.params = NULL; + bt_mesh_free(dst->generic_client_set_state.set_state); + dst->generic_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->generic_client_set_state.set_state->user_property_set.property_value, + src->generic_client_set_state.set_state->user_property_set.property_value->data, + src->generic_client_set_state.set_state->user_property_set.property_value->len); + } + break; + case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET: + if (src->generic_client_set_state.set_state->admin_property_set.property_value) { + length = src->generic_client_set_state.set_state->admin_property_set.property_value->len; + dst->generic_client_set_state.set_state->admin_property_set.property_value = bt_mesh_alloc_buf(length); + if (!dst->generic_client_set_state.set_state->admin_property_set.property_value) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->generic_client_set_state.params); + dst->generic_client_set_state.params = NULL; + bt_mesh_free(dst->generic_client_set_state.set_state); + dst->generic_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->generic_client_set_state.set_state->admin_property_set.property_value, + src->generic_client_set_state.set_state->admin_property_set.property_value->data, + src->generic_client_set_state.set_state->admin_property_set.property_value->len); + } + break; + default: + break; } break; } @@ -165,7 +193,7 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -187,6 +215,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.user_properties_status.property_ids = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.user_properties_status.property_ids) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.user_properties_status.property_ids, @@ -202,6 +233,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.user_property_status.property_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.user_property_status.property_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.user_property_status.property_value, @@ -216,6 +250,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.admin_properties_status.property_ids = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.admin_properties_status.property_ids) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.admin_properties_status.property_ids, @@ -231,6 +268,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.admin_property_status.property_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.admin_property_status.property_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.admin_property_status.property_value, @@ -245,6 +285,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.manufacturer_properties_status.property_ids = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.manufacturer_properties_status.property_ids) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_properties_status.property_ids, @@ -260,6 +303,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.manufacturer_property_status.property_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.manufacturer_property_status.property_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_property_status.property_value, @@ -274,6 +320,9 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de p_dest_data->status_cb.client_properties_status.property_ids = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.client_properties_status.property_ids) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.client_properties_status.property_ids, diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_health_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_health_model.c index 75ae22c208..f23ac1e280 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_health_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_health_model.c @@ -38,7 +38,10 @@ void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void switch (msg->act) { case BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE: { - dst->health_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + dst->health_client_get_state.params = NULL; + dst->health_client_get_state.get_state = NULL; + + dst->health_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->health_client_get_state.params) { memcpy(dst->health_client_get_state.params, src->health_client_get_state.params, sizeof(esp_ble_mesh_client_common_param_t)); @@ -47,27 +50,41 @@ void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void break; } if (src->health_client_get_state.get_state) { - dst->health_client_get_state.get_state = (esp_ble_mesh_health_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_health_client_get_state_t)); + dst->health_client_get_state.get_state = (esp_ble_mesh_health_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_health_client_get_state_t)); if (dst->health_client_get_state.get_state) { memcpy(dst->health_client_get_state.get_state, src->health_client_get_state.get_state, sizeof(esp_ble_mesh_health_client_get_state_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->health_client_get_state.params); + dst->health_client_get_state.params = NULL; } } break; } case BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE: { - dst->health_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->health_client_set_state.set_state = (esp_ble_mesh_health_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_health_client_set_state_t)); - if (dst->health_client_set_state.params && dst->health_client_set_state.set_state) { - memcpy(dst->health_client_set_state.params, src->health_client_set_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->health_client_set_state.set_state, src->health_client_set_state.set_state, - sizeof(esp_ble_mesh_health_client_set_state_t)); - } else { + dst->health_client_set_state.params = NULL; + dst->health_client_set_state.set_state = NULL; + + dst->health_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->health_client_set_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + memcpy(dst->health_client_set_state.params, src->health_client_set_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + + dst->health_client_set_state.set_state = (esp_ble_mesh_health_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_health_client_set_state_t)); + if (!dst->health_client_set_state.set_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->health_client_set_state.params); + dst->health_client_set_state.params = NULL; + break; + } + memcpy(dst->health_client_set_state.set_state, src->health_client_set_state.set_state, + sizeof(esp_ble_mesh_health_client_set_state_t)); break; } default: @@ -121,7 +138,7 @@ static void btc_ble_mesh_health_client_copy_req_data(btc_msg_t *msg, void *p_des } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -142,6 +159,9 @@ static void btc_ble_mesh_health_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.current_status.fault_array = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.current_status.fault_array) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.current_status.fault_array, @@ -158,6 +178,9 @@ static void btc_ble_mesh_health_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.fault_status.fault_array = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.fault_status.fault_array) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.fault_status.fault_array, diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c index 3195c513f5..d82b5f1204 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c @@ -38,7 +38,10 @@ void btc_ble_mesh_lighting_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, vo switch (msg->act) { case BTC_BLE_MESH_ACT_LIGHTING_CLIENT_GET_STATE: { - dst->light_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + dst->light_client_get_state.params = NULL; + dst->light_client_get_state.get_state = NULL; + + dst->light_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->light_client_get_state.params) { memcpy(dst->light_client_get_state.params, src->light_client_get_state.params, sizeof(esp_ble_mesh_client_common_param_t)); @@ -47,27 +50,42 @@ void btc_ble_mesh_lighting_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, vo break; } if (src->light_client_get_state.get_state) { - dst->light_client_get_state.get_state = (esp_ble_mesh_light_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_light_client_get_state_t)); + dst->light_client_get_state.get_state = (esp_ble_mesh_light_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_light_client_get_state_t)); if (dst->light_client_get_state.get_state) { memcpy(dst->light_client_get_state.get_state, src->light_client_get_state.get_state, - sizeof(esp_ble_mesh_light_client_get_state_t)); + sizeof(esp_ble_mesh_light_client_get_state_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->light_client_get_state.params); + dst->light_client_get_state.params = NULL; } } break; } case BTC_BLE_MESH_ACT_LIGHTING_CLIENT_SET_STATE: { - dst->light_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->light_client_set_state.set_state = (esp_ble_mesh_light_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_light_client_set_state_t)); - if (dst->light_client_set_state.params && dst->light_client_set_state.set_state) { - memcpy(dst->light_client_set_state.params, src->light_client_set_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->light_client_set_state.set_state, src->light_client_set_state.set_state, - sizeof(esp_ble_mesh_light_client_set_state_t)); - } else { + dst->light_client_set_state.params = NULL; + dst->light_client_set_state.set_state = NULL; + + dst->light_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->light_client_set_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + + dst->light_client_set_state.set_state = (esp_ble_mesh_light_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_light_client_set_state_t)); + if (!dst->light_client_set_state.set_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->light_client_set_state.params); + dst->light_client_set_state.params = NULL; + break; + } + + memcpy(dst->light_client_set_state.params, src->light_client_set_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->light_client_set_state.set_state, src->light_client_set_state.set_state, + sizeof(esp_ble_mesh_light_client_set_state_t)); break; } default: @@ -121,7 +139,7 @@ static void btc_ble_mesh_lighting_client_copy_req_data(btc_msg_t *msg, void *p_d } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -144,6 +162,9 @@ static void btc_ble_mesh_lighting_client_copy_req_data(btc_msg_t *msg, void *p_d p_dest_data->status_cb.lc_property_status.property_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.lc_property_status.property_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.lc_property_status.property_value, diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 49ae1d5dda..5e5bbe30c3 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -206,9 +206,10 @@ static void btc_ble_mesh_prov_copy_req_data(btc_msg_t *msg, void *p_dest, void * switch (msg->act) { #if CONFIG_BLE_MESH_CERT_BASED_PROV - case ESP_BLE_MESH_PROVISIONER_RECV_PROV_RECORDS_LIST_EVT: { - if (p_src_data->recv_provisioner_records_list.msg) { - p_dest_data->recv_provisioner_records_list.msg = (uint8_t *)bt_mesh_alloc_buf(p_src_data->recv_provisioner_records_list.len); + case ESP_BLE_MESH_PROVISIONER_RECV_PROV_RECORDS_LIST_EVT: + if (p_src_data->recv_provisioner_records_list.msg && + p_src_data->recv_provisioner_records_list.len) { + p_dest_data->recv_provisioner_records_list.msg = (uint8_t *)bt_mesh_calloc(p_src_data->recv_provisioner_records_list.len); if (!p_dest_data->recv_provisioner_records_list.msg) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -219,7 +220,20 @@ static void btc_ble_mesh_prov_copy_req_data(btc_msg_t *msg, void *p_dest, void * p_src_data->recv_provisioner_records_list.len); } break; - } + case ESP_BLE_MESH_PROVISIONER_PROV_RECORD_RECV_COMP_EVT: + if (p_src_data->provisioner_prov_record_recv_comp.record && + p_src_data->provisioner_prov_record_recv_comp.total_len) { + p_dest_data->provisioner_prov_record_recv_comp.record = bt_mesh_calloc(p_src_data->provisioner_prov_record_recv_comp.total_len); + if (!p_dest_data->provisioner_prov_record_recv_comp.record) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + return; + } + + memcpy(p_dest_data->provisioner_prov_record_recv_comp.record, + p_src_data->provisioner_prov_record_recv_comp.record, + p_src_data->provisioner_prov_record_recv_comp.total_len); + } + break; #endif /* CONFIG_BLE_MESH_CERT_BASED_PROV */ default: break; @@ -239,13 +253,17 @@ static void btc_ble_mesh_prov_free_req_data(btc_msg_t *msg) switch (msg->act) { #if CONFIG_BLE_MESH_CERT_BASED_PROV - case ESP_BLE_MESH_PROVISIONER_RECV_PROV_RECORDS_LIST_EVT: { + case ESP_BLE_MESH_PROVISIONER_RECV_PROV_RECORDS_LIST_EVT: if (arg->recv_provisioner_records_list.msg) { bt_mesh_free(arg->recv_provisioner_records_list.msg); } break; - } -#else + case ESP_BLE_MESH_PROVISIONER_PROV_RECORD_RECV_COMP_EVT: + if (arg->provisioner_prov_record_recv_comp.record) { + bt_mesh_free(arg->provisioner_prov_record_recv_comp.record); + } + break; +#else /* CONFIG_BLE_MESH_CERT_BASED_PROV */ ARG_UNUSED(arg); #endif /* CONFIG_BLE_MESH_CERT_BASED_PROV */ default: @@ -266,24 +284,33 @@ void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) switch (msg->act) { case BTC_BLE_MESH_ACT_SERVER_MODEL_SEND: case BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND: { - dst->model_send.data = src->model_send.length ? (uint8_t *)bt_mesh_malloc(src->model_send.length) : NULL; - dst->model_send.ctx = bt_mesh_malloc(sizeof(esp_ble_mesh_msg_ctx_t)); + dst->model_send.data = NULL; + dst->model_send.ctx = NULL; + if (src->model_send.length) { - if (dst->model_send.data) { - memcpy(dst->model_send.data, src->model_send.data, src->model_send.length); - } else { + dst->model_send.data = (uint8_t *)bt_mesh_calloc(src->model_send.length); + if (!dst->model_send.data) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + memcpy(dst->model_send.data, src->model_send.data, src->model_send.length); } - if (dst->model_send.ctx) { - memcpy(dst->model_send.ctx, src->model_send.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); - } else { + + dst->model_send.ctx = bt_mesh_calloc(sizeof(esp_ble_mesh_msg_ctx_t)); + if (!dst->model_send.ctx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->model_send.data) { + bt_mesh_free(dst->model_send.data); + dst->model_send.data = NULL; + } + break; } + memcpy(dst->model_send.ctx, src->model_send.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); break; } case BTC_BLE_MESH_ACT_SERVER_MODEL_UPDATE_STATE: - dst->model_update_state.value = bt_mesh_malloc(sizeof(esp_ble_mesh_server_state_value_t)); + dst->model_update_state.value = bt_mesh_calloc(sizeof(esp_ble_mesh_server_state_value_t)); if (dst->model_update_state.value) { memcpy(dst->model_update_state.value, src->model_update_state.value, sizeof(esp_ble_mesh_server_state_value_t)); @@ -340,46 +367,70 @@ static void btc_ble_mesh_model_copy_req_data(btc_msg_t *msg, void *p_dest, void switch (msg->act) { case ESP_BLE_MESH_MODEL_OPERATION_EVT: { - if (p_src_data->model_operation.ctx && p_src_data->model_operation.msg) { - p_dest_data->model_operation.ctx = bt_mesh_malloc(sizeof(esp_ble_mesh_msg_ctx_t)); - p_dest_data->model_operation.msg = p_src_data->model_operation.length ? (uint8_t *)bt_mesh_malloc(p_src_data->model_operation.length) : NULL; - if (p_dest_data->model_operation.ctx) { - memcpy(p_dest_data->model_operation.ctx, p_src_data->model_operation.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); - } else { + p_dest_data->model_operation.ctx = NULL; + p_dest_data->model_operation.msg = NULL; + + if (p_src_data->model_operation.ctx) { + p_dest_data->model_operation.ctx = bt_mesh_calloc(sizeof(esp_ble_mesh_msg_ctx_t)); + if (!p_dest_data->model_operation.ctx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } - if (p_src_data->model_operation.length) { - if (p_dest_data->model_operation.msg) { - memcpy(p_dest_data->model_operation.msg, p_src_data->model_operation.msg, p_src_data->model_operation.length); - } else { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + memcpy(p_dest_data->model_operation.ctx, p_src_data->model_operation.ctx, + sizeof(esp_ble_mesh_msg_ctx_t)); + } + + if (p_src_data->model_operation.msg && + p_src_data->model_operation.length) { + p_dest_data->model_operation.msg = (uint8_t *)bt_mesh_calloc(p_src_data->model_operation.length); + if (!p_dest_data->model_operation.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (p_dest_data->model_operation.ctx) { + bt_mesh_free(p_dest_data->model_operation.ctx); + p_dest_data->model_operation.ctx = NULL; } + break; } + memcpy(p_dest_data->model_operation.msg, p_src_data->model_operation.msg, + p_src_data->model_operation.length); } break; } case ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT: { - if (p_src_data->client_recv_publish_msg.ctx && p_src_data->client_recv_publish_msg.msg) { - p_dest_data->client_recv_publish_msg.ctx = bt_mesh_malloc(sizeof(esp_ble_mesh_msg_ctx_t)); - p_dest_data->client_recv_publish_msg.msg = p_src_data->client_recv_publish_msg.length ? (uint8_t *)bt_mesh_malloc(p_src_data->client_recv_publish_msg.length) : NULL; - if (p_dest_data->client_recv_publish_msg.ctx) { - memcpy(p_dest_data->client_recv_publish_msg.ctx, p_src_data->client_recv_publish_msg.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); - } else { + p_dest_data->client_recv_publish_msg.ctx = NULL; + p_dest_data->client_recv_publish_msg.msg = NULL; + + if (p_src_data->client_recv_publish_msg.ctx) { + p_dest_data->client_recv_publish_msg.ctx = bt_mesh_calloc(sizeof(esp_ble_mesh_msg_ctx_t)); + if (!p_dest_data->client_recv_publish_msg.ctx) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } - if (p_src_data->client_recv_publish_msg.length) { - if (p_dest_data->client_recv_publish_msg.msg) { - memcpy(p_dest_data->client_recv_publish_msg.msg, p_src_data->client_recv_publish_msg.msg, p_src_data->client_recv_publish_msg.length); - } else { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + memcpy(p_dest_data->client_recv_publish_msg.ctx, p_src_data->client_recv_publish_msg.ctx, + sizeof(esp_ble_mesh_msg_ctx_t)); + } + + if (p_src_data->client_recv_publish_msg.msg && + p_src_data->client_recv_publish_msg.length) { + p_dest_data->client_recv_publish_msg.msg = (uint8_t *)bt_mesh_calloc(p_src_data->client_recv_publish_msg.length); + if (!p_dest_data->client_recv_publish_msg.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (p_dest_data->client_recv_publish_msg.ctx) { + bt_mesh_free(p_dest_data->client_recv_publish_msg.ctx); + p_dest_data->client_recv_publish_msg.ctx = NULL; } + break; } + memcpy(p_dest_data->client_recv_publish_msg.msg, p_src_data->client_recv_publish_msg.msg, + p_src_data->client_recv_publish_msg.length); } break; } case ESP_BLE_MESH_MODEL_SEND_COMP_EVT: { if (p_src_data->model_send_comp.ctx) { - p_dest_data->model_send_comp.ctx = bt_mesh_malloc(sizeof(esp_ble_mesh_msg_ctx_t)); + p_dest_data->model_send_comp.ctx = bt_mesh_calloc(sizeof(esp_ble_mesh_msg_ctx_t)); if (p_dest_data->model_send_comp.ctx) { memcpy(p_dest_data->model_send_comp.ctx, p_src_data->model_send_comp.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); } else { @@ -390,7 +441,7 @@ static void btc_ble_mesh_model_copy_req_data(btc_msg_t *msg, void *p_dest, void } case ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT: { if (p_src_data->client_send_timeout.ctx) { - p_dest_data->client_send_timeout.ctx = bt_mesh_malloc(sizeof(esp_ble_mesh_msg_ctx_t)); + p_dest_data->client_send_timeout.ctx = bt_mesh_calloc(sizeof(esp_ble_mesh_msg_ctx_t)); if (p_dest_data->client_send_timeout.ctx) { memcpy(p_dest_data->client_send_timeout.ctx, p_src_data->client_send_timeout.ctx, sizeof(esp_ble_mesh_msg_ctx_t)); } else { @@ -654,6 +705,7 @@ static int btc_ble_mesh_output_string_cb(const char *str) esp_ble_mesh_prov_cb_param_t mesh_param = {0}; bt_status_t ret = BT_STATUS_SUCCESS; + memset(mesh_param.node_prov_output_str.string, 0, sizeof(mesh_param.node_prov_output_str.string)); strncpy(mesh_param.node_prov_output_str.string, str, MIN(strlen(str), sizeof(mesh_param.node_prov_output_str.string))); @@ -2987,6 +3039,12 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg) break; } case BTC_BLE_MESH_ACT_SERVER_MODEL_SEND: { + assert(arg->model_send.model); + assert(arg->model_send.ctx); + if (arg->model_send.length) { + assert(arg->model_send.data); + } + /* arg->model_send.length contains opcode & payload, plus extra 4-bytes TransMIC */ struct net_buf_simple *buf = bt_mesh_alloc_buf(arg->model_send.length + BLE_MESH_MIC_SHORT); if (!buf) { @@ -3007,6 +3065,12 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg) break; } case BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND: { + assert(arg->model_send.model); + assert(arg->model_send.ctx); + if (arg->model_send.length) { + assert(arg->model_send.data); + } + /* arg->model_send.length contains opcode & message, plus extra 4-bytes TransMIC */ struct net_buf_simple *buf = bt_mesh_alloc_buf(arg->model_send.length + BLE_MESH_MIC_SHORT); if (!buf) { diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c index 0a29fe9049..015e108c38 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c @@ -39,134 +39,244 @@ void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void switch (msg->act) { case BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE: { - dst->sensor_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->sensor_client_get_state.get_state = (esp_ble_mesh_sensor_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_sensor_client_get_state_t)); - if (dst->sensor_client_get_state.params && dst->sensor_client_get_state.get_state) { - memcpy(dst->sensor_client_get_state.params, src->sensor_client_get_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->sensor_client_get_state.get_state, src->sensor_client_get_state.get_state, - sizeof(esp_ble_mesh_sensor_client_get_state_t)); + dst->sensor_client_get_state.params = NULL; + dst->sensor_client_get_state.get_state = NULL; - switch (src->sensor_client_get_state.params->opcode) { - case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET: - if (src->sensor_client_get_state.get_state->column_get.raw_value_x) { - length = src->sensor_client_get_state.get_state->column_get.raw_value_x->len; - dst->sensor_client_get_state.get_state->column_get.raw_value_x = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_get_state.get_state->column_get.raw_value_x) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->column_get.raw_value_x, - src->sensor_client_get_state.get_state->column_get.raw_value_x->data, - src->sensor_client_get_state.get_state->column_get.raw_value_x->len); - } - break; - case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET: - if (src->sensor_client_get_state.get_state->series_get.raw_value_x1) { - length = src->sensor_client_get_state.get_state->series_get.raw_value_x1->len; - dst->sensor_client_get_state.get_state->series_get.raw_value_x1 = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x1) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x1, - src->sensor_client_get_state.get_state->series_get.raw_value_x1->data, - src->sensor_client_get_state.get_state->series_get.raw_value_x1->len); - } - if (src->sensor_client_get_state.get_state->series_get.raw_value_x2) { - length = src->sensor_client_get_state.get_state->series_get.raw_value_x2->len; - dst->sensor_client_get_state.get_state->series_get.raw_value_x2 = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x2) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x2, - src->sensor_client_get_state.get_state->series_get.raw_value_x2->data, - src->sensor_client_get_state.get_state->series_get.raw_value_x2->len); - } - break; - default: - break; - } - } else { + dst->sensor_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->sensor_client_get_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + return; + } + + dst->sensor_client_get_state.get_state = (esp_ble_mesh_sensor_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_sensor_client_get_state_t)); + if (!dst->sensor_client_get_state.get_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sensor_client_get_state.params); + dst->sensor_client_get_state.params = NULL; + return; + } + + memcpy(dst->sensor_client_get_state.params, src->sensor_client_get_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->sensor_client_get_state.get_state, src->sensor_client_get_state.get_state, + sizeof(esp_ble_mesh_sensor_client_get_state_t)); + + switch (src->sensor_client_get_state.params->opcode) { + case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET: + if (src->sensor_client_get_state.get_state->column_get.raw_value_x) { + length = src->sensor_client_get_state.get_state->column_get.raw_value_x->len; + dst->sensor_client_get_state.get_state->column_get.raw_value_x = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_get_state.get_state->column_get.raw_value_x) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sensor_client_get_state.params); + dst->sensor_client_get_state.params = NULL; + bt_mesh_free(dst->sensor_client_get_state.get_state); + dst->sensor_client_get_state.get_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->column_get.raw_value_x, + src->sensor_client_get_state.get_state->column_get.raw_value_x->data, + src->sensor_client_get_state.get_state->column_get.raw_value_x->len); + } + break; + case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET: + if (src->sensor_client_get_state.get_state->series_get.raw_value_x1) { + length = src->sensor_client_get_state.get_state->series_get.raw_value_x1->len; + dst->sensor_client_get_state.get_state->series_get.raw_value_x1 = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x1) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sensor_client_get_state.params); + dst->sensor_client_get_state.params = NULL; + bt_mesh_free(dst->sensor_client_get_state.get_state); + dst->sensor_client_get_state.get_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x1, + src->sensor_client_get_state.get_state->series_get.raw_value_x1->data, + src->sensor_client_get_state.get_state->series_get.raw_value_x1->len); + } + if (src->sensor_client_get_state.get_state->series_get.raw_value_x2) { + length = src->sensor_client_get_state.get_state->series_get.raw_value_x2->len; + dst->sensor_client_get_state.get_state->series_get.raw_value_x2 = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x2) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->sensor_client_get_state.get_state->series_get.raw_value_x1) { + bt_mesh_free_buf(dst->sensor_client_get_state.get_state->series_get.raw_value_x1); + dst->sensor_client_get_state.get_state->series_get.raw_value_x1 = NULL; + } + bt_mesh_free(dst->sensor_client_get_state.params); + dst->sensor_client_get_state.params = NULL; + bt_mesh_free(dst->sensor_client_get_state.get_state); + dst->sensor_client_get_state.get_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x2, + src->sensor_client_get_state.get_state->series_get.raw_value_x2->data, + src->sensor_client_get_state.get_state->series_get.raw_value_x2->len); + } + break; + default: + break; } break; } case BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE: { - dst->sensor_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->sensor_client_set_state.set_state = (esp_ble_mesh_sensor_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_sensor_client_set_state_t)); - if (dst->sensor_client_set_state.params && dst->sensor_client_set_state.set_state) { - memcpy(dst->sensor_client_set_state.params, src->sensor_client_set_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->sensor_client_set_state.set_state, src->sensor_client_set_state.set_state, - sizeof(esp_ble_mesh_sensor_client_set_state_t)); + dst->sensor_client_set_state.params = NULL; + dst->sensor_client_set_state.set_state = NULL; - switch (src->sensor_client_set_state.params->opcode) { - case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET: - if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { - length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len; - dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down, - src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->data, - src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len); - } - if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { - length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len; - dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up, - src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->data, - src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len); - } - if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { - length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len; - dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low, - src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->data, - src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len); - } - if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) { - length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len; - dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high, - src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->data, - src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len); - } - break; - case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET: - if (src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) { - length = src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len; - dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw = bt_mesh_alloc_buf(length); - if (!dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw, - src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->data, - src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len); - } - break; - default: - break; - } - } else { + dst->sensor_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->sensor_client_set_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + return; + } + + dst->sensor_client_set_state.set_state = (esp_ble_mesh_sensor_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_sensor_client_set_state_t)); + if (!dst->sensor_client_set_state.set_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + return; + } + + memcpy(dst->sensor_client_set_state.params, src->sensor_client_set_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->sensor_client_set_state.set_state, src->sensor_client_set_state.set_state, + sizeof(esp_ble_mesh_sensor_client_set_state_t)); + + switch (src->sensor_client_set_state.params->opcode) { + case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET: + if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len; + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + bt_mesh_free(dst->sensor_client_set_state.set_state); + dst->sensor_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down, + src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->data, + src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len); + } + if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { + length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len; + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = NULL; + } + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + bt_mesh_free(dst->sensor_client_set_state.set_state); + dst->sensor_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up, + src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->data, + src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len); + } + if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { + length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len; + dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = NULL; + } + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + bt_mesh_free(dst->sensor_client_set_state.set_state); + dst->sensor_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low, + src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->data, + src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len); + } + if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) { + length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len; + dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low); + dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low = NULL; + } + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + bt_mesh_free(dst->sensor_client_set_state.set_state); + dst->sensor_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high, + src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->data, + src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len); + } + break; + case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET: + if (src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) { + length = src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len; + dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw = bt_mesh_alloc_buf(length); + if (!dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up); + dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low); + dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low = NULL; + } + if (dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) { + bt_mesh_free_buf(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high); + dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high = NULL; + } + bt_mesh_free(dst->sensor_client_set_state.params); + dst->sensor_client_set_state.params = NULL; + bt_mesh_free(dst->sensor_client_set_state.set_state); + dst->sensor_client_set_state.set_state = NULL; + return; + } + net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw, + src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->data, + src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len); + } + break; + default: + break; } break; } @@ -249,7 +359,7 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -271,6 +381,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.descriptor_status.descriptor = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.descriptor_status.descriptor) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.descriptor_status.descriptor, @@ -286,6 +399,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.cadence_status.sensor_cadence_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.cadence_status.sensor_cadence_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.cadence_status.sensor_cadence_value, @@ -300,6 +416,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.settings_status.sensor_setting_property_ids = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.settings_status.sensor_setting_property_ids) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.settings_status.sensor_setting_property_ids, @@ -315,6 +434,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.setting_status.sensor_setting_raw = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.setting_status.sensor_setting_raw) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.setting_status.sensor_setting_raw, @@ -329,6 +451,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.sensor_status.marshalled_sensor_data = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.sensor_status.marshalled_sensor_data) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.sensor_status.marshalled_sensor_data, @@ -343,6 +468,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.column_status.sensor_column_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.column_status.sensor_column_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.column_status.sensor_column_value, @@ -357,6 +485,9 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des p_dest_data->status_cb.series_status.sensor_series_value = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.series_status.sensor_series_value) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.series_status.sensor_series_value, diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c index a8556a9023..234dd8edff 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c @@ -38,36 +38,53 @@ void btc_ble_mesh_time_scene_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, switch (msg->act) { case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE: { - dst->time_scene_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - if (dst->time_scene_client_get_state.params) { - memcpy(dst->time_scene_client_get_state.params, src->time_scene_client_get_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - } else { + dst->time_scene_client_get_state.params = NULL; + dst->time_scene_client_get_state.get_state = NULL; + + dst->time_scene_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->time_scene_client_get_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); break; } + memcpy(dst->time_scene_client_get_state.params, src->time_scene_client_get_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + if (src->time_scene_client_get_state.get_state) { - dst->time_scene_client_get_state.get_state = (esp_ble_mesh_time_scene_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_time_scene_client_get_state_t)); - if (dst->time_scene_client_get_state.get_state) { - memcpy(dst->time_scene_client_get_state.get_state, src->time_scene_client_get_state.get_state, - sizeof(esp_ble_mesh_time_scene_client_get_state_t)); - } else { + dst->time_scene_client_get_state.get_state = (esp_ble_mesh_time_scene_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_time_scene_client_get_state_t)); + if (!dst->time_scene_client_get_state.get_state) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->time_scene_client_get_state.params); + dst->time_scene_client_get_state.params = NULL; + break; } + memcpy(dst->time_scene_client_get_state.get_state, src->time_scene_client_get_state.get_state, + sizeof(esp_ble_mesh_time_scene_client_get_state_t)); } break; } case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE: { - dst->time_scene_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->time_scene_client_set_state.set_state = (esp_ble_mesh_time_scene_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_time_scene_client_set_state_t)); - if (dst->time_scene_client_set_state.params && dst->time_scene_client_set_state.set_state) { - memcpy(dst->time_scene_client_set_state.params, src->time_scene_client_set_state.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->time_scene_client_set_state.set_state, src->time_scene_client_set_state.set_state, - sizeof(esp_ble_mesh_time_scene_client_set_state_t)); - } else { + dst->time_scene_client_set_state.params = NULL; + dst->time_scene_client_set_state.set_state = NULL; + + dst->time_scene_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->time_scene_client_set_state.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + memcpy(dst->time_scene_client_set_state.params, src->time_scene_client_set_state.params, + sizeof(esp_ble_mesh_client_common_param_t)); + + dst->time_scene_client_set_state.set_state = (esp_ble_mesh_time_scene_client_set_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_time_scene_client_set_state_t)); + if (!dst->time_scene_client_set_state.set_state) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->time_scene_client_set_state.params); + dst->time_scene_client_set_state.params = NULL; + break; + } + memcpy(dst->time_scene_client_set_state.set_state, src->time_scene_client_set_state.set_state, + sizeof(esp_ble_mesh_time_scene_client_set_state_t)); break; } default: @@ -121,7 +138,7 @@ static void btc_ble_mesh_time_scene_client_copy_req_data(btc_msg_t *msg, void *p } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; @@ -145,6 +162,9 @@ static void btc_ble_mesh_time_scene_client_copy_req_data(btc_msg_t *msg, void *p p_dest_data->status_cb.scene_register_status.scenes = bt_mesh_alloc_buf(length); if (!p_dest_data->status_cb.scene_register_status.scenes) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } net_buf_simple_add_mem(p_dest_data->status_cb.scene_register_status.scenes, diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h index 741a6b313d..7b985a5b1e 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h @@ -115,7 +115,7 @@ typedef union { uint32_t number; } input_number; struct ble_mesh_node_input_str_args { - char string[8]; + char string[ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN + 1]; } input_string; struct ble_mesh_set_device_name_args { char name[ESP_BLE_MESH_DEVICE_NAME_MAX_LEN + 1]; @@ -141,7 +141,7 @@ typedef union { uint8_t pub_key_y[32]; } provisioner_read_oob_pub_key; struct ble_mesh_provisioner_input_str_args { - char string[8]; + char string[ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN + 1]; uint8_t link_idx; } provisioner_input_str; struct ble_mesh_provisioner_input_num_args { diff --git a/components/bt/esp_ble_mesh/common/buf.c b/components/bt/esp_ble_mesh/common/buf.c index f1c9559dd0..f988c4e8bd 100644 --- a/components/bt/esp_ble_mesh/common/buf.c +++ b/components/bt/esp_ble_mesh/common/buf.c @@ -279,26 +279,22 @@ uint16_t net_buf_simple_pull_be16(struct net_buf_simple *buf) uint32_t net_buf_simple_pull_le24(struct net_buf_simple *buf) { - struct uint24 { - uint32_t u24:24; - } __attribute__((packed)) val; + uint32_t val = 0U; - val = UNALIGNED_GET((struct uint24 *)buf->data); - net_buf_simple_pull(buf, sizeof(val)); + val = sys_get_le24(buf->data); + net_buf_simple_pull(buf, 3); - return sys_le24_to_cpu(val.u24); + return val; } uint32_t net_buf_simple_pull_be24(struct net_buf_simple *buf) { - struct uint24 { - uint32_t u24:24; - } __attribute__((packed)) val; + uint32_t val = 0U; - val = UNALIGNED_GET((struct uint24 *)buf->data); - net_buf_simple_pull(buf, sizeof(val)); + val = sys_get_be24(buf->data); + net_buf_simple_pull(buf, 3); - return sys_be24_to_cpu(val.u24); + return val; } uint32_t net_buf_simple_pull_le32(struct net_buf_simple *buf) @@ -323,26 +319,22 @@ uint32_t net_buf_simple_pull_be32(struct net_buf_simple *buf) uint64_t net_buf_simple_pull_le48(struct net_buf_simple *buf) { - struct uint48 { - uint64_t u48:48; - } __attribute__((packed)) val; + uint64_t val = 0U; - val = UNALIGNED_GET((struct uint48 *)buf->data); - net_buf_simple_pull(buf, sizeof(val)); + val = sys_get_le48(buf->data); + net_buf_simple_pull(buf, 6); - return sys_le48_to_cpu(val.u48); + return val; } uint64_t net_buf_simple_pull_be48(struct net_buf_simple *buf) { - struct uint48 { - uint64_t u48:48; - } __attribute__((packed)) val; + uint64_t val = 0U; - val = UNALIGNED_GET((struct uint48 *)buf->data); - net_buf_simple_pull(buf, sizeof(val)); + val = sys_get_be48(buf->data); + net_buf_simple_pull(buf, 6); - return sys_be48_to_cpu(val.u48); + return val; } uint64_t net_buf_simple_pull_le64(struct net_buf_simple *buf) diff --git a/components/bt/esp_ble_mesh/common/mutex.c b/components/bt/esp_ble_mesh/common/mutex.c index 3a3dedb80d..d3d280c87b 100644 --- a/components/bt/esp_ble_mesh/common/mutex.c +++ b/components/bt/esp_ble_mesh/common/mutex.c @@ -18,6 +18,11 @@ void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex) return; } + if (mutex->mutex) { + BT_INFO("Create, mutex already exist"); + return; + } + #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); @@ -81,6 +86,11 @@ void bt_mesh_r_mutex_create(bt_mesh_mutex_t *mutex) return; } + if (mutex->mutex) { + BT_INFO("Create, r mutex already exist"); + return; + } + #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); @@ -137,6 +147,11 @@ void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init) return; } + if (mutex->mutex) { + BT_INFO("Create, sem already exist"); + return; + } + #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); diff --git a/components/bt/esp_ble_mesh/common/timer.c b/components/bt/esp_ble_mesh/common/timer.c index 248480e70b..2b4ae036b7 100644 --- a/components/bt/esp_ble_mesh/common/timer.c +++ b/components/bt/esp_ble_mesh/common/timer.c @@ -112,6 +112,7 @@ int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) { BT_ERR("Init, alarm not set"); + osi_alarm_free(alarm); bt_mesh_alarm_unlock(); return -EIO; } @@ -235,6 +236,7 @@ int k_delayed_work_free(struct k_delayed_work *work) } osi_alarm_cancel(alarm); + osi_alarm_free(alarm); hash_map_erase(bm_alarm_hash_map, work); bt_mesh_alarm_unlock(); diff --git a/components/bt/esp_ble_mesh/core/adv_common.c b/components/bt/esp_ble_mesh/core/adv_common.c index cd6157e3bc..bf8e33e506 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.c +++ b/components/bt/esp_ble_mesh/core/adv_common.c @@ -919,16 +919,34 @@ void bt_mesh_adv_task_deinit(void) { BT_DBG("AdvTaskDeinit"); - vTaskDelete(adv_task.handle); - adv_task.handle = NULL; + if (adv_task.handle) { + vTaskDelete(adv_task.handle); + adv_task.handle = NULL; + } #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \ (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \ CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY) - heap_caps_free(adv_task.stack); - adv_task.stack = NULL; - heap_caps_free(adv_task.task); - adv_task.task = NULL; + /* Under specific configurations, bt_mesh_adv_task_deinit immediately releases + * adv_task.stack and adv_task.task (StaticTask_t) using heap_caps_free. + * However, vTaskDelete(adv_task.handle) only marks the task for deletion and + * adds it to the xTasksWaitingTermination list, which will be processed later + * by the Idle task (calling prvDeleteTCB). Even though static tasks are not + * automatically released by FreeRTOS, the Idle task will still access the TCB + * (checking fields such as ucStaticallyAllocated, resetting states). Premature + * release leads to a use-after-free (UAF) by the Idle task. + * Additionally, if the task is still running (possible in multi-core scenarios), + * releasing the stack may cause the task to execute with an invalid stack. + */ + vTaskDelay(pdMS_TO_TICKS(100)); + if (adv_task.stack) { + heap_caps_free(adv_task.stack); + adv_task.stack = NULL; + } + if (adv_task.task) { + heap_caps_free(adv_task.task); + adv_task.task = NULL; + } #endif } diff --git a/components/bt/esp_ble_mesh/core/beacon.c b/components/bt/esp_ble_mesh/core/beacon.c index 32e31f10a9..4f030ec99d 100644 --- a/components/bt/esp_ble_mesh/core/beacon.c +++ b/components/bt/esp_ble_mesh/core/beacon.c @@ -496,6 +496,7 @@ update_stats: void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) { + struct net_buf_simple_state state = {0}; uint8_t type = 0U; BT_DBG("BeaconRecv"); @@ -511,12 +512,16 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) case BEACON_TYPE_UNPROVISIONED: BT_DBG("UnprovDevBeaconRecv, Rssi %d", rssi); + net_buf_simple_save(buf, &state); + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && bt_mesh_is_provisioner_en()) { bt_mesh_provisioner_unprov_beacon_recv(buf, rssi); } + net_buf_simple_restore(buf, &state); + #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_is_provisioned()) { const bt_mesh_addr_t *addr = NULL; diff --git a/components/bt/esp_ble_mesh/core/ble_adv.c b/components/bt/esp_ble_mesh/core/ble_adv.c index aaaa4b4290..436e3e2800 100644 --- a/components/bt/esp_ble_mesh/core/ble_adv.c +++ b/components/bt/esp_ble_mesh/core/ble_adv.c @@ -121,6 +121,9 @@ static void ble_adv_send_end(int err, void *cb_data) BT_DBG("Count %u Period %u", tx->param.count, tx->param.period); if (tx->param.count) { + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0); + net_buf_unref(tx->buf); + if (tx->param.period) { k_delayed_work_submit(&tx->resend, tx->param.period); } else { @@ -278,7 +281,6 @@ int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param, int bt_mesh_stop_ble_advertising(uint8_t index) { struct bt_mesh_ble_adv_tx *tx = NULL; - bool unref = true; BT_DBG("StopBLEAdv, Index %u", index); @@ -298,15 +300,7 @@ int bt_mesh_stop_ble_advertising(uint8_t index) !!bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)), tx->buf->ref); - /* busy 1, ref 1; busy 1, ref 2; - * busy 0, ref 0; busy 0, ref 1; - */ - - if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) && - tx->buf->ref == 1U) { - unref = false; - } - ble_adv_tx_reset(tx, unref); + ble_adv_tx_reset(tx, true); return 0; } diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index c04206e657..5fe87f9ff7 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -285,6 +285,10 @@ static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report) switch (ext_adv_report->data_status) { case BTM_BLE_EXT_ADV_DATA_COMPLETE: if (adv_report_cache.adv_data_len) { + if (adv_report_cache.adv_data_len + ext_adv_report->adv_data_len > BLE_MESH_GAP_ADV_MAX_LEN) { + memset(&adv_report_cache, 0, sizeof(adv_report_cache)); + return false; + } memcpy(adv_report_cache.adv_data + adv_report_cache.adv_data_len, ext_adv_report->adv_data, ext_adv_report->adv_data_len); adv_report_cache.adv_data_len += ext_adv_report->adv_data_len; @@ -577,7 +581,7 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, ext_scan_params.coded_cfg.scan_type = scan_type; ext_scan_params.coded_cfg.scan_interval = interval; - ext_scan_params.coded_cfg.scan_window = interval - window; + ext_scan_params.coded_cfg.scan_window = MAX(interval - window, BTM_BLE_SCAN_WIN_MIN); BTA_DmBleGapSetExtScanParams(&ext_scan_params); @@ -757,7 +761,7 @@ int bt_le_ext_adv_start(const uint8_t inst_id, * Clearing sd is done by calling set_adv_data() with NULL data and zero len. * So following condition check is unusual but correct. */ - if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) { + if (sd) { err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, inst_id, sd, sd_len); if (err) { BT_ERR("Failed to set scan rsp data err %d", err); @@ -821,7 +825,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, * Clearing sd is done by calling set_adv_data() with NULL data and zero len. * So following condition check is unusual but correct. */ - if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) { + if (sd) { err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, sd, sd_len); if (err) { BT_ERR("Failed to set scan rsp data, err %d", err); @@ -1157,7 +1161,7 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) BT_DBG("gatts read, handle %d", p_data->req_data.p_data->read_req.handle); - if (attr != NULL && attr->read != NULL) { + if (attr != NULL && attr->read != NULL && index < ARRAY_SIZE(bt_mesh_gatts_conn)) { if ((len = attr->read(&bt_mesh_gatts_conn[index], attr, buf, 100, p_data->req_data.p_data->read_req.offset)) > 0) { rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle; @@ -1181,7 +1185,7 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) p_data->req_data.p_data->write_req.len, bt_hex(p_data->req_data.p_data->write_req.value, p_data->req_data.p_data->write_req.len)); - if (attr != NULL && attr->write != NULL) { + if (attr != NULL && attr->write != NULL && index < ARRAY_SIZE(bt_mesh_gatts_conn)) { if ((len = attr->write(&bt_mesh_gatts_conn[index], attr, p_data->req_data.p_data->write_req.value, p_data->req_data.p_data->write_req.len, @@ -1388,18 +1392,25 @@ ssize_t bt_mesh_gatts_attr_read_included(struct bt_mesh_conn *conn, void *buf, uint16_t len, uint16_t offset) { struct bt_mesh_gatt_attr *incl = attr->user_data; - struct bt_mesh_uuid *uuid = incl->user_data; + struct bt_mesh_gatt_attr *next_svc_start = NULL; + struct bt_mesh_uuid *uuid = NULL; struct gatts_incl pdu = {0}; uint8_t value_len = 0U; + assert(incl); + /* First attr points to the start handle */ pdu.start_handle = sys_cpu_to_le16(incl->handle); + next_svc_start = bt_mesh_gatts_attr_next(incl); + pdu.end_handle = sys_cpu_to_le16(next_svc_start ? next_svc_start->handle - 1 : incl->handle); value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle); /* * Core 4.2, Vol 3, Part G, 3.2, * The Service UUID shall only be present when the UUID is a 16-bit Bluetooth UUID. */ + uuid = incl->user_data; + if (uuid->type == BLE_MESH_UUID_TYPE_16) { pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val); value_len += sizeof(pdu.uuid16); @@ -1552,7 +1563,9 @@ static tBTA_GATT_PERM bt_mesh_perm_to_bta_perm(uint8_t perm) int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) { + bool service_created = false; tBT_UUID bta_uuid = {0}; + int service_idx = -1; assert(svc != NULL); @@ -1566,8 +1579,10 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) &bta_uuid, 0, svc->attr_count, true); if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add primary service"); - return ESP_FAIL; + goto cleanup; } + service_created = true; + service_idx = i; svc->attrs[i].handle = svc_handle; BT_DBG("Add primary service, uuid 0x%04x, perm %d, handle %d", bta_uuid.uu.uuid16, svc->attrs[i].perm, svc_handle); @@ -1580,8 +1595,10 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) &bta_uuid, 0, svc->attr_count, false); if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add secondary service"); - return ESP_FAIL; + goto cleanup; } + service_created = true; + service_idx = i; svc->attrs[i].handle = svc_handle; BT_DBG("Add secondary service, uuid 0x%04x, perm %d, handle %d", bta_uuid.uu.uuid16, svc->attrs[i].perm, svc_handle); @@ -1597,7 +1614,7 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) BTA_GATTS_AddCharacteristic(svc_handle, &bta_uuid, bt_mesh_perm_to_bta_perm(svc->attrs[i + 1].perm), gatts_chrc->properties, NULL, NULL); if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add characteristic"); - return ESP_FAIL; + goto cleanup; } /* All the characteristic should have two handles: the declaration handle and the value handle */ svc->attrs[i].handle = char_handle - 1; @@ -1622,7 +1639,7 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) BTA_GATTS_AddCharDescriptor(svc_handle, bt_mesh_perm_to_bta_perm(svc->attrs[i].perm), &bta_uuid, NULL, NULL); if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add descriptor"); - return ESP_FAIL; + goto cleanup; } svc->attrs[i].handle = char_handle; BT_DBG("Add descriptor, uuid 0x%04x, perm %d, handle %d", @@ -1641,6 +1658,13 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) gatts_register(svc); return 0; + +cleanup: + if (service_created && service_idx >= 0) { + BTA_GATTS_DeleteService(svc->attrs[service_idx].handle); + svc->attrs[service_idx].handle = 0; + } + return -EIO; } int bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service *svc) @@ -1730,7 +1754,13 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc) int bt_mesh_gatts_set_local_device_name(const char *name) { - BTM_SetLocalDeviceName((char *)name, BT_DEVICE_TYPE_BLE); + tBTM_STATUS status = BTM_SUCCESS; + + status = BTM_SetLocalDeviceName((char *)name, BT_DEVICE_TYPE_BLE); + if (status != BTM_NO_RESOURCES) { + BT_ERR("SetLocalDevNameFail[%d]", status); + return -EIO; + } return 0; } @@ -1882,7 +1912,7 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid) BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL); #endif /* CONFIG_BLE_MESH_USE_BLE_50 */ - return 0; + return i; } void bt_mesh_gattc_exchange_mtu(uint8_t index) diff --git a/components/bt/esp_ble_mesh/core/cfg_cli.c b/components/bt/esp_ble_mesh/core/cfg_cli.c index 211f80e9ed..6daae86afe 100644 --- a/components/bt/esp_ble_mesh/core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/core/cfg_cli.c @@ -470,8 +470,8 @@ static void hb_pub_status(struct bt_mesh_model *model, status.count = net_buf_simple_pull_u8(buf); status.period = net_buf_simple_pull_u8(buf); status.ttl = net_buf_simple_pull_u8(buf); - status.feat = net_buf_simple_pull_u8(buf); - status.net_idx = net_buf_simple_pull_u8(buf); + status.feat = net_buf_simple_pull_le16(buf); + status.net_idx = net_buf_simple_pull_le16(buf); cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_hb_sub_status)); } @@ -773,6 +773,11 @@ int bt_mesh_cfg_friend_set(bt_mesh_client_common_param_t *param, uint8_t val) { BT_DBG("FrndSet, Val 0x%02x", val); + if (val > 0x01) { + BT_ERR("InvalidFriendState 0x%02x", val); + return -EINVAL; + } + return send_msg_with_u8(param, OP_FRIEND_SET, val); } diff --git a/components/bt/esp_ble_mesh/core/cfg_srv.c b/components/bt/esp_ble_mesh/core/cfg_srv.c index 9be3e51983..6f7396bc6b 100644 --- a/components/bt/esp_ble_mesh/core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/core/cfg_srv.c @@ -911,7 +911,6 @@ static void default_ttl_set(struct bt_mesh_model *model, } } else { BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]); - return; } bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS); @@ -2016,11 +2015,6 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, BT_DBG("ModSubGetVnd"); addr = net_buf_simple_pull_le16(buf); - if (!BLE_MESH_ADDR_IS_UNICAST(addr)) { - BT_ERR("Prohibited element address 0x%04x", addr); - return; - } - company = net_buf_simple_pull_le16(buf); id = net_buf_simple_pull_le16(buf); @@ -2028,6 +2022,15 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST_VND); + if (!BLE_MESH_ADDR_IS_UNICAST(addr)) { + BT_ERR("ProhibitedElementAddress 0x%04x", addr); + net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS); + net_buf_simple_add_le16(&msg, addr); + net_buf_simple_add_le16(&msg, company); + net_buf_simple_add_le16(&msg, id); + goto send_list; + } + elem = bt_mesh_elem_find(addr); if (!elem) { BT_DBG("StatusInvalidAddress"); @@ -2119,6 +2122,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, if (bt_mesh_model_find_group(mod, sub_addr)) { /* Tried to add existing subscription */ status = STATUS_SUCCESS; + va_del(label_uuid, &sub_addr); goto send_status; } @@ -2136,6 +2140,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, if (i == ARRAY_SIZE(mod->groups)) { BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; + va_del(label_uuid, &sub_addr); } else { if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { bt_mesh_lpn_group_add(sub_addr); @@ -2403,7 +2408,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, return; } - net_buf_simple_pull(buf, 18); + net_buf_simple_pull(buf, 16); mod_id = buf->data; @@ -2721,7 +2726,7 @@ send_status: if (status == STATUS_SUCCESS) { bt_mesh_cfg_server_state_change_t change = {0}; - change.cfg_netkey_delete.net_idx = sub ? sub->net_idx : BLE_MESH_KEY_UNUSED; + change.cfg_netkey_delete.net_idx = del_idx; bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change)); } @@ -2970,14 +2975,17 @@ static void mod_app_unbind(struct bt_mesh_model *model, BT_DBG("ModAppUnbind"); elem_addr = net_buf_simple_pull_le16(buf); - if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { - BT_ERR("Prohibited element address 0x%04x", elem_addr); - return; - } - key_app_idx = net_buf_simple_pull_le16(buf); mod_id = buf->data; + if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_ERR("ProhibitedElementAddress 0x%04x", elem_addr); + mod = NULL; + vnd = (buf->len == 4U); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + elem = bt_mesh_elem_find(elem_addr); if (!elem) { BT_DBG("StatusInvalidAddress"); @@ -3121,6 +3129,7 @@ static void send_friend_status(struct bt_mesh_model *model, struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("SendFrndStatus"); + assert(cfg); bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS); net_buf_simple_add_u8(&msg, cfg->frnd); @@ -3298,6 +3307,7 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY); return; } @@ -3316,6 +3326,7 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, (sub->kr_phase == BLE_MESH_KR_NORMAL && phase == BLE_MESH_KR_PHASE_2)) { BT_WARN("Prohibited transition %u -> %u", sub->kr_phase, phase); + send_krp_status(model, ctx, idx, sub->kr_phase, STATUS_UNSPECIFIED); return; } @@ -3348,7 +3359,7 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, bt_mesh_cfg_server_state_change_t change = {0}; change.cfg_kr_phase_set.net_idx = idx; - change.cfg_kr_phase_set.kr_phase = phase; + change.cfg_kr_phase_set.kr_phase = sub->kr_phase; bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change)); } @@ -3357,14 +3368,10 @@ static uint8_t hb_log(uint16_t val) { BT_DBG("HbLog, Val 0x%04x", val); - switch (val) { - case 0x0000: + if (val == 0x0000) { return 0x00; - case 0xFFFF: - return 0xFF; - default: - return 32 - __builtin_clz(val); } + return 32 - __builtin_clz(val); } static uint8_t hb_pub_count_log(uint16_t val) @@ -3415,6 +3422,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model, struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("HbPubSendStatus, Src 0x%04x Status 0x%02x", ctx->addr, status); + assert(cfg); bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_STATUS); @@ -3458,6 +3466,7 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, uint8_t status = 0U; BT_DBG("HeartbeatPubSet, Src 0x%04x", ctx->addr); + assert(cfg); dst = sys_le16_to_cpu(param->dst); /* All other address types but virtual are valid */ @@ -3481,7 +3490,8 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, if (param->ttl > BLE_MESH_TTL_MAX && param->ttl != BLE_MESH_TTL_DEFAULT) { BT_ERR("InvalidTTL %u", param->ttl); - return; + status = STATUS_UNSPECIFIED; + goto failed; } feat = sys_le16_to_cpu(param->feat); @@ -3489,7 +3499,8 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, idx = sys_le16_to_cpu(param->net_idx); if (idx > 0xfff) { BT_ERR("InvalidNetIdx 0x%04x", idx); - return; + status = STATUS_INVALID_NETKEY; + goto failed; } if (!bt_mesh_subnet_get(idx)) { @@ -3560,6 +3571,7 @@ static void hb_sub_send_status(struct bt_mesh_model *model, int64_t uptime = 0; BT_DBG("HbSubSendStatus, Src 0x%04x Status 0x%02x", ctx->addr, status); + assert(cfg); uptime = k_uptime_get(); if (uptime > cfg->hb_sub.expiry) { @@ -3602,6 +3614,7 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, int32_t period_ms = 0; BT_DBG("HeartbeatSubSet, Src 0x%04x", ctx->addr); + assert(cfg); sub_src = net_buf_simple_pull_le16(buf); sub_dst = net_buf_simple_pull_le16(buf); @@ -3697,7 +3710,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { { OP_RELAY_SET, 2, relay_set }, { OP_MOD_PUB_GET, 4, mod_pub_get }, { OP_MOD_PUB_SET, 11, mod_pub_set }, - { OP_MOD_PUB_VA_SET, 24, mod_pub_va_set }, + { OP_MOD_PUB_VA_SET, 25, mod_pub_va_set }, { OP_MOD_SUB_ADD, 6, mod_sub_add }, { OP_MOD_SUB_VA_ADD, 20, mod_sub_va_add }, { OP_MOD_SUB_DEL, 6, mod_sub_del }, @@ -3784,6 +3797,16 @@ static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg) return false; } + if (cfg->gatt_proxy > BLE_MESH_GATT_PROXY_NOT_SUPPORTED) { + BT_ERR("InvalidGattProxy 0x%02x", cfg->gatt_proxy); + return false; + } + + if (cfg->frnd > BLE_MESH_FRIEND_NOT_SUPPORTED) { + BT_ERR("InvalidFriend 0x%02x", cfg->frnd); + return false; + } + if (!IS_ENABLED(CONFIG_BLE_MESH_RELAY)) { BT_INFO("Relay not supported"); cfg->relay = BLE_MESH_RELAY_NOT_SUPPORTED; diff --git a/components/bt/esp_ble_mesh/core/crypto.c b/components/bt/esp_ble_mesh/core/crypto.c index 6066ef15c6..8e85c8f436 100644 --- a/components/bt/esp_ble_mesh/core/crypto.c +++ b/components/bt/esp_ble_mesh/core/crypto.c @@ -327,6 +327,11 @@ int bt_mesh_net_decrypt(const uint8_t key[16], struct net_buf_simple *buf, BT_DBG("Nonce %s", bt_hex(nonce, 13)); + if (buf->len < 8 + mic_len) { + BT_ERR("TooShortMsgToDecrypt[%u][%u]", buf->len, mic_len); + return -EINVAL; + } + buf->len -= mic_len; err = bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, diff --git a/components/bt/esp_ble_mesh/core/ext_adv.c b/components/bt/esp_ble_mesh/core/ext_adv.c index c4feaa7a4e..a7279b6c2e 100644 --- a/components/bt/esp_ble_mesh/core/ext_adv.c +++ b/components/bt/esp_ble_mesh/core/ext_adv.c @@ -150,7 +150,7 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration) struct bt_mesh_ble_adv_data data = {0}; struct bt_mesh_ble_adv_tx *tx = cb_data; - if (tx == NULL) { + if (tx == NULL || tx->buf == NULL || tx->buf->len < 2) { BT_ERR("Invalid adv user data"); net_buf_unref(buf); return -EINVAL; @@ -160,13 +160,21 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration) ADV_SCAN_INT(tx->param.interval), tx->param.duration, tx->param.period, tx->param.count); - data.adv_data_len = tx->buf->data[0]; - if (data.adv_data_len) { + data.adv_data_len = MIN(tx->buf->data[0], sizeof(data.adv_data)); + if (data.adv_data_len && tx->buf->len >= 1 + data.adv_data_len) { memcpy(data.adv_data, tx->buf->data + 1, data.adv_data_len); + } else { + data.adv_data_len = 0; } - data.scan_rsp_data_len = tx->buf->data[data.adv_data_len + 1]; - if (data.scan_rsp_data_len) { - memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len); + if (tx->buf->len >= data.adv_data_len + 2) { + data.scan_rsp_data_len = MIN(tx->buf->data[data.adv_data_len + 1], sizeof(data.scan_rsp_data)); + if (data.scan_rsp_data_len && tx->buf->len >= data.adv_data_len + 2 + data.scan_rsp_data_len) { + memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len); + } else { + data.scan_rsp_data_len = 0; + } + } else { + data.scan_rsp_data_len = 0; } duration = tx->param.duration; diff --git a/components/bt/esp_ble_mesh/core/fast_prov.c b/components/bt/esp_ble_mesh/core/fast_prov.c index 5d34db8a09..6a256fb3bb 100644 --- a/components/bt/esp_ble_mesh/core/fast_prov.c +++ b/components/bt/esp_ble_mesh/core/fast_prov.c @@ -169,7 +169,7 @@ const uint8_t *bt_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx) BT_DBG("GetFastProvAppKey, NetIdx 0x%04x AppIdx 0x%04x", net_idx, app_idx); key = bt_mesh_fast_prov_app_key_find(app_idx); - if (!key) { + if (!key || key->net_idx != net_idx) { BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx); return NULL; } @@ -202,7 +202,10 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action) bt_mesh_proxy_client_prov_enable(); } - bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()); + if (bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()) < 0) { + BT_ERR("SetPrimaryElemAddrFail"); + return 0x01; + } bt_mesh_provisioner_set_prov_bearer(BLE_MESH_PROV_ADV, false); bt_mesh_provisioner_fast_prov_enable(true); bt_mesh_atomic_or(bt_mesh.flags, BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV)); diff --git a/components/bt/esp_ble_mesh/core/friend.c b/components/bt/esp_ble_mesh/core/friend.c index 46060d3b0f..dd7c58b1ed 100644 --- a/components/bt/esp_ble_mesh/core/friend.c +++ b/components/bt/esp_ble_mesh/core/friend.c @@ -516,12 +516,16 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, return 0; } + BT_DBG("Re-encryptFriendPdu %06x/%06x", meta.net.seq, bt_mesh.seq); + err = unseg_app_sdu_decrypt(frnd, buf, &meta); if (err) { BT_WARN("Decryption failed! %d", err); return err; } + meta.net.seq = bt_mesh.seq; + err = unseg_app_sdu_encrypt(frnd, buf, &meta); if (err) { BT_WARN("Re-encryption failed! %d", err); @@ -572,6 +576,7 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, } } + /* Increment the sequence number for later usage */ seq = bt_mesh_next_seq(); sys_put_be24(seq, &buf->data[2]); @@ -667,6 +672,7 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, uint8_t xact) } if (encrypt_friend_pdu(frnd, buf, false)) { + net_buf_unref(buf); return; } @@ -1038,6 +1044,7 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, int8_t rssi) } if (encrypt_friend_pdu(frnd, buf, true)) { + net_buf_unref(buf); return; } @@ -1135,23 +1142,21 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) if (frnd) { BT_WARN("Existing LPN re-requesting Friendship"); friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_REQ); - goto init_friend; - } + } else { + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + if (!bt_mesh.frnd[i].valid) { + frnd = &bt_mesh.frnd[i]; + break; + } + } - for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { - if (!bt_mesh.frnd[i].valid) { - frnd = &bt_mesh.frnd[i]; - frnd->valid = 1U; - break; + if (!frnd) { + BT_WARN("No free Friend contexts for new LPN"); + return -ENOMEM; } } - if (!frnd) { - BT_WARN("No free Friend contexts for new LPN"); - return -ENOMEM; - } - -init_friend: + frnd->valid = 1U; frnd->lpn = rx->ctx.addr; frnd->num_elem = msg->num_elem; frnd->net_idx = rx->sub->net_idx; @@ -1265,6 +1270,12 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, net_buf_slist_put(&seg->queue, buf); if (type == BLE_MESH_FRIEND_PDU_COMPLETE) { + struct net_buf *sbuf; + while ((sbuf = (void *)sys_slist_get(&seg->queue))) { + sbuf->frags = NULL; + sbuf->flags &= ~NET_BUF_FRAGS; + } + sys_slist_merge_slist(&frnd->queue, &seg->queue); frnd->queue_size += seg->seg_count; @@ -1700,6 +1711,9 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr, } total += seg->seg_count; + if (total > CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE) { + return false; + } } BT_DBG("TotalCount %u", total); @@ -1709,7 +1723,7 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr, * is because we don't have a mechanism of aborting already pending * segmented messages to free up buffers. */ - return (CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE - total) > seg_count; + return (CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE - total) >= seg_count; } bool bt_mesh_friend_queue_has_space(uint16_t net_idx, uint16_t src, uint16_t dst, @@ -1755,7 +1769,6 @@ bool bt_mesh_friend_queue_has_space(uint16_t net_idx, uint16_t src, uint16_t dst static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t addr, const uint64_t *seq_auth, uint8_t seg_count) { - bool pending_segments = false; uint8_t avail_space = 0U; BT_DBG("FrndQueuePrepareSpace"); @@ -1766,9 +1779,8 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add } avail_space = CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE - frnd->queue_size; - pending_segments = false; - while (pending_segments || avail_space < seg_count) { + while (avail_space < seg_count) { struct net_buf *buf = (void *)sys_slist_get(&frnd->queue); if (!buf) { @@ -1776,14 +1788,11 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add return false; } - BT_DBG("PendingSeg %u AvailSpace %u QueueSize %u", - pending_segments, avail_space, frnd->queue_size); + BT_DBG("AvailSpace %u QueueSize %u", avail_space, frnd->queue_size); frnd->queue_size--; avail_space++; - pending_segments = (buf->flags & NET_BUF_FRAGS); - /* Make sure old slist entry state doesn't remain */ buf->frags = NULL; buf->flags &= ~NET_BUF_FRAGS; diff --git a/components/bt/esp_ble_mesh/core/include/mesh/main.h b/components/bt/esp_ble_mesh/core/include/mesh/main.h index 35e554458a..c002c3b0b3 100644 --- a/components/bt/esp_ble_mesh/core/include/mesh/main.h +++ b/components/bt/esp_ble_mesh/core/include/mesh/main.h @@ -4,7 +4,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -619,9 +619,11 @@ int bt_mesh_resume(void); * * @return Zero on success or (negative) error code otherwise. */ -int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, - uint8_t flags, uint32_t iv_index, uint16_t addr, - const uint8_t dev_key[16]); +int bt_mesh_pre_provision(const uint8_t net_key[16], uint16_t net_idx, + uint8_t flags, uint32_t iv_index, uint16_t addr, + const uint8_t dev_key[16]); + +void bt_mesh_provision(void); /** @brief Check if the device is an unprovisioned device * and will act as a node once provisioned. diff --git a/components/bt/esp_ble_mesh/core/local.c b/components/bt/esp_ble_mesh/core/local.c index fb933cc804..05d6e96269 100644 --- a/components/bt/esp_ble_mesh/core/local.c +++ b/components/bt/esp_ble_mesh/core/local.c @@ -112,8 +112,8 @@ int bt_mesh_model_unsubscribe_group_addr(uint16_t elem_addr, uint16_t cid, match = bt_mesh_model_find_group(model, group_addr); if (match == NULL) { - BT_WARN("GroupAddrExist 0x%04x", group_addr); - return -EEXIST; + BT_WARN("GroupAddrNotExist 0x%04x", group_addr); + return -ENOENT; } *match = BLE_MESH_ADDR_UNASSIGNED; diff --git a/components/bt/esp_ble_mesh/core/lpn.c b/components/bt/esp_ble_mesh/core/lpn.c index a38b0944e4..79d97887c7 100644 --- a/components/bt/esp_ble_mesh/core/lpn.c +++ b/components/bt/esp_ble_mesh/core/lpn.c @@ -758,7 +758,7 @@ static bool sub_update(uint8_t op) } } - if (added_count + g >= lpn->queue_size) { + if (op == TRANS_CTL_OP_FRIEND_SUB_ADD && added_count + g >= lpn->queue_size) { BT_WARN("FrndQueueExceeded, Added %u G %u Size %u", added_count, g, lpn->queue_size); break; diff --git a/components/bt/esp_ble_mesh/core/main.c b/components/bt/esp_ble_mesh/core/main.c index cc5543697e..8efe3832a5 100644 --- a/components/bt/esp_ble_mesh/core/main.c +++ b/components/bt/esp_ble_mesh/core/main.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,11 +43,10 @@ bool bt_mesh_is_initialized(void) return mesh_init; } -int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, - uint8_t flags, uint32_t iv_index, uint16_t addr, - const uint8_t dev_key[16]) +int bt_mesh_pre_provision(const uint8_t net_key[16], uint16_t net_idx, + uint8_t flags, uint32_t iv_index, + uint16_t addr, const uint8_t dev_key[16]) { - bool pb_gatt_enabled = false; int err = 0; BT_INFO("NodeProvisioned"); @@ -62,28 +61,10 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, return -EALREADY; } - if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { - if (bt_mesh_proxy_server_prov_disable(false) == 0) { - pb_gatt_enabled = true; - } else { - pb_gatt_enabled = false; - } - } else { - pb_gatt_enabled = false; - } - - BT_DBG("PbGattEnabled %u", pb_gatt_enabled); - err = bt_mesh_net_create(net_idx, flags, net_key, iv_index); if (err) { BT_ERR("Create network for node failed"); - bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID); - - if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && pb_gatt_enabled) { - bt_mesh_proxy_server_prov_enable(); - } - return err; } @@ -93,6 +74,15 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, memcpy(bt_mesh.dev_key, dev_key, 16); + return 0; +} + +void bt_mesh_provision(void) +{ + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { + bt_mesh_proxy_server_prov_disable(false); + } + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && IS_ENABLED(CONFIG_BLE_MESH_LPN_SUB_ALL_NODES_ADDR)) { BT_DBG("LPNAllNodesAdded"); @@ -106,8 +96,6 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, } bt_mesh_net_start(); - - return 0; } void bt_mesh_node_reset(void) @@ -722,13 +710,13 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) err = bt_mesh_provisioner_net_create(); if (err) { BT_ERR("Failed to create network"); - return err; + goto end; } err = bt_mesh_provisioner_init_prov_info(); if (err) { BT_ERR("Failed to init prov info"); - return err; + goto end; } bt_mesh_provisioner_set_prov_bearer(bearers, false); @@ -772,10 +760,14 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) err = bt_mesh_scan_enable(); if (err) { - return err; + goto end; } return 0; + +end: + bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); + return err; } int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index ac2b16b5d9..6c5ca3f64e 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -364,6 +364,9 @@ static int chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, break; } } + if (j == ARRAY_SIZE(bt_mesh_gattc_info)) { + return 0; + } ble_gattc_disc_all_dscs(conn_handle, bt_mesh_gattc_info[j].data_out_handle, bt_mesh_gattc_info[j].end_handle, dsc_disced, (void *)j); } else { @@ -762,6 +765,11 @@ report_to_user: } notif_len = OS_MBUF_PKTLEN(event->notify_rx.om); + if (notif_len > sizeof(notif_data)) { + BT_ERR("TooLongNtf[%u]", notif_len); + bt_mesh_gattc_disconnect(conn); + return 0; + } rc = os_mbuf_copydata(event->notify_rx.om, 0, notif_len, notif_data); if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) { @@ -859,22 +867,6 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, return 0; } -static int set_ad(const struct bt_mesh_adv_data *ad, size_t ad_len, uint8_t *buf, uint8_t *buf_len) -{ - int i; - - for (i = 0; i < ad_len; i++) { - buf[(*buf_len)++] = ad[i].data_len + 1; - buf[(*buf_len)++] = ad[i].type; - - memcpy(&buf[*buf_len], ad[i].data, - ad[i].data_len); - *buf_len += ad[i].data_len; - } - - return 0; -} - #if CONFIG_BLE_MESH_NODE static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle); @@ -1052,6 +1044,10 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) } #else /* CONFIG_BLE_MESH_USE_BLE_50 */ index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle); + if (index >= BLE_MESH_MAX_CONN) { + BT_ERR("InvConnIdx[%d]", index); + return 0; + } #endif /* CONFIG_BLE_MESH_USE_BLE_50 */ if (event->subscribe.prev_notify != event->subscribe.cur_notify) { @@ -1151,6 +1147,31 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) } #endif /* CONFIG_BLE_MESH_NODE */ +static size_t get_buf_len(const struct bt_mesh_adv_data *ad, size_t ad_len) +{ + size_t len = 0; + + for (size_t i = 0; i < ad_len; i++) { + len += (2 + ad[i].data_len); + } + + return len; +} + +static int set_ad(const struct bt_mesh_adv_data *ad, size_t ad_len, uint8_t *buf, uint8_t *buf_len) +{ + for (size_t i = 0; i < ad_len; i++) { + buf[(*buf_len)++] = ad[i].data_len + 1; + buf[(*buf_len)++] = ad[i].type; + + memcpy(&buf[*buf_len], ad[i].data, + ad[i].data_len); + *buf_len += ad[i].data_len; + } + + return 0; +} + #if CONFIG_BLE_MESH_USE_BLE_50 static struct { bool set; @@ -1190,7 +1211,7 @@ int bt_le_ext_adv_start(const uint8_t inst_id, err = set_ad(ad, ad_len, buf, &buf_len); if (err) { bt_mesh_free(buf); - BT_ERR("set_ad failed: err %d", err); + BT_ERR("SetAdvDataFail[%d]", err); return err; } @@ -1222,7 +1243,7 @@ int bt_le_ext_adv_start(const uint8_t inst_id, err = set_ad(sd, sd_len, buf, &buf_len); if (err) { bt_mesh_free(buf); - BT_ERR("set_ad failed: err %d", err); + BT_ERR("SetScanRspDataFail[%d]", err); return err; } @@ -1360,8 +1381,8 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *sd, size_t sd_len) { struct ble_gap_adv_params adv_params; - uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint16_t interval = 0; + uint8_t *buf = NULL; uint8_t buf_len = 0; int err; @@ -1371,32 +1392,52 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, } #endif + buf = bt_mesh_calloc(get_buf_len(ad, ad_len)); + if (buf == NULL) { + BT_ERR("AllocAdvDataBufFail[%u]", get_buf_len(ad, ad_len)); + return -ENOMEM; + } + err = set_ad(ad, ad_len, buf, &buf_len); if (err) { - BT_ERR("set_ad failed: err %d", err); + BT_ERR("SetAdvDataFail[%d]", err); + bt_mesh_free(buf); return err; } err = ble_gap_adv_set_data(buf, buf_len); if (err != 0) { BT_ERR("Advertising set failed: err %d", err); + bt_mesh_free(buf); return err; } + bt_mesh_free(buf); + if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) { buf_len = 0; + buf = bt_mesh_calloc(get_buf_len(sd, sd_len)); + if (buf == NULL) { + BT_ERR("AllocScanRspDataBufFail[%u]", get_buf_len(sd, sd_len)); + return -ENOMEM; + } + err = set_ad(sd, sd_len, buf, &buf_len); if (err) { - BT_ERR("set_ad failed: err %d", err); + BT_ERR("SetScanRspDataFail[%d]", err); + bt_mesh_free(buf); return err; } err = ble_gap_adv_rsp_set_data(buf, buf_len); if (err != 0) { BT_ERR("Scan rsp failed: err %d", err); + bt_mesh_free(buf); return err; } + + bt_mesh_free(buf); } memset(&adv_params, 0, sizeof adv_params); @@ -2230,8 +2271,13 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid) memcpy(peer_addr.val, addr->val, 6); peer_addr.type = addr->type; - return ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER, &conn_params, - disc_cb, NULL); + rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER, &conn_params, + disc_cb, NULL); + if (rc) { + return -1; + } + + return i; } static int mtu_cb(uint16_t conn_handle, diff --git a/components/bt/esp_ble_mesh/core/prov_common.c b/components/bt/esp_ble_mesh/core/prov_common.c index bf5657852b..8f14b67efa 100644 --- a/components/bt/esp_ble_mesh/core/prov_common.c +++ b/components/bt/esp_ble_mesh/core/prov_common.c @@ -285,6 +285,12 @@ bool bt_mesh_gen_prov_cont(struct bt_mesh_prov_link *link, } return false; } + } else if (buf->len > CONT_PAYLOAD_MAX) { + BT_ERR("Invalid non-last seg len: %u > %u", buf->len, CONT_PAYLOAD_MAX); + if (close) { + *close = true; + } + return false; } if ((link->rx.seg & BIT(seg)) == 0) { @@ -597,7 +603,7 @@ static uint8_t last_seg(uint8_t len) len -= START_PAYLOAD_MAX; - return 1 + (len / CONT_PAYLOAD_MAX); + return DIV_ROUND_UP(len, CONT_PAYLOAD_MAX); } int bt_mesh_prov_send_adv(struct bt_mesh_prov_link *link, struct net_buf_simple *msg) diff --git a/components/bt/esp_ble_mesh/core/prov_node.c b/components/bt/esp_ble_mesh/core/prov_node.c index 24bb71bfb6..721f8feb72 100644 --- a/components/bt/esp_ble_mesh/core/prov_node.c +++ b/components/bt/esp_ble_mesh/core/prov_node.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -598,6 +598,7 @@ int bt_mesh_input_string(const char *str) return -EINVAL; } + (void)memset(prov_link.auth, 0, sizeof(prov_link.auth)); (void)memcpy(prov_link.auth, str, bt_mesh_prov_get()->input_size); send_input_complete(); @@ -946,17 +947,17 @@ static void prov_data(const uint8_t *data) bt_mesh_prov_buf_init(&msg, PROV_COMPLETE); - if (bt_mesh_prov_send(&prov_link, &msg)) { - BT_ERR("Failed to send Provisioning Complete"); - return; - } - - /* Ignore any further PDUs on this link */ - prov_link.expect = 0U; - #if CONFIG_BLE_MESH_RPR_SRV /* For NPPI, no need to perform the following actions */ if (bt_mesh_atomic_test_bit(prov_link.flags, PB_NPPI)) { + if (bt_mesh_prov_send(&prov_link, &msg)) { + BT_ERR("NPPI, failed to send Provisioning Complete"); + return; + } + + /* Ignore any further PDUs on this link */ + prov_link.expect = 0U; + return; } #endif /* CONFIG_BLE_MESH_RPR_SRV */ @@ -968,12 +969,24 @@ static void prov_data(const uint8_t *data) identity_enable = false; } - err = bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key); + err = bt_mesh_pre_provision(pdu, net_idx, flags, iv_index, addr, dev_key); if (err) { BT_ERR("Failed to provision (err %d)", err); + close_link(PROV_ERR_UNEXP_ERR); return; } + if (bt_mesh_prov_send(&prov_link, &msg)) { + BT_ERR("Failed to send Provisioning Complete"); + return; + } + + /* Ignore any further PDUs on this link */ + prov_link.expect = 0U; + + /* The device becomes a node and enters the network */ + bt_mesh_provision(); + /* After PB-GATT provisioning we should start advertising * using Node Identity. */ @@ -1673,6 +1686,11 @@ int bt_mesh_rpr_srv_nppi_pdu_recv(uint8_t type, const uint8_t *data) return -EINVAL; } + if (type >= ARRAY_SIZE(prov_handlers)) { + BT_ERR("NPPI, unknown provisioning PDU type 0x%02x", type); + return -EINVAL; + } + if (type != prov_link.expect) { BT_ERR("NPPI, unexpected msg 0x%02x != 0x%02x", type, prov_link.expect); return -EINVAL; diff --git a/components/bt/esp_ble_mesh/core/prov_pvnr.c b/components/bt/esp_ble_mesh/core/prov_pvnr.c index 3182f49e80..88ce691464 100644 --- a/components/bt/esp_ble_mesh/core/prov_pvnr.c +++ b/components/bt/esp_ble_mesh/core/prov_pvnr.c @@ -37,7 +37,7 @@ _Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME, #define UNICAST_ADDR_LIMIT 0x7FFF -#define PROV_SVC_ADV_RX_CHECK(pre, cur) ((cur) < (pre) ? ((cur) + (UINT32_MAX - (pre)) >= 200) : ((cur) - (pre) >= 200)) +#define PROV_SVC_ADV_RX_CHECK(pre, cur) ((cur) < (pre) ? ((cur) + (UINT32_MAX - (pre) + 1) >= 200) : ((cur) - (pre) >= 200)) /* Provisioner link structure allocation * |--------------------------------------------------------| @@ -102,6 +102,9 @@ struct bt_mesh_prov_ctx { bt_mesh_mutex_t pb_gatt_lock; #endif /* CONFIG_BLE_MESH_PB_GATT */ + /* Mutex used to protect the provisioning procedure */ + bt_mesh_mutex_t prov_lock; + /* Fast provisioning related information */ struct { bool enable; @@ -177,6 +180,16 @@ void bt_mesh_prov_pvnr_send_invite(struct bt_mesh_prov_link *link) send_invite(link); } +static inline void bt_mesh_prov_lock(void) +{ + bt_mesh_mutex_lock(&prov_ctx.prov_lock); +} + +static inline void bt_mesh_prov_unlock(void) +{ + bt_mesh_mutex_unlock(&prov_ctx.prov_lock); +} + #if CONFIG_BLE_MESH_PB_ADV static inline void bt_mesh_pb_adv_lock(void) { @@ -1266,6 +1279,10 @@ static void prov_capabilities(struct bt_mesh_prov_link *link, /* Provisioner select output action */ if (bt_mesh_prov_get()->prov_input_num && output_size) { + if (output_action == 0) { + BT_ERR("Invalid Output OOB Action 0x%04x/%d", output_action, output_size); + goto fail; + } output_action = __builtin_ctz(output_action); } else { output_size = 0x0; @@ -1308,6 +1325,10 @@ static void prov_capabilities(struct bt_mesh_prov_link *link, /* Provisioner select input action */ if (bt_mesh_prov_get()->prov_output_num && input_size) { + if (input_action == 0) { + BT_ERR("Invalid Input OOB Action 0x%04x/%d", input_action, input_size); + goto fail; + } input_action = __builtin_ctz(input_action); } else { input_size = 0x0; @@ -1576,6 +1597,8 @@ static void send_confirm(struct bt_mesh_prov_link *link) BT_DBG("ConfirmationSalt: %s", bt_hex(link->conf_salt, conf_salt_size)); BT_DBG("ConfirmationKey: %s", bt_hex(link->conf_key, conf_key_size)); BT_DBG("LocalRandom: %s", bt_hex(link->rand, rand_size)); + ARG_UNUSED(conf_salt_size); + ARG_UNUSED(conf_key_size); bt_mesh_prov_buf_init(&buf, PROV_CONFIRM); @@ -2139,6 +2162,7 @@ static void send_prov_data(struct bt_mesh_prov_link *link) * not update the prov_ctx.alloc_addr after the proper provisioning * complete pdu is received. */ + bt_mesh_prov_lock(); if (!BLE_MESH_ADDR_IS_UNICAST(prev_addr)) { if (BLE_MESH_ADDR_IS_UNICAST(link->assign_addr)) { /* Even if the unicast address of the node is assigned by the @@ -2163,6 +2187,7 @@ static void send_prov_data(struct bt_mesh_prov_link *link) bt_mesh_store_prov_info(prov_ctx.primary_addr, prov_ctx.alloc_addr); } } + bt_mesh_prov_unlock(); if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV) && FAST_PROV_ENABLE()) { link->kri_flags = get_net_flags(prov_ctx.fast_prov.net_idx); @@ -2480,10 +2505,6 @@ static void prov_msg_recv(struct bt_mesh_prov_link *link) goto fail; } - bt_mesh_gen_prov_ack_send(link, link->rx.id); - link->rx.prev_id = link->rx.id; - link->rx.id = 0; - /* Provisioner first checks information within the received * Provisioning PDU. If the check succeeds then check fcs. */ @@ -2496,6 +2517,10 @@ static void prov_msg_recv(struct bt_mesh_prov_link *link) goto fail; } + bt_mesh_gen_prov_ack_send(link, link->rx.id); + link->rx.prev_id = link->rx.id; + link->rx.id = 0; + k_delayed_work_submit(&link->prot_timer, PROTOCOL_TIMEOUT); prov_handlers[type].func(link, link->rx.buf); @@ -2881,6 +2906,7 @@ int bt_mesh_provisioner_prov_init(void) #if CONFIG_BLE_MESH_PB_GATT bt_mesh_mutex_create(&prov_ctx.pb_gatt_lock); #endif + bt_mesh_mutex_create(&prov_ctx.prov_lock); return 0; } @@ -2976,6 +3002,7 @@ int bt_mesh_provisioner_prov_deinit(bool erase) #if CONFIG_BLE_MESH_PB_GATT bt_mesh_mutex_free(&prov_ctx.pb_gatt_lock); #endif + bt_mesh_mutex_free(&prov_ctx.prov_lock); prov_ctx.static_oob_len = 0U; memset(prov_ctx.static_oob_val, 0, sizeof(prov_ctx.static_oob_val)); @@ -3133,6 +3160,11 @@ void bt_mesh_provisioner_prov_adv_recv(struct net_buf_simple *buf, int bt_mesh_rpr_cli_pdu_recv(struct bt_mesh_prov_link *link, uint8_t type, struct net_buf_simple *buf) { + if (type >= ARRAY_SIZE(prov_handlers)) { + BT_ERR("NPPI, unknown provisioning PDU type 0x%02x", type); + return -EINVAL; + } + if (type != link->expect) { BT_ERR("PB-Remote, unexpected msg 0x%02x != 0x%02x", type, link->expect); return -EINVAL; diff --git a/components/bt/esp_ble_mesh/core/proxy_client.c b/components/bt/esp_ble_mesh/core/proxy_client.c index 710159fd25..125a902ebe 100644 --- a/components/bt/esp_ble_mesh/core/proxy_client.c +++ b/components/bt/esp_ble_mesh/core/proxy_client.c @@ -519,7 +519,7 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_prov_node_get_link()->conn == conn) { for (size_t i = 0; i < ARRAY_SIZE(waiting_conn_link); i++) { - if (waiting_conn_link[i].link->conn == conn) { + if (waiting_conn_link[i].link && waiting_conn_link[i].link->conn == conn) { waiting_conn_link[i].link = NULL; memset(&waiting_conn_link[i].addr, 0, sizeof(bt_mesh_addr_t)); break; @@ -559,6 +559,7 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) { struct bt_mesh_proxy_server *server = find_server(conn); + int err = 0; BT_DBG("ProvWriteCCC, ConnHandle 0x%04x", conn->handle); @@ -572,18 +573,29 @@ static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_prov_node_get_link()->conn == conn) { - int err = bt_mesh_pb_gatt_open(conn); + err = bt_mesh_pb_gatt_open(conn); if (err) { BT_ERR("proxy write ccc error %d", err); + server->conn_type = CLI_NONE; return err; } - return bt_mesh_rpr_srv_recv_link_ack(addr->val, false); + err = bt_mesh_rpr_srv_recv_link_ack(addr->val, false); + if (err) { + BT_ERR("rpr srv recv link ack fail %d", err); + server->conn_type = CLI_NONE; + } + return err; } #endif /* CONFIG_BLE_MESH_RPR_SRV */ #if CONFIG_BLE_MESH_PROVISIONER - return bt_mesh_provisioner_pb_gatt_open(conn, addr->val); + err = bt_mesh_provisioner_pb_gatt_open(conn, addr->val); + if (err) { + BT_ERR("pvnr pb gatt open fail %d", err); + server->conn_type = CLI_NONE; + } + return err; #endif /* CONFIG_BLE_MESH_PROVISIONER */ } @@ -615,7 +627,7 @@ int bt_mesh_proxy_client_prov_enable(void) BT_DBG("ProxyClientProvEnable"); for (i = 0; i < ARRAY_SIZE(servers); i++) { - if (servers[i].conn) { + if (servers[i].conn && servers[i].conn_type == CLI_NONE) { servers[i].conn_type = CLI_PROV; } } @@ -932,6 +944,11 @@ bool bt_mesh_proxy_client_relay(struct net_buf_simple *buf, uint16_t dst) * so we need to make a copy. */ net_buf_simple_reserve(&msg, 1); + if (buf->len > net_buf_simple_tailroom(&msg)) { + BT_ERR("Relay buf too large: %u > %u", buf->len, net_buf_simple_tailroom(&msg)); + continue; + } + net_buf_simple_add_mem(&msg, buf->data, buf->len); err = bt_mesh_proxy_client_send(server->conn, BLE_MESH_PROXY_NET_PDU, &msg); @@ -1220,6 +1237,9 @@ int bt_mesh_proxy_client_deinit(void) for (i = 0; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; k_delayed_work_free(&server->sar_timer); + if (server->conn) { + bt_mesh_conn_unref(server->conn); + } memset(server, 0, sizeof(struct bt_mesh_proxy_server)); } diff --git a/components/bt/esp_ble_mesh/core/proxy_server.c b/components/bt/esp_ble_mesh/core/proxy_server.c index 6021ca7f8f..2dcc54f58d 100644 --- a/components/bt/esp_ble_mesh/core/proxy_server.c +++ b/components/bt/esp_ble_mesh/core/proxy_server.c @@ -118,7 +118,12 @@ struct bt_mesh_proxy_client *bt_mesh_proxy_server_get_client(uint8_t index) { BT_DBG("ProxyServerGetClient, Index %u", index); - return &clients[0]; + if (index >= ARRAY_SIZE(clients)) { + BT_ERR("InvalidClientIndex %u", index); + return NULL; + } + + return &clients[index]; } uint8_t bt_mesh_proxy_server_get_client_count(void) @@ -514,6 +519,11 @@ static void proxy_send_beacons(struct k_work *work) BT_DBG("ProxySendBeacons"); + if (client == NULL || client->conn == NULL) { + BT_WARN("NullInProxySendBeacons %p", client); + return; + } + /* Upon connection, the Proxy Server shall evaluate Proxy Privacy parameter * for the connection and the Proxy Server shall retain the value of the * Proxy Privacy parameter for the lifetime of the connection. The Proxy @@ -664,7 +674,7 @@ bool bt_mesh_proxy_server_is_node_id_enable(void) struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; if (sub->net_idx != BLE_MESH_KEY_UNUSED && - sub->node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_RUNNING) { + sub->node_id == BLE_MESH_NODE_IDENTITY_RUNNING) { return true; } } @@ -921,9 +931,9 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) BT_DBG("ProxyConnected, ConnHandle 0x%04x Err 0x%02x", conn->handle, err); if (gatt_svc == MESH_GATT_PROV && conn_count == 1) { - BT_WARN("Only one prov connection could exists"); - bt_mesh_gatts_disconnect(conn, 0x13); - return; + BT_WARN("Only one prov connection could exists"); + bt_mesh_gatts_disconnect(conn, 0x13); + return; } conn_count++; @@ -957,6 +967,7 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) if (!client) { BT_ERR("No free Proxy Client objects"); + bt_mesh_gatts_disconnect(conn, 0x13); return; } @@ -1006,6 +1017,10 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) k_delayed_work_cancel(&rand_upd_timer); #endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV */ +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER + k_delayed_work_cancel(&client->send_beacons); +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ + k_delayed_work_cancel(&client->sar_timer); bt_mesh_conn_unref(client->conn); client->conn = NULL; @@ -1411,6 +1426,11 @@ bool bt_mesh_proxy_server_relay(struct net_buf_simple *buf, uint16_t dst) /* Proxy PDU sending modifies the original buffer, * so we need to make a copy. */ + if (1 + buf->len > msg.size) { + BT_WARN("Too large Net PDU for proxy relay (%u > %u)", 1 + buf->len, msg.size); + continue; + } + net_buf_simple_reserve(&msg, 1); net_buf_simple_add_mem(&msg, buf->data, buf->len); @@ -1446,6 +1466,7 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type, struct net_buf_simple *msg) { uint16_t mtu = 0U; + int err = 0; BT_DBG("ProxyServerSegSend"); BT_DBG("ConnHandle 0x%04x Type %u", conn->handle, type); @@ -1462,18 +1483,25 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type, } net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_FIRST, type)); - proxy_send(conn, msg->data, mtu); + err = proxy_send(conn, msg->data, mtu); + if (err) { + BT_ERR("ProxyServerSendFail %d", err); + return err; + } net_buf_simple_pull(msg, mtu); while (msg->len) { if (msg->len + 1 <= mtu) { net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_LAST, type)); - proxy_send(conn, msg->data, msg->len); - break; + return proxy_send(conn, msg->data, msg->len); } net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_CONT, type)); - proxy_send(conn, msg->data, mtu); + err = proxy_send(conn, msg->data, mtu); + if (err) { + BT_ERR("ProxyServerSendFail %d", err); + return err; + } net_buf_simple_pull(msg, mtu); } diff --git a/components/bt/esp_ble_mesh/core/pvnr_mgmt.c b/components/bt/esp_ble_mesh/core/pvnr_mgmt.c index 96ad2feb32..8fc5915d31 100644 --- a/components/bt/esp_ble_mesh/core/pvnr_mgmt.c +++ b/components/bt/esp_ble_mesh/core/pvnr_mgmt.c @@ -222,23 +222,29 @@ bool bt_mesh_provisioner_check_is_addr_dup(uint16_t addr, uint8_t elem_num, bool } } + bt_mesh_provisioner_lock(); + for (comp_addr = addr; comp_addr < addr + elem_num; comp_addr++) { for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) { node = mesh_nodes[i]; if (node && comp_addr >= node->unicast_addr && comp_addr < node->unicast_addr + node->element_num) { BT_ERR("Duplicate with node address 0x%04x", comp_addr); + bt_mesh_provisioner_unlock(); return true; } if (comp_with_own && comp_addr >= primary_addr && comp_addr < primary_addr + comp->elem_count) { BT_ERR("Duplicate with Provisioner address 0x%04x", comp_addr); + bt_mesh_provisioner_unlock(); return true; } } } + bt_mesh_provisioner_unlock(); + return false; } @@ -538,13 +544,18 @@ int bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t *addr) { int i; + bt_mesh_provisioner_lock(); + for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) { if (mesh_nodes[i] && mesh_nodes[i]->addr_type == addr->type && !memcmp(mesh_nodes[i]->addr, addr->val, BLE_MESH_ADDR_LEN)) { + bt_mesh_provisioner_unlock(); return provisioner_remove_node(i, true); } } + bt_mesh_provisioner_unlock(); + BT_WARN("Node not exist, device address %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN)); return -ENODEV; } @@ -686,9 +697,19 @@ static int store_node_comp_data(uint16_t addr, const uint8_t *data, uint16_t len return -ENODEV; } + bt_mesh_provisioner_lock(); + + /* Free old composition data of the node */ + if (node->comp_data) { + bt_mesh_free(node->comp_data); + node->comp_data = NULL; + node->comp_length = 0; + } + node->comp_data = bt_mesh_calloc(length); if (node->comp_data == NULL) { BT_ERR("%s, Out of memory", __func__); + bt_mesh_provisioner_unlock(); return -ENOMEM; } @@ -699,6 +720,7 @@ static int store_node_comp_data(uint16_t addr, const uint8_t *data, uint16_t len bt_mesh_store_node_comp_data(node); } + bt_mesh_provisioner_unlock(); return 0; } @@ -742,14 +764,18 @@ bool bt_mesh_provisioner_check_msg_dst(uint16_t dst) return true; } + bt_mesh_provisioner_lock(); + for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) { node = mesh_nodes[i]; if (node && dst >= node->unicast_addr && dst < node->unicast_addr + node->element_num) { + bt_mesh_provisioner_unlock(); return true; } } + bt_mesh_provisioner_unlock(); return false; } @@ -1174,39 +1200,48 @@ int bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16], uint16_t *n struct bt_mesh_subnet *sub = NULL; uint8_t p_key[16] = {0}; int add = -1; + int err = 0; + + bt_mesh_provisioner_lock(); if (bt_mesh.p_net_idx_next >= 0x1000) { BT_ERR("No NetKeyIndex available"); - return -EIO; + err = -EIO; + goto end; } if (!net_idx || (*net_idx != 0xFFFF && *net_idx >= 0x1000)) { BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; + err = -EINVAL; + goto end; } /* Check if the same network key already exists */ if (provisioner_check_net_key(net_key, net_idx)) { BT_WARN("NetKey exists, NetKeyIndex updated"); - return 0; + err = 0; + goto end; } /* Check if the same net_idx already exists */ if (provisioner_check_net_idx(*net_idx, true)) { BT_ERR("Invalid NetKeyIndex 0x%04x", *net_idx); - return -EEXIST; + err = -EEXIST; + goto end; } add = provisioner_check_net_key_full(); if (add < 0) { BT_ERR("NetKey is full!"); - return -ENOMEM; + err = -ENOMEM; + goto end; } if (!net_key) { if (bt_mesh_rand(p_key, 16)) { BT_ERR("Failed to generate NetKey"); - return -EIO; + err = -EIO; + goto end; } } else { memcpy(p_key, net_key, 16); @@ -1215,13 +1250,15 @@ int bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16], uint16_t *n sub = bt_mesh_calloc(sizeof(struct bt_mesh_subnet)); if (!sub) { BT_ERR("%s, Out of memory", __func__); - return -ENOMEM; + err = -ENOMEM; + goto end; } if (bt_mesh_net_keys_create(&sub->keys[0], p_key)) { BT_ERR("Failed to generate NID"); bt_mesh_free(sub); - return -EIO; + err = -EIO; + goto end; } if (*net_idx != 0xFFFF) { @@ -1234,7 +1271,8 @@ int bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16], uint16_t *n if (sub->net_idx >= 0x1000) { BT_ERR("No NetKeyIndex available"); bt_mesh_free(sub); - return -EIO; + err = -EIO; + goto end; } } else { break; @@ -1258,7 +1296,9 @@ int bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16], uint16_t *n bt_mesh_store_p_subnet(sub); } - return 0; +end: + bt_mesh_provisioner_unlock(); + return err; } int bt_mesh_provisioner_local_net_key_update(const uint8_t net_key[16], uint16_t net_idx) diff --git a/components/bt/esp_ble_mesh/core/scan.c b/components/bt/esp_ble_mesh/core/scan.c index a7a685d099..96b77e8a7f 100644 --- a/components/bt/esp_ble_mesh/core/scan.c +++ b/components/bt/esp_ble_mesh/core/scan.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -303,7 +303,11 @@ static void handle_adv_service_data(struct net_buf_simple *buf, switch (type) { #if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) && \ CONFIG_BLE_MESH_PB_GATT - case BLE_MESH_UUID_MESH_PROV_VAL: + case BLE_MESH_UUID_MESH_PROV_VAL: { + struct net_buf_simple_state state = {0}; + + net_buf_simple_save(buf, &state); + #if CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { if (buf->len != PROV_SVC_DATA_LEN) { @@ -316,10 +320,17 @@ static void handle_adv_service_data(struct net_buf_simple *buf, } #endif /* CONFIG_BLE_MESH_PROVISIONER */ + net_buf_simple_restore(buf, &state); + #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_is_provisioned()) { const bt_mesh_addr_t *addr = NULL; + if (buf->len != PROV_SVC_DATA_LEN) { + BT_WARN("Invalid Mesh Prov Service Data length %d", buf->len); + return; + } + addr = bt_mesh_get_unprov_dev_addr(); assert(addr); @@ -328,12 +339,14 @@ static void handle_adv_service_data(struct net_buf_simple *buf, bt_mesh_rpr_srv_unprov_beacon_recv(buf, bt_mesh_get_adv_type(), addr, rssi); } #endif /* CONFIG_BLE_MESH_RPR_SRV */ + + break; + } #endif /* (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) && CONFIG_BLE_MESH_PB_GATT */ - break; #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT - case BLE_MESH_UUID_MESH_PROXY_VAL: + case BLE_MESH_UUID_MESH_PROXY_VAL: { if (buf->len != PROXY_SVC_DATA_LEN_NET_ID && buf->len != PROXY_SVC_DATA_LEN_NODE_ID) { /* PROXY_SVC_DATA_LEN_NODE_ID, @@ -347,10 +360,11 @@ static void handle_adv_service_data(struct net_buf_simple *buf, BT_DBG("Start to handle Mesh Proxy Service Data"); bt_mesh_proxy_client_gatt_adv_recv(buf, addr, rssi); break; + } #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ #if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX - case BLE_MESH_UUID_MESH_PROXY_SOLIC_VAL: + case BLE_MESH_UUID_MESH_PROXY_SOLIC_VAL: { if (buf->len != (1 + BLE_MESH_NET_HDR_LEN + 8)) { BT_WARN("Invalid Mesh Proxy Solic Service Data length %d", buf->len); return; @@ -359,6 +373,7 @@ static void handle_adv_service_data(struct net_buf_simple *buf, BT_DBG("Start to handle Mesh Proxy Solic Service Data"); bt_mesh_proxy_server_solic_recv(buf, addr, rssi); break; + } #endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX */ default: diff --git a/components/bt/esp_ble_mesh/core/storage/settings.c b/components/bt/esp_ble_mesh/core/storage/settings.c index b48274eade..8d783893d6 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings.c +++ b/components/bt/esp_ble_mesh/core/storage/settings.c @@ -1424,7 +1424,7 @@ int settings_core_load(void) break; default: BT_ERR("Restored mesh device role: Unknown"); - return 0; + return -EINVAL; } } } @@ -1826,7 +1826,7 @@ static void store_pending_hb_pub(void) return; } - val.indefinite = (hb_pub->count = 0xffff); + val.indefinite = (hb_pub->count == 0xffff); val.dst = hb_pub->dst; val.period = hb_pub->period; val.ttl = hb_pub->ttl; @@ -2524,7 +2524,7 @@ void bt_mesh_clear_rpl(void) { BT_DBG("ClearRPLSchedule"); - schedule_store(BLE_MESH_RPL_PENDING); + clear_rpl(); } void bt_mesh_store_mod_bind(struct bt_mesh_model *model) @@ -2879,8 +2879,7 @@ int settings_core_init(void) { BT_DBG("SettingsCoreInit"); - k_delayed_work_init(&pending_store, store_pending); - return 0; + return k_delayed_work_init(&pending_store, store_pending); } int bt_mesh_settings_init(void) @@ -2942,7 +2941,7 @@ void bt_mesh_settings_reset(bool erase) #define SETTINGS_MAX_DIR_DEPTH 8 -int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, +int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len) { diff --git a/components/bt/esp_ble_mesh/core/storage/settings.h b/components/bt/esp_ble_mesh/core/storage/settings.h index 7ad8cf3cd6..27db4c852d 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings.h +++ b/components/bt/esp_ble_mesh/core/storage/settings.h @@ -35,7 +35,7 @@ void bt_mesh_store_mod_sub(struct bt_mesh_model *mod); void bt_mesh_store_mod_pub(struct bt_mesh_model *mod); void bt_mesh_store_label(void); -int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, +int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len); diff --git a/components/bt/esp_ble_mesh/core/storage/settings_nvs.c b/components/bt/esp_ble_mesh/core/storage/settings_nvs.c index f539c0a35a..6ca0083337 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings_nvs.c +++ b/components/bt/esp_ble_mesh/core/storage/settings_nvs.c @@ -186,6 +186,10 @@ int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle) err = bt_mesh_settings_nvs_open(ctx->nvs_name, &ctx->handle); if (err) { BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err); + /* Close the previously opened nvs nvs partition(s) */ + for (int j = 0; j < i; j++) { + bt_mesh_settings_nvs_close(settings_ctx[j].handle); + } return -EIO; } diff --git a/components/bt/esp_ble_mesh/core/storage/settings_uid.c b/components/bt/esp_ble_mesh/core/storage/settings_uid.c index e1de639722..fae4b89f5f 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings_uid.c +++ b/components/bt/esp_ble_mesh/core/storage/settings_uid.c @@ -150,6 +150,7 @@ int settings_uid_erase(void) * be erased when the deinit function is invoked, * no need to erase it here. */ + assert(user_ids[i].handle != INVALID_SETTINGS_HANDLE); bt_mesh_settings_nvs_close(user_ids[i].handle); } else if (settings_uid_empty(&user_ids[i]) == false) { /* When a user id is not empty, which means the nvs @@ -188,6 +189,7 @@ static int settings_direct_erase(uint8_t index) err = bt_mesh_settings_erase_all(handle); if (err) { BT_ERR("Erase settings failed, index %d", index); + bt_mesh_settings_nvs_close(handle); return err; } @@ -278,13 +280,13 @@ static int settings_open(uint8_t index) err = bt_mesh_save_uid_settings(name, (const uint8_t *)uid->id, SETTINGS_UID_SIZE); if (err) { BT_ERR("Save uid failed, name %s", name); - return err; + goto fail; } err = bt_mesh_add_uid_settings_item("mesh/uid", index); if (err) { BT_ERR("Add uid failed, index %d", index); - return err; + goto fail; } /* Mark this as open here, because we need this flag for @@ -295,16 +297,22 @@ static int settings_open(uint8_t index) err = settings_core_load(); if (err) { BT_ERR("Load settings failed, name %s", uid->name); - return err; + goto fail; } err = settings_core_commit(); if (err) { BT_ERR("Commit settings failed, name %s", uid->name); - return err; + goto fail; } return 0; + +fail: + bt_mesh_settings_nvs_close(uid->handle); + uid->handle = INVALID_SETTINGS_HANDLE; + uid->open = false; + return err; } int bt_mesh_provisioner_open_settings_with_index(uint8_t index) @@ -445,6 +453,7 @@ static int settings_delete(uint8_t index) * and delete the corresponding user id. */ struct settings_uid *uid = &user_ids[index]; + int err = 0; BT_DBG("SettingsDelete, Index %u UID %s", index, uid->id); @@ -453,7 +462,10 @@ static int settings_delete(uint8_t index) return -EBUSY; } - settings_direct_erase(index); + err = settings_direct_erase(index); + if (err) { + return err; + } memset(uid, 0, sizeof(struct settings_uid)); uid->handle = INVALID_SETTINGS_HANDLE; @@ -564,12 +576,24 @@ int bt_mesh_provisioner_direct_erase_settings(void) #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE for (int i = 0; i < ARRAY_SIZE(user_ids); i++) { - settings_direct_erase(i); + err = settings_direct_erase(i); + if (err) { + BT_ERR("SettingsDirectEraseFail %d %d", i, err); + /* Continue the following erase operation, no need to return */ + } } - bt_mesh_erase_uid_settings("mesh/uid"); + err = bt_mesh_erase_uid_settings("mesh/uid"); + if (err) { + BT_ERR("SettingsEraseUidFail %d", err); + /* Continue the following operation, no need to return */ + } #else /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ err = bt_mesh_settings_erase_all(handle); + if (err) { + BT_ERR("SettingsEraseAllFail %u %d", handle, err); + /* Continue the following operation, no need to return */ + } #endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ bt_mesh_settings_direct_close(); diff --git a/components/bt/esp_ble_mesh/core/test.c b/components/bt/esp_ble_mesh/core/test.c index 6433f9c0d4..29bd2e651f 100644 --- a/components/bt/esp_ble_mesh/core/test.c +++ b/components/bt/esp_ble_mesh/core/test.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,14 +50,16 @@ int bt_mesh_device_auto_enter_network(struct bt_mesh_device_network_info *info) bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); - /* The device becomes a node and enters the network */ - err = bt_mesh_provision(info->net_key, info->net_idx, info->flags, info->iv_index, - info->unicast_addr, info->dev_key); + err = bt_mesh_pre_provision(info->net_key, info->net_idx, info->flags, info->iv_index, + info->unicast_addr, info->dev_key); if (err) { - BT_ERR("bt_mesh_provision() failed (err %d)", err); + BT_ERR("bt_mesh_pre_provision() failed (err %d)", err); return err; } + /* The device becomes a node and enters the network */ + bt_mesh_provision(); + /* Adds application key to device */ sub = bt_mesh_subnet_get(info->net_idx); if (!sub) { diff --git a/components/bt/esp_ble_mesh/core/transport.c b/components/bt/esp_ble_mesh/core/transport.c index 8c5319b717..0c33dce5ef 100644 --- a/components/bt/esp_ble_mesh/core/transport.c +++ b/components/bt/esp_ble_mesh/core/transport.c @@ -150,12 +150,12 @@ static inline void bt_mesh_seg_tx_unlock(struct seg_tx *tx) static inline void bt_mesh_seg_rx_lock(void) { - bt_mesh_mutex_lock(&seg_rx_lock); + bt_mesh_r_mutex_lock(&seg_rx_lock); } static inline void bt_mesh_seg_rx_unlock(void) { - bt_mesh_mutex_unlock(&seg_rx_lock); + bt_mesh_r_mutex_unlock(&seg_rx_lock); } uint8_t bt_mesh_get_seg_rtx_num(void) @@ -344,6 +344,7 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) static void seg_tx_reset(struct seg_tx *tx) { + uint8_t seg_n = 0U; int i; BT_DBG("SegTxReset"); @@ -358,7 +359,8 @@ static void seg_tx_reset(struct seg_tx *tx) tx->sub = NULL; tx->dst = BLE_MESH_ADDR_UNASSIGNED; - for (i = 0; i <= tx->seg_n && tx->nack_count; i++) { + seg_n = MIN(tx->seg_n, ARRAY_SIZE(tx->seg) - 1); + for (i = 0; i <= seg_n && tx->nack_count; i++) { if (!tx->seg[i]) { continue; } @@ -616,6 +618,11 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, } else { tx->seg_n = 0; } + if (tx->seg_n >= ARRAY_SIZE(tx->seg)) { + BT_ERR("TooLargeSegNReceived %u/%u", tx->seg_n, ARRAY_SIZE(tx->seg)); + seg_tx_reset(tx); + return -EMSGSIZE; + } tx->nack_count = tx->seg_n + 1; tx->seq_auth = SEQ_AUTH(BLE_MESH_NET_IVI_TX, bt_mesh.seq); tx->sub = net_tx->sub; @@ -1067,6 +1074,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, struct net_buf_simple *buf, uint64_t *seq_auth) { struct seg_tx *tx = NULL; + bool tx_complete = false; uint16_t seq_zero = 0U; unsigned int bit = 0; uint32_t ack = 0U; @@ -1100,7 +1108,10 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, return -EINVAL; } + bt_mesh_seg_tx_lock(tx); + if (!BLE_MESH_ADDR_IS_UNICAST(tx->dst)) { + bt_mesh_seg_tx_unlock(tx); BT_WARN("Received ack for segments to group"); return -EINVAL; } @@ -1108,12 +1119,14 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, *seq_auth = tx->seq_auth; if (!ack) { + bt_mesh_seg_tx_unlock(tx); BT_WARN("SDU canceled"); seg_tx_complete(tx, -ECANCELED); return 0; } if (find_msb_set(ack) - 1 > tx->seg_n) { + bt_mesh_seg_tx_unlock(tx); BT_ERR("Too large segment number in ack"); return -EINVAL; } @@ -1124,15 +1137,17 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, if (tx->seg[bit - 1]) { BT_INFO("Seg %u/%u acked", bit - 1, tx->seg_n); - bt_mesh_seg_tx_lock(tx); seg_tx_done(tx, bit - 1); - bt_mesh_seg_tx_unlock(tx); } ack &= ~BIT(bit - 1); } - if (tx->nack_count) { + tx_complete = (tx->nack_count == 0); + + bt_mesh_seg_tx_unlock(tx); + + if (tx_complete == false) { seg_tx_send_unacked(tx); } else { BT_DBG("SDU TX complete"); @@ -1593,6 +1608,11 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, /* Copy the information in seg_rx into ext_seg_rx */ struct seg_rx *ext_rx = seg_rx_alloc(net_rx, &(rx->hdr), seq_auth, rx->seg_n); + if (!ext_rx) { + BT_ERR("Failed to alloc ext_rx for long packet"); + return NULL; + } + uint16_t last_seg_len = rx->buf.len - (rx->seg_n * seg_len(&si)); uint8_t *last_seg = rx->buf.data + (rx->seg_n * seg_len(&si)); @@ -1673,7 +1693,7 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, rx->seq_auth = *seq_auth; rx->seg_n = seg_n; rx->hdr = *hdr; - rx->ttl = net_rx->ctx.send_ttl; + rx->ttl = net_rx->ctx.recv_ttl; rx->src = net_rx->ctx.addr; rx->dst = net_rx->ctx.recv_dst; rx->block = 0U; @@ -1988,7 +2008,9 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) return 0; } + bt_mesh_seg_rx_lock(); err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); + bt_mesh_seg_rx_unlock(); } else { seg_count = 1U; @@ -2036,6 +2058,12 @@ void bt_mesh_rx_reset(void) for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { seg_rx_reset(&seg_rx[i], true); } + +#if CONFIG_BLE_MESH_LONG_PACKET + for (i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) { + seg_rx_reset(&ext_seg_rx[i], true); + } +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ } void bt_mesh_tx_reset(void) @@ -2065,6 +2093,15 @@ void bt_mesh_rx_reset_single(uint16_t src) seg_rx_reset(rx, true); } } + +#if CONFIG_BLE_MESH_LONG_PACKET + for (i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) { + struct seg_rx *rx = &ext_seg_rx[i]; + if (src == rx->src) { + seg_rx_reset(rx, true); + } + } +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ } void bt_mesh_tx_reset_single(uint16_t dst) @@ -2112,7 +2149,7 @@ void bt_mesh_trans_init(void) } #endif - bt_mesh_mutex_create(&seg_rx_lock); + bt_mesh_r_mutex_create(&seg_rx_lock); } #if CONFIG_BLE_MESH_DEINIT @@ -2133,6 +2170,12 @@ void bt_mesh_trans_deinit(bool erase) k_delayed_work_free(&seg_rx[i].ack_timer); } - bt_mesh_mutex_free(&seg_rx_lock); +#if CONFIG_BLE_MESH_LONG_PACKET + for (i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) { + k_delayed_work_free(&ext_seg_rx[i].ack_timer); + } +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ + + bt_mesh_r_mutex_free(&seg_rx_lock); } #endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/core/transport.enh.c b/components/bt/esp_ble_mesh/core/transport.enh.c index 7d81ebcbc5..4a962a6ba3 100644 --- a/components/bt/esp_ble_mesh/core/transport.enh.c +++ b/components/bt/esp_ble_mesh/core/transport.enh.c @@ -602,10 +602,7 @@ static bool send_next_segment(struct seg_tx *tx, int *result) return true; } - /* If security credentials is updated in the network layer, - * need to store the security credentials for the segments, - * which will be used for retransmission later. - */ + /* For sending the next segments, the credential must match */ if (tx->cred != net_tx.ctx->send_cred) { BT_ERR("MismatchSegCred %u vs. %u", tx->cred, net_tx.ctx->send_cred); @@ -1851,9 +1848,10 @@ static void seg_ack_send_start(uint16_t duration, int err, void *user_data) BT_INFO("SegAckSendStart, Err %d", err); if (err) { + bt_mesh_seg_rx_lock(); rx->last_ack = k_uptime_get_32(); - BT_DBG("LastAck %lu", rx->last_ack); + bt_mesh_seg_rx_unlock(); } } @@ -1862,12 +1860,15 @@ static void seg_ack_send_end(int err, void *user_data) struct seg_rx *rx = user_data; uint32_t interval = 0U; + bt_mesh_seg_rx_lock(); + BT_INFO("SegAckSendEnd, InUse %u Err %d", rx->in_use, err); /* This could happen when during the Segment ACK transaction, * the seg_rx is been reset. */ if (rx->in_use == 0) { + bt_mesh_seg_rx_unlock(); return; } @@ -1900,6 +1901,8 @@ static void seg_ack_send_end(int err, void *user_data) /* Introduce a delay for the Segment ACK retransmission */ k_delayed_work_submit(&rx->ack_timer, interval); } + + bt_mesh_seg_rx_unlock(); } static const struct bt_mesh_send_cb seg_ack_sent_cb = { @@ -2053,6 +2056,7 @@ static void discard_msg(struct k_work *work) timeout = bt_mesh_seg_discard_timeout(); BT_WARN("DiscardTimerExpired, timeout %lu", timeout); + ARG_UNUSED(timeout); /* Not fully reset the seg_rx, in case any segment of * this message is received later. @@ -2124,7 +2128,7 @@ static struct seg_rx *seg_rx_find_with_buf(struct bt_mesh_net_rx *net_rx, } /* Received a new packet when the old packet was not fully obtained */ - BT_WARN("Duplicate SDU from src 0x%04x auth 0x%04x", net_rx->ctx.addr, rx->seq_auth); + BT_WARN("Duplicate SDU from src 0x%04x auth 0x%016llx", net_rx->ctx.addr, rx->seq_auth); /* Clear out the old context since the sender * has apparently started sending a new SDU. @@ -2177,6 +2181,11 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, /* Copy the information in seg_rx into ext_seg_rx */ struct seg_rx *ext_rx = seg_rx_alloc(net_rx, &(rx->hdr), seq_auth, rx->seg_n); + if (!ext_rx) { + BT_ERR("Failed to alloc ext_rx for long packet"); + return NULL; + } + uint16_t last_seg_len = rx->buf.len - (rx->seg_n * seg_len(&si)); uint8_t *last_seg = rx->buf.data + (rx->seg_n * seg_len(&si)); @@ -2667,6 +2676,12 @@ void bt_mesh_rx_reset(void) for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { seg_rx_reset(&seg_rx[i], true); } + +#if CONFIG_BLE_MESH_LONG_PACKET + for (size_t i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) { + seg_rx_reset(&ext_seg_rx[i], true); + } +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ } void bt_mesh_tx_reset(void) @@ -2692,6 +2707,15 @@ void bt_mesh_rx_reset_single(uint16_t src) seg_rx_reset(rx, true); } } + +#if CONFIG_BLE_MESH_LONG_PACKET + for (size_t i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) { + struct seg_rx *rx = &ext_seg_rx[i]; + if (src == rx->src) { + seg_rx_reset(rx, true); + } + } +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ } void bt_mesh_tx_reset_single(uint16_t dst) diff --git a/components/bt/esp_ble_mesh/lib/ext.c b/components/bt/esp_ble_mesh/lib/ext.c index 7a8b37706f..9f7b61d548 100644 --- a/components/bt/esp_ble_mesh/lib/ext.c +++ b/components/bt/esp_ble_mesh/lib/ext.c @@ -1739,6 +1739,9 @@ uint8_t *bt_mesh_ext_prov_link_get_record(void *link, uint16_t id) uint8_t *bt_mesh_ext_prov_link_alloc_record(void *link, uint16_t id, uint16_t len) { #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_CERT_BASED_PROV) + if (id >= BLE_MESH_REC_MAX_ID) { + return NULL; + } LINK(link)->records[id] = bt_mesh_calloc(len * sizeof(uint8_t)); return LINK(link)->records[id]; #else diff --git a/components/bt/esp_ble_mesh/models/client/client_common.c b/components/bt/esp_ble_mesh/models/client/client_common.c index e87c68f62c..1c177c3cf9 100644 --- a/components/bt/esp_ble_mesh/models/client/client_common.c +++ b/components/bt/esp_ble_mesh/models/client/client_common.c @@ -210,6 +210,7 @@ static int32_t client_calc_timeout(struct bt_mesh_msg_ctx *ctx, mic_size = (need_seg && ctx->send_szmic == BLE_MESH_SEG_SZMIC_LONG && net_buf_simple_tailroom(msg) >= BLE_MESH_MIC_LONG) ? BLE_MESH_MIC_LONG : BLE_MESH_MIC_SHORT; + ARG_UNUSED(mic_size); BT_DBG("NeedSeg %u MicSize %u", need_seg, mic_size); @@ -223,11 +224,11 @@ static int32_t client_calc_timeout(struct bt_mesh_msg_ctx *ctx, #if CONFIG_BLE_MESH_LONG_PACKET if (ctx->enh.long_pkt_cfg && msg->len > BLE_MESH_TX_SDU_MAX) { - seg_count = (msg->len + mic_size - 1) / BLE_MESH_EXT_APP_SEG_SDU_MAX + 1U; + seg_count = DIV_ROUND_UP(msg->len, BLE_MESH_EXT_APP_SEG_SDU_MAX); } else #endif { - seg_count = (msg->len + mic_size - 1) / 12U + 1U; + seg_count = DIV_ROUND_UP(msg->len, BLE_MESH_APP_SEG_SDU_MAX); } duration = client_get_adv_duration(ctx); @@ -272,9 +273,8 @@ static void msg_send_start(uint16_t duration, int err, void *cb_data) BT_DBG("MsgSendStart, Duration %u Err %d", duration, err); if (err) { - if (!k_delayed_work_free(&node->timer)) { - bt_mesh_client_free_node(node); - } + k_delayed_work_free(&node->timer); + bt_mesh_client_free_node(node); return; } diff --git a/components/bt/esp_ble_mesh/models/client/time_scene_client.c b/components/bt/esp_ble_mesh/models/client/time_scene_client.c index 8cdc4800ee..84a8752ffa 100644 --- a/components/bt/esp_ble_mesh/models/client/time_scene_client.c +++ b/components/bt/esp_ble_mesh/models/client/time_scene_client.c @@ -15,7 +15,7 @@ #if CONFIG_BLE_MESH_TIME_SCENE_CLIENT #include "mesh/time_scene_client.h" -/* The followings are the macro definitions of Time Scene client +/* The following are the macro definitions of Time Scene client * model message length, and a message is composed of 3 parts: * Opcode + Payload + MIC */ @@ -114,12 +114,20 @@ static void time_scene_status(struct bt_mesh_model *model, } memcpy(status->tai_seconds, buf->data, 5); net_buf_simple_pull(buf, 5); - status->sub_second = net_buf_simple_pull_u8(buf); - status->uncertainty = net_buf_simple_pull_u8(buf); - uint16_t temp = net_buf_simple_pull_le16(buf); - status->time_authority = temp & BIT(0); - status->tai_utc_delta = temp >> 15; - status->time_zone_offset = net_buf_simple_pull_u8(buf); + if (buf->len) { + status->sub_second = net_buf_simple_pull_u8(buf); + status->uncertainty = net_buf_simple_pull_u8(buf); + uint16_t temp = net_buf_simple_pull_le16(buf); + status->time_authority = temp & BIT(0); + status->tai_utc_delta = temp >> 15; + status->time_zone_offset = net_buf_simple_pull_u8(buf); + } else { + status->sub_second = 0; + status->uncertainty = 0; + status->time_authority = 0; + status->tai_utc_delta = 0; + status->time_zone_offset = 0; + } val = (uint8_t *)status; len = sizeof(struct bt_mesh_time_status); break; diff --git a/components/bt/esp_ble_mesh/models/server/generic_server.c b/components/bt/esp_ble_mesh/models/server/generic_server.c index 747d78b25f..08c4ba19bb 100644 --- a/components/bt/esp_ble_mesh/models/server/generic_server.c +++ b/components/bt/esp_ble_mesh/models/server/generic_server.c @@ -1830,6 +1830,7 @@ static void gen_admin_prop_set(struct bt_mesh_model *model, struct bt_mesh_gen_admin_prop_srv *srv = model->user_data; struct bt_mesh_generic_property *property = NULL; uint16_t property_id = 0U; + uint8_t expect_len = 0U; uint8_t access = 0U; if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) { @@ -1865,6 +1866,13 @@ static void gen_admin_prop_set(struct bt_mesh_model *model, return; } + expect_len = bt_mesh_get_dev_prop_len(property_id); + if (buf->len != expect_len) { + BT_ERR("Invalid Admin Property 0x%04x length, expect %d, actual %d", + property_id, expect_len, buf->len); + return; + } + property->admin_access = access; net_buf_simple_reset(property->val); @@ -2062,19 +2070,16 @@ static void gen_manu_prop_set(struct bt_mesh_model *model, } /* Generic Client Property Server message handlers */ -static int search_prop_id_index(const uint16_t *array, uint8_t array_idx, uint16_t id) +static int search_prop_id_index(const uint16_t *array_start, + const uint16_t *array, + uint8_t array_idx, uint16_t id) { - static const uint16_t *start = NULL; uint8_t index = 0U; uint16_t temp = 0U; - if (start == NULL) { - start = array; - } - if (array_idx == 0U) { if (*array >= id) { - return array - start; + return array - array_start; } return -1; @@ -2084,14 +2089,14 @@ static int search_prop_id_index(const uint16_t *array, uint8_t array_idx, uint16 temp = array[index]; if (temp == id) { - return array + index - start; + return array + index - array_start; } if (temp > id) { - return search_prop_id_index(array, index, id); + return search_prop_id_index(array_start, array, index, id); } - return search_prop_id_index(array + index + 1, array_idx - 1 - index, id); + return search_prop_id_index(array_start, array + index + 1, array_idx - 1 - index, id); } static void gen_client_prop_get(struct bt_mesh_model *model, @@ -2126,7 +2131,7 @@ static void gen_client_prop_get(struct bt_mesh_model *model, */ property_id = net_buf_simple_pull_le16(buf); - index = search_prop_id_index(srv->property_ids, srv->id_count - 1, property_id); + index = search_prop_id_index(srv->property_ids, srv->property_ids, srv->id_count - 1, property_id); if (index < 0) { NET_BUF_SIMPLE_DEFINE(msg, 1 + BLE_MESH_SERVER_TRANS_MIC_SIZE); bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS); diff --git a/components/bt/esp_ble_mesh/models/server/lighting_server.c b/components/bt/esp_ble_mesh/models/server/lighting_server.c index 6df51458a4..ef82087294 100644 --- a/components/bt/esp_ble_mesh/models/server/lighting_server.c +++ b/components/bt/esp_ble_mesh/models/server/lighting_server.c @@ -371,7 +371,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, light_lightness_linear_tt_values(srv, trans_time, delay); } else { bt_mesh_light_server_state_change_t change = { - .lightness_linear_set.lightness = srv->state->lightness_actual, + .lightness_linear_set.lightness = srv->state->lightness_linear, }; bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change)); @@ -1513,15 +1513,14 @@ static void light_hsl_range_set(struct bt_mesh_model *model, saturation_min = net_buf_simple_pull_le16(buf); saturation_max = net_buf_simple_pull_le16(buf); - if (hue_min > hue_max) { - BT_ERR("Invalid parameter, hue min 0x%04x, hue max 0x%04x", - hue_min, hue_max); - return; - } - - if (saturation_min > saturation_max) { - BT_ERR("Invalid parameter, saturation min 0x%04x, saturation max 0x%04x", - saturation_min, saturation_max); + if (hue_min > hue_max || saturation_min > saturation_max) { + BT_ERR("Invalid parameter, hue 0x%04x/0x%04x saturation 0x%04x/0x%04x", + hue_min, hue_max, saturation_min, saturation_max); + srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN; + if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET) { + send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS); + } + send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS); return; } @@ -2497,102 +2496,113 @@ static void light_lc_sensor_status(struct bt_mesh_model *model, return; } - mpid = net_buf_simple_pull_le16(buf); - if (mpid & BIT(0)) { - length = (uint8_t)((mpid & 0xff) >> 1); - uint8_t msb = net_buf_simple_pull_u8(buf); - prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8); - } else { - length = (uint8_t)((mpid & 0x1f) >> 1); - prop_id = (uint16_t)(mpid >> 5); - } - - change.sensor_status.property_id = prop_id; - - switch (prop_id) { - case BLE_MESH_MOTION_SENSED: { - if (length != BLE_MESH_MOTION_SENSED_LEN || length != buf->len) { - BT_WARN("Invalid Motion Sensed Property length %d", length); - return; + while (buf->len >= 2) { + mpid = net_buf_simple_pull_le16(buf); + if (mpid & BIT(0)) { + if (buf->len < 1) { + BT_WARN("Invalid LC Sensor status length %d", buf->len); + return; + } + length = (uint8_t)((mpid & 0xff) >> 1); + uint8_t msb = net_buf_simple_pull_u8(buf); + prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8); + } else { + length = (uint8_t)((mpid & 0x1f) >> 1); + prop_id = (uint16_t)(mpid >> 5); } - uint8_t val = net_buf_simple_pull_u8(buf); - if (val > 0) { - srv->lc->state.occupancy = BLE_MESH_STATE_ON; - change.sensor_status.state.occupancy = srv->lc->state.occupancy; + change.sensor_status.property_id = prop_id; + + switch (prop_id) { + case BLE_MESH_MOTION_SENSED: { + if (length != BLE_MESH_MOTION_SENSED_LEN || + buf->len < BLE_MESH_MOTION_SENSED_LEN) { + BT_WARN("Invalid Motion Sensed Property length %d/%d", length, buf->len); + return; + } + uint8_t val = net_buf_simple_pull_u8(buf); + if (val > 0) { + srv->lc->state.occupancy = BLE_MESH_STATE_ON; + + change.sensor_status.state.occupancy = srv->lc->state.occupancy; + bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, + model, ctx, (const uint8_t *)&change, sizeof(change)); + } + break; + } + case BLE_MESH_PEOPLE_COUNT: { + if (length != BLE_MESH_PEOPLE_COUNT_LEN || + buf->len < BLE_MESH_PEOPLE_COUNT_LEN) { + BT_WARN("Invalid People Count Property length %d/%d", length, buf->len); + return; + } + uint16_t val = net_buf_simple_pull_le16(buf); + if (val > 0) { + srv->lc->state.occupancy = BLE_MESH_STATE_ON; + + change.sensor_status.state.occupancy = srv->lc->state.occupancy; + bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, + model, ctx, (const uint8_t *)&change, sizeof(change)); + } + break; + } + case BLE_MESH_PRESENCE_DETECTED: { + if (length != BLE_MESH_PRESENCE_DETECTED_LEN || + buf->len < BLE_MESH_PRESENCE_DETECTED_LEN) { + BT_WARN("Invalid Presence Detected Property length %d/%d", length, buf->len); + return; + } + uint8_t val = net_buf_simple_pull_u8(buf); + if (val > 0) { + srv->lc->state.occupancy = BLE_MESH_STATE_ON; + + change.sensor_status.state.occupancy = srv->lc->state.occupancy; + bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, + model, ctx, (const uint8_t *)&change, sizeof(change)); + } + break; + } + case BLE_MESH_TIME_SINCE_MOTION_SENSED: { + if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN || + buf->len < BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN) { + BT_WARN("Invalid Time Scene Motion Sensed Property length %d/%d", length, buf->len); + return; + } + uint16_t val = net_buf_simple_pull_le16(buf); + if (val <= srv->lc->prop_state.time_occupancy_delay) { + srv->lc->prop_state.set_occupancy_to_1_delay = + srv->lc->prop_state.time_occupancy_delay - val; + + change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay; + bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, + model, ctx, (const uint8_t *)&change, sizeof(change)); + } + break; + } + case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: { + /** + * Present Ambient Light Level device property is 4 octets, but ambient + * luxlevel length is 3 octets, and other devices may send Sensor Status + * which only contains 3 octets just for Light LC Server. + * Here we just check if the length is larger than 3. + */ + if (length < BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL_LEN || + buf->len < BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL_LEN) { + BT_WARN("Invalid Present Ambient Light Level Property length %d/%d", length, buf->len); + return; + } + uint16_t lsb = net_buf_simple_pull_le16(buf); + uint8_t msb = net_buf_simple_pull_u8(buf); + srv->lc->state.ambient_luxlevel = (msb << 16) | lsb; + + change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel; bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change)); + break; } - break; - } - case BLE_MESH_PEOPLE_COUNT: { - if (length != BLE_MESH_PEOPLE_COUNT_LEN || length != buf->len) { - BT_WARN("Invalid Motion Sensed Property length %d", length); - return; + default: + break; } - uint16_t val = net_buf_simple_pull_le16(buf); - if (val > 0) { - srv->lc->state.occupancy = BLE_MESH_STATE_ON; - - change.sensor_status.state.occupancy = srv->lc->state.occupancy; - bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, - model, ctx, (const uint8_t *)&change, sizeof(change)); - } - break; - } - case BLE_MESH_PRESENCE_DETECTED: { - if (length != BLE_MESH_PRESENCE_DETECTED_LEN || length != buf->len) { - BT_WARN("Invalid Motion Sensed Property length %d", length); - return; - } - uint8_t val = net_buf_simple_pull_u8(buf); - if (val > 0) { - srv->lc->state.occupancy = BLE_MESH_STATE_ON; - - change.sensor_status.state.occupancy = srv->lc->state.occupancy; - bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, - model, ctx, (const uint8_t *)&change, sizeof(change)); - } - break; - } - case BLE_MESH_TIME_SINCE_MOTION_SENSED: { - if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN || length != buf->len) { - BT_WARN("Invalid Motion Sensed Property length %d", length); - return; - } - uint16_t val = net_buf_simple_pull_le16(buf); - if (val <= srv->lc->prop_state.time_occupancy_delay) { - srv->lc->prop_state.set_occupancy_to_1_delay = - srv->lc->prop_state.time_occupancy_delay - val; - - change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay; - bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, - model, ctx, (const uint8_t *)&change, sizeof(change)); - } - break; - } - case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: { - /** - * Present Ambient Light Level device property is 4 octets, but ambient - * luxlevel length is 3 octets, and other devices may send Sensor Status - * which only contains 3 octets just for Light LC Server. - * Here we just check if the length is larger than 3. - */ - if (buf->len < 3) { - BT_WARN("Invalid Motion Sensed Property length %d", buf->len); - return; - } - uint16_t lsb = net_buf_simple_pull_le16(buf); - uint8_t msb = net_buf_simple_pull_u8(buf); - srv->lc->state.ambient_luxlevel = (msb << 16) | lsb; - - change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel; - bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, - model, ctx, (const uint8_t *)&change, sizeof(change)); - break; - } - default: - break; } } @@ -2731,7 +2741,7 @@ static void light_lc_prop_get(struct bt_mesh_model *model, /* Callback the received message to the application layer */ if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) { bt_mesh_light_server_recv_get_msg_t get = { - .lc_property_get.id = net_buf_simple_pull_le16(buf), + .lc_property_get.id = prop_id, }; bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, (const uint8_t *)&get, sizeof(get)); @@ -2762,8 +2772,8 @@ static void light_lc_prop_set(struct bt_mesh_model *model, if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) { bt_mesh_light_server_recv_set_msg_t set = { - .lc_property_set.id = net_buf_simple_pull_le16(buf), - .lc_property_set.value = buf, + .lc_property_set.id = prop_id, + .lc_property_set.value = buf->len ? buf : NULL, }; bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set)); diff --git a/components/bt/esp_ble_mesh/models/server/sensor_server.c b/components/bt/esp_ble_mesh/models/server/sensor_server.c index b920283ec6..f400b6c41e 100644 --- a/components/bt/esp_ble_mesh/models/server/sensor_server.c +++ b/components/bt/esp_ble_mesh/models/server/sensor_server.c @@ -599,6 +599,10 @@ static void sensor_get(struct bt_mesh_model *model, ctx->recv_op == BLE_MESH_MODEL_OP_SENSOR_GET) { bool get_all = buf->len ? false : true; if (buf->len) { + if (buf->len != 2) { + BT_ERR("Invalid Sensor Get msg length %u", buf->len); + return; + } prop_id = net_buf_simple_pull_le16(buf); if (prop_id == INVALID_SENSOR_PROPERTY_ID) { BT_ERR("Prohibited Sensor Property ID 0x0000"); @@ -806,11 +810,21 @@ static void sensor_cadence_set(struct bt_mesh_model *model, } if (state->cadence->trigger_delta_down) { + if (net_buf_simple_tailroom(state->cadence->trigger_delta_down) < trigger_len) { + BT_ERR("InsuffTriggerDeltaDownBufSize %d/%d", + net_buf_simple_tailroom(state->cadence->trigger_delta_down), trigger_len); + return; + } net_buf_simple_reset(state->cadence->trigger_delta_down); net_buf_simple_add_mem(state->cadence->trigger_delta_down, buf->data, trigger_len); net_buf_simple_pull_mem(buf, trigger_len); } if (state->cadence->trigger_delta_up) { + if (net_buf_simple_tailroom(state->cadence->trigger_delta_up) < trigger_len) { + BT_ERR("InsuffTriggerDeltaUpBufSize %d/%d", + net_buf_simple_tailroom(state->cadence->trigger_delta_up), trigger_len); + return; + } net_buf_simple_reset(state->cadence->trigger_delta_up); net_buf_simple_add_mem(state->cadence->trigger_delta_up, buf->data, trigger_len); net_buf_simple_pull_mem(buf, trigger_len); @@ -831,11 +845,21 @@ static void sensor_cadence_set(struct bt_mesh_model *model, if (buf->len) { uint8_t range_len = buf->len / 2; if (state->cadence->fast_cadence_low) { + if (net_buf_simple_tailroom(state->cadence->fast_cadence_low) < range_len) { + BT_ERR("InsuffFastCadenceLowBufSize %d/%d", + net_buf_simple_tailroom(state->cadence->fast_cadence_low), range_len); + return; + } net_buf_simple_reset(state->cadence->fast_cadence_low); net_buf_simple_add_mem(state->cadence->fast_cadence_low, buf->data, range_len); net_buf_simple_pull_mem(buf, range_len); } if (state->cadence->fast_cadence_high) { + if (net_buf_simple_tailroom(state->cadence->fast_cadence_high) < range_len) { + BT_ERR("InsuffFastCadenceHighBufSize %d/%d", + net_buf_simple_tailroom(state->cadence->fast_cadence_high), range_len); + return; + } net_buf_simple_reset(state->cadence->fast_cadence_high); net_buf_simple_add_mem(state->cadence->fast_cadence_high, buf->data, range_len); net_buf_simple_pull_mem(buf, range_len); @@ -1018,7 +1042,12 @@ static int check_sensor_server_init(struct bt_mesh_sensor_state *state_start, return -EINVAL; } } - if (state->setting_count && state->settings) { + if (state->setting_count) { + if (state->settings == NULL) { + BT_ERR("NullSettingsWithNonZeroSettingCount %u", state->setting_count); + return -EINVAL; + } + for (j = 0; j < state->setting_count; j++) { setting = &state->settings[j]; if (setting->property_id == INVALID_SENSOR_SETTING_PROPERTY_ID || setting->raw == NULL) { diff --git a/components/bt/esp_ble_mesh/models/server/state_transition.c b/components/bt/esp_ble_mesh/models/server/state_transition.c index 46c8281697..8a3879031c 100644 --- a/components/bt/esp_ble_mesh/models/server/state_transition.c +++ b/components/bt/esp_ble_mesh/models/server/state_transition.c @@ -95,12 +95,18 @@ static void transition_time_values(struct bt_mesh_state_transition *transition, transition->trans_time = trans_time; transition->delay = delay; - if (trans_time == 0U) { + if ((trans_time & 0x3F) == 0U) { + transition->counter = 0U; + transition->quo_tt = 0U; return; } tt_values_calculator(transition); - transition->quo_tt = transition->total_duration / transition->counter; + if (transition->counter) { + transition->quo_tt = transition->total_duration / transition->counter; + } else { + transition->quo_tt = 0; + } } static void transition_timer_start(struct bt_mesh_state_transition *transition) @@ -127,16 +133,24 @@ void generic_level_tt_values(struct bt_mesh_gen_level_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_level = - ((float) (srv->state.level - srv->state.target_level) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_level = + ((float) (srv->state.level - srv->state.target_level) / srv->transition.counter); + } else { + srv->tt_delta_level = 0; + } } void generic_power_level_tt_values(struct bt_mesh_gen_power_level_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_level = - ((float) (srv->state->power_actual - srv->state->target_power_actual) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_level = + ((float) (srv->state->power_actual - srv->state->target_power_actual) / srv->transition.counter); + } else { + srv->tt_delta_level = 0; + } } #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */ @@ -145,78 +159,117 @@ void light_lightness_actual_tt_values(struct bt_mesh_light_lightness_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->actual_transition, trans_time, delay); - srv->tt_delta_lightness_actual = - ((float) (srv->state->lightness_actual - srv->state->target_lightness_actual) / srv->actual_transition.counter); + if (srv->actual_transition.counter) { + srv->tt_delta_lightness_actual = + ((float) (srv->state->lightness_actual - srv->state->target_lightness_actual) / srv->actual_transition.counter); + } else { + srv->tt_delta_lightness_actual = 0; + } } void light_lightness_linear_tt_values(struct bt_mesh_light_lightness_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->linear_transition, trans_time, delay); - srv->tt_delta_lightness_linear = - ((float) (srv->state->lightness_linear - srv->state->target_lightness_linear) / srv->linear_transition.counter); + if (srv->linear_transition.counter) { + srv->tt_delta_lightness_linear = + ((float) (srv->state->lightness_linear - srv->state->target_lightness_linear) / srv->linear_transition.counter); + } else { + srv->tt_delta_lightness_linear = 0; + } } void light_ctl_tt_values(struct bt_mesh_light_ctl_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_lightness = - ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); - srv->tt_delta_temperature = - ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter); - srv->tt_delta_delta_uv = - ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_lightness = + ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); + srv->tt_delta_temperature = + ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter); + srv->tt_delta_delta_uv = + ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter); + } else { + srv->tt_delta_lightness = 0; + srv->tt_delta_temperature = 0; + srv->tt_delta_delta_uv = 0; + } } void light_ctl_temp_tt_values(struct bt_mesh_light_ctl_temp_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_temperature = - ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter); - srv->tt_delta_delta_uv = - ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_temperature = + ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter); + srv->tt_delta_delta_uv = + ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter); + } else { + srv->tt_delta_temperature = 0; + srv->tt_delta_delta_uv = 0; + } } void light_hsl_tt_values(struct bt_mesh_light_hsl_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_lightness = - ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); - srv->tt_delta_hue = - ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter); - srv->tt_delta_saturation = - ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_lightness = + ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); + srv->tt_delta_hue = + ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter); + srv->tt_delta_saturation = + ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter); + } else { + srv->tt_delta_lightness = 0; + srv->tt_delta_hue = 0; + srv->tt_delta_saturation = 0; + } } void light_hsl_hue_tt_values(struct bt_mesh_light_hsl_hue_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_hue = - ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_hue = + ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter); + } else { + srv->tt_delta_hue = 0; + } } void light_hsl_sat_tt_values(struct bt_mesh_light_hsl_sat_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_saturation = - ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_saturation = + ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter); + } else { + srv->tt_delta_saturation = 0; + } } void light_xyl_tt_values(struct bt_mesh_light_xyl_srv *srv, uint8_t trans_time, uint8_t delay) { transition_time_values(&srv->transition, trans_time, delay); - srv->tt_delta_lightness = - ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); - srv->tt_delta_x = - ((float) (srv->state->x - srv->state->target_x) / srv->transition.counter); - srv->tt_delta_y = - ((float) (srv->state->y - srv->state->target_y) / srv->transition.counter); + if (srv->transition.counter) { + srv->tt_delta_lightness = + ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter); + srv->tt_delta_x = + ((float) (srv->state->x - srv->state->target_x) / srv->transition.counter); + srv->tt_delta_y = + ((float) (srv->state->y - srv->state->target_y) / srv->transition.counter); + } else { + srv->tt_delta_lightness = 0; + srv->tt_delta_x = 0; + srv->tt_delta_y = 0; + } } void light_lc_tt_values(struct bt_mesh_light_lc_srv *srv, diff --git a/components/bt/esp_ble_mesh/models/server/time_scene_server.c b/components/bt/esp_ble_mesh/models/server/time_scene_server.c index a63550bc7f..7a8061c47a 100644 --- a/components/bt/esp_ble_mesh/models/server/time_scene_server.c +++ b/components/bt/esp_ble_mesh/models/server/time_scene_server.c @@ -235,6 +235,7 @@ static void time_get(struct bt_mesh_model *model, srv->state->time.subsecond = net_buf_simple_pull_u8(buf); srv->state->time.uncertainty = net_buf_simple_pull_u8(buf); val = net_buf_simple_pull_le16(buf); + srv->state->time.time_authority = val & BIT(0); srv->state->time.tai_utc_delta_curr = (val >> 1) & BIT_MASK(15); srv->state->time.time_zone_offset_curr = net_buf_simple_pull_u8(buf); } @@ -754,6 +755,7 @@ static void scene_action(struct bt_mesh_model *model, if (i == srv->state->scene_count) { BT_WARN("Scene Register is full!"); srv->state->status_code = SCENE_REG_FULL; +#if 0 /* Get the Scene Number of the currently active scene */ for (i = 0; i < srv->state->scene_count; i++) { scene = &srv->state->scenes[i]; @@ -766,10 +768,12 @@ static void scene_action(struct bt_mesh_model *model, /* A value of 0x0000 when no scene is active */ srv->state->current_scene = INVALID_SCENE_NUMBER; } +#endif } } - if (srv->state->in_progress == true) { + if (srv->state->status_code == SCENE_SUCCESS && + srv->state->in_progress == true) { /** * When the scene transition is in progress and a new Scene Number is * stored in the Scene Register as a result of Scene Store operation, @@ -940,6 +944,12 @@ static void send_scheduler_act_status(struct bt_mesh_model *model, switch (model->id) { case BLE_MESH_MODEL_ID_SCHEDULER_SRV: { struct bt_mesh_scheduler_srv *srv = model->user_data; + if (srv == NULL || srv->state == NULL || + srv->state->schedules == NULL || + index >= srv->state->schedule_count) { + BT_ERR("InvalidScheduleSrvParams"); + return; + } value = get_schedule_reg_state(srv->state, index); net_buf_simple_add_le32(&msg, (uint32_t)value); net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32)); @@ -948,6 +958,12 @@ static void send_scheduler_act_status(struct bt_mesh_model *model, } case BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV: { struct bt_mesh_scheduler_setup_srv *srv = model->user_data; + if (srv == NULL || srv->state == NULL || + srv->state->schedules == NULL || + index >= srv->state->schedule_count) { + BT_ERR("InvalidScheduleSrvParams"); + return; + } value = get_schedule_reg_state(srv->state, index); net_buf_simple_add_le32(&msg, (uint32_t)value); net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32)); @@ -1056,6 +1072,11 @@ static void scheduler_act_set(struct bt_mesh_model *model, return; } + if (index >= srv->state->schedule_count) { + BT_ERR("TooLargeScheduleIndex %u/%u", index, srv->state->schedule_count); + return; + } + if (year > SCHEDULE_YEAR_ANY_YEAR) { BT_ERR("Invalid Scheduler Register year 0x%02x", year); return; diff --git a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h index 0f9097262a..44fa7aec8a 100644 --- a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h +++ b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h @@ -13,7 +13,7 @@ #if CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV #ifndef _BLE_MESH_BLOB_DEPRECATE_WARN #define _BLE_MESH_BLOB_DEPRECATE_WARN -#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future. +// #warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future. #endif #endif /* CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV */ diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c index 3da11c10d2..ad087c33eb 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c @@ -40,29 +40,45 @@ void btc_ble_mesh_agg_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_AGG_CLIENT_SEND: - dst->agg_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->agg_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_agg_client_msg_t)); - if (dst->agg_send.params && dst->agg_send.msg) { - memcpy(dst->agg_send.params, src->agg_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->agg_send.msg, src->agg_send.msg, - sizeof(esp_ble_mesh_agg_client_msg_t)); - if (src->agg_send.params->opcode == ESP_BLE_MESH_MODEL_OP_AGG_SEQUENCE) { - if (src->agg_send.msg->agg_sequence.items) { - length = src->agg_send.msg->agg_sequence.items->len; - dst->agg_send.msg->agg_sequence.items = bt_mesh_alloc_buf(length); - if (!dst->agg_send.msg->agg_sequence.items) { - BT_ERR("%s, Out of memory", __func__); - break; - } + dst->agg_send.params = NULL; + dst->agg_send.msg = NULL; - net_buf_simple_add_mem(dst->agg_send.msg->agg_sequence.items, - src->agg_send.msg->agg_sequence.items->data, - src->agg_send.msg->agg_sequence.items->len); - } - } - } else { + dst->agg_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->agg_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + return; + } + + dst->agg_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_agg_client_msg_t)); + if (!dst->agg_send.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->agg_send.params); + dst->agg_send.params = NULL; + return; + } + + memcpy(dst->agg_send.params, src->agg_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->agg_send.msg, src->agg_send.msg, sizeof(esp_ble_mesh_agg_client_msg_t)); + + if (src->agg_send.params->opcode == ESP_BLE_MESH_MODEL_OP_AGG_SEQUENCE) { + if (src->agg_send.msg->agg_sequence.items) { + length = src->agg_send.msg->agg_sequence.items->len; + dst->agg_send.msg->agg_sequence.items = bt_mesh_alloc_buf(length); + if (!dst->agg_send.msg->agg_sequence.items) { + BT_ERR("%s, Out of memory", __func__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->agg_send.params); + dst->agg_send.params = NULL; + bt_mesh_free(dst->agg_send.msg); + dst->agg_send.msg = NULL; + break; + } + + net_buf_simple_add_mem(dst->agg_send.msg->agg_sequence.items, + src->agg_send.msg->agg_sequence.items->data, + src->agg_send.msg->agg_sequence.items->len); + } } break; default: @@ -134,6 +150,9 @@ static void btc_ble_mesh_agg_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.agg_status.items = bt_mesh_alloc_buf(length); if (!p_dest_data->recv.agg_status.items) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c index 36e9446024..6b607eab18 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c @@ -49,6 +49,9 @@ void btc_ble_mesh_brc_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_BRC_CLIENT_SEND: + dst->brc_send.params = NULL; + dst->brc_send.msg = NULL; + dst->brc_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->brc_send.params) { memcpy(dst->brc_send.params, src->brc_send.params, @@ -64,6 +67,9 @@ void btc_ble_mesh_brc_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p sizeof(esp_ble_mesh_brc_client_msg_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->brc_send.params); + dst->brc_send.params = NULL; } } break; @@ -131,6 +137,9 @@ static void btc_ble_mesh_brc_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.bridged_subnets_list.net_idx_pair = bt_mesh_calloc(length); if (!p_dest_data->recv.bridged_subnets_list.net_idx_pair) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } memcpy(p_dest_data->recv.bridged_subnets_list.net_idx_pair, @@ -144,6 +153,9 @@ static void btc_ble_mesh_brc_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.bridging_table_list.bridged_addr_list = bt_mesh_calloc(length); if (!p_dest_data->recv.bridging_table_list.bridged_addr_list) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } memcpy(p_dest_data->recv.bridging_table_list.bridged_addr_list, diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c index aa4cadad11..92dc75e490 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c @@ -75,6 +75,9 @@ void btc_ble_mesh_df_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_ switch (msg->act) { case BTC_BLE_MESH_ACT_DF_CLIENT_GET_STATE: { + dst->df_get.params = NULL; + dst->df_get.get = NULL; + dst->df_get.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->df_get.params) { memcpy(dst->df_get.params, src->df_get.params, @@ -90,81 +93,122 @@ void btc_ble_mesh_df_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_ sizeof(esp_ble_mesh_df_client_get_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->df_get.params); + dst->df_get.params = NULL; } } break; } case BTC_BLE_MESH_ACT_DF_CLIENT_SET_STATE: { + dst->df_set.params = NULL; + dst->df_set.set = NULL; + dst->df_set.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->df_set.set = bt_mesh_calloc(sizeof(esp_ble_mesh_df_client_set_t)); - if (dst->df_set.params && dst->df_set.set) { - memcpy(dst->df_set.params, src->df_set.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->df_set.set, src->df_set.set, - sizeof(esp_ble_mesh_df_client_set_t)); - - switch (src->df_set.params->opcode) { - case ESP_BLE_MESH_MODEL_OP_FORWARDING_TABLE_DEPS_ADD: - if (src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list && - src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list_size) { - length = src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list_size * sizeof(esp_ble_mesh_uar_t); - dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list = bt_mesh_calloc(length); - if (!dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - - memcpy(dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list, - src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list, - length); - } - if (src->df_set.set->forwarding_table_deps_add.dep_target_uar_list && - src->df_set.set->forwarding_table_deps_add.dep_target_uar_list_size) { - length = src->df_set.set->forwarding_table_deps_add.dep_target_uar_list_size * sizeof(esp_ble_mesh_uar_t); - dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list = bt_mesh_calloc(length); - if (!dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - - memcpy(dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list, - src->df_set.set->forwarding_table_deps_add.dep_target_uar_list, - length); - } - break; - case ESP_BLE_MESH_MODEL_OP_FORWARDING_TABLE_DEPS_DEL: - if (src->df_set.set->forwarding_table_deps_del.dep_origin_list && - src->df_set.set->forwarding_table_deps_del.dep_origin_list_size) { - length = src->df_set.set->forwarding_table_deps_del.dep_origin_list_size * 2; - dst->df_set.set->forwarding_table_deps_del.dep_origin_list = bt_mesh_calloc(length); - if (!dst->df_set.set->forwarding_table_deps_del.dep_origin_list) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - - memcpy(dst->df_set.set->forwarding_table_deps_del.dep_origin_list, - src->df_set.set->forwarding_table_deps_del.dep_origin_list, - length); - } - if (src->df_set.set->forwarding_table_deps_del.dep_target_list && - src->df_set.set->forwarding_table_deps_del.dep_target_list_size) { - length = src->df_set.set->forwarding_table_deps_del.dep_target_list_size * 2; - dst->df_set.set->forwarding_table_deps_del.dep_target_list = bt_mesh_calloc(length); - if (!dst->df_set.set->forwarding_table_deps_del.dep_target_list) { - BT_ERR("%s, Out of memory, act %d", __func__, msg->act); - return; - } - - memcpy(dst->df_set.set->forwarding_table_deps_del.dep_target_list, - src->df_set.set->forwarding_table_deps_del.dep_target_list, - length); - } - break; - default: - break; - } - } else { + if (!dst->df_set.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; + } + + dst->df_set.set = bt_mesh_calloc(sizeof(esp_ble_mesh_df_client_set_t)); + if (!dst->df_set.set) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->df_set.params); + dst->df_set.params = NULL; + break; + } + + memcpy(dst->df_set.params, src->df_set.params, sizeof(esp_ble_mesh_client_common_param_t)); + memcpy(dst->df_set.set, src->df_set.set, sizeof(esp_ble_mesh_df_client_set_t)); + + switch (src->df_set.params->opcode) { + case ESP_BLE_MESH_MODEL_OP_FORWARDING_TABLE_DEPS_ADD: + if (src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list && + src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list_size) { + length = src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list_size * sizeof(esp_ble_mesh_uar_t); + dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list = bt_mesh_calloc(length); + if (!dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->df_set.params); + dst->df_set.params = NULL; + bt_mesh_free(dst->df_set.set); + dst->df_set.set = NULL; + return; + } + + memcpy(dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list, + src->df_set.set->forwarding_table_deps_add.dep_origin_uar_list, + length); + } + if (src->df_set.set->forwarding_table_deps_add.dep_target_uar_list && + src->df_set.set->forwarding_table_deps_add.dep_target_uar_list_size) { + length = src->df_set.set->forwarding_table_deps_add.dep_target_uar_list_size * sizeof(esp_ble_mesh_uar_t); + dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list = bt_mesh_calloc(length); + if (!dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list) { + bt_mesh_free(dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list); + dst->df_set.set->forwarding_table_deps_add.dep_origin_uar_list = NULL; + } + bt_mesh_free(dst->df_set.params); + dst->df_set.params = NULL; + bt_mesh_free(dst->df_set.set); + dst->df_set.set = NULL; + return; + } + + memcpy(dst->df_set.set->forwarding_table_deps_add.dep_target_uar_list, + src->df_set.set->forwarding_table_deps_add.dep_target_uar_list, + length); + } + break; + case ESP_BLE_MESH_MODEL_OP_FORWARDING_TABLE_DEPS_DEL: + if (src->df_set.set->forwarding_table_deps_del.dep_origin_list && + src->df_set.set->forwarding_table_deps_del.dep_origin_list_size) { + length = src->df_set.set->forwarding_table_deps_del.dep_origin_list_size * 2; + dst->df_set.set->forwarding_table_deps_del.dep_origin_list = bt_mesh_calloc(length); + if (!dst->df_set.set->forwarding_table_deps_del.dep_origin_list) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->df_set.params); + dst->df_set.params = NULL; + bt_mesh_free(dst->df_set.set); + dst->df_set.set = NULL; + return; + } + + memcpy(dst->df_set.set->forwarding_table_deps_del.dep_origin_list, + src->df_set.set->forwarding_table_deps_del.dep_origin_list, + length); + } + if (src->df_set.set->forwarding_table_deps_del.dep_target_list && + src->df_set.set->forwarding_table_deps_del.dep_target_list_size) { + length = src->df_set.set->forwarding_table_deps_del.dep_target_list_size * 2; + dst->df_set.set->forwarding_table_deps_del.dep_target_list = bt_mesh_calloc(length); + if (!dst->df_set.set->forwarding_table_deps_del.dep_target_list) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (dst->df_set.set->forwarding_table_deps_del.dep_origin_list) { + bt_mesh_free(dst->df_set.set->forwarding_table_deps_del.dep_origin_list); + dst->df_set.set->forwarding_table_deps_del.dep_origin_list = NULL; + } + bt_mesh_free(dst->df_set.params); + dst->df_set.params = NULL; + bt_mesh_free(dst->df_set.set); + dst->df_set.set = NULL; + return; + } + + memcpy(dst->df_set.set->forwarding_table_deps_del.dep_target_list, + src->df_set.set->forwarding_table_deps_del.dep_target_list, + length); + } + break; + default: + break; } break; } @@ -255,6 +299,9 @@ static void btc_ble_mesh_df_client_copy_req_data(btc_msg_t *msg, void *p_dest, v p_dest_data->recv.forwarding_table_entries_status.entry_list = bt_mesh_calloc(length); if (!p_dest_data->recv.forwarding_table_entries_status.entry_list) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } @@ -270,6 +317,9 @@ static void btc_ble_mesh_df_client_copy_req_data(btc_msg_t *msg, void *p_dest, v p_dest_data->recv.forwarding_table_deps_get_status.dep_origin_uar_list = bt_mesh_calloc(length); if (!p_dest_data->recv.forwarding_table_deps_get_status.dep_origin_uar_list) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } @@ -282,6 +332,13 @@ static void btc_ble_mesh_df_client_copy_req_data(btc_msg_t *msg, void *p_dest, v p_dest_data->recv.forwarding_table_deps_get_status.dep_target_uar_list = bt_mesh_calloc(length); if (!p_dest_data->recv.forwarding_table_deps_get_status.dep_target_uar_list) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + if (p_dest_data->recv.forwarding_table_deps_get_status.dep_origin_uar_list) { + bt_mesh_free(p_dest_data->recv.forwarding_table_deps_get_status.dep_origin_uar_list); + p_dest_data->recv.forwarding_table_deps_get_status.dep_origin_uar_list = NULL; + } + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c index d23497ef2f..f316486c0c 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c @@ -41,6 +41,9 @@ void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE: { + dst->dfu_get.params = NULL; + dst->dfu_get.get = NULL; + dst->dfu_get.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->dfu_get.params) { memcpy(dst->dfu_get.params, src->dfu_get.params, @@ -62,20 +65,28 @@ void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p src->dfu_get.get->dfu_metadata_check.metadata->data, src->dfu_get.get->dfu_metadata_check.metadata->len); } else { + /* Free the previously allocated resources */ bt_mesh_free(dst->dfu_get.get); + dst->dfu_get.get = NULL; bt_mesh_free(dst->dfu_get.params); + dst->dfu_get.params = NULL; BT_ERR("Out of memory for metadata"); return; } } else { + /* Free the previously allocated resources */ bt_mesh_free(dst->dfu_get.get); + dst->dfu_get.get = NULL; bt_mesh_free(dst->dfu_get.params); + dst->dfu_get.params = NULL; BT_ERR("Metadata should be exists"); return; } } } else { + /* Free the previously allocated resources */ bt_mesh_free(dst->dfu_get.params); + dst->dfu_get.params = NULL; BT_ERR("%s, Out of memory, act %d", __func__, msg->act); } } @@ -105,19 +116,20 @@ void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg) switch (msg->act) { case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE: - if (arg->dfu_get.get) { - switch (arg->dfu_get.params->opcode) { - case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK: - if (arg->dfu_get.get->dfu_metadata_check.metadata) { - bt_mesh_free_buf(arg->dfu_get.get->dfu_metadata_check.metadata); - } - break; - default: - break; - } - bt_mesh_free(arg->dfu_get.get); - } if (arg->dfu_get.params) { + if (arg->dfu_get.get) { + switch (arg->dfu_get.params->opcode) { + case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK: + if (arg->dfu_get.get->dfu_metadata_check.metadata) { + bt_mesh_free_buf(arg->dfu_get.get->dfu_metadata_check.metadata); + } + break; + default: + break; + } + bt_mesh_free(arg->dfu_get.get); + } + bt_mesh_free(arg->dfu_get.params); } break; @@ -156,8 +168,10 @@ static void btc_ble_mesh_dfu_client_copy_req_data(btc_msg_t *msg, void *p_dest, length = p_src_data->recv.dfu_update_info_status.fw_info_list_cnt * sizeof(esp_ble_mesh_firmware_info_t); p_dest_data->recv.dfu_update_info_status.fw_info_list = bt_mesh_calloc(length); if (!p_dest_data->recv.dfu_update_info_status.fw_info_list) { - bt_mesh_free(p_dest_data->params); BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } memcpy(p_dest_data->recv.dfu_update_info_status.fw_info_list, @@ -595,6 +609,9 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_DFD_CLIENT_GET: + dst->dfd_client_get.params = NULL; + dst->dfd_client_get.get = NULL; + dst->dfd_client_get.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->dfd_client_get.params == NULL) { @@ -606,9 +623,10 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p if (src->dfd_client_get.get) { dst->dfd_client_get.get = (esp_ble_mesh_dfd_client_get_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_client_get_param_t)); if (dst->dfd_client_get.get == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_get.params); dst->dfd_client_get.params = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } memcpy(dst->dfd_client_get.get, src->dfd_client_get.get, sizeof(esp_ble_mesh_dfd_client_get_param_t)); @@ -618,6 +636,7 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p case ESP_BLE_MESH_DFD_OP_FW_GET: if (src->dfd_client_get.get->dist_fw_get.fwid == NULL) { BT_ERR("%s:%d,InvParam", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_get.params); dst->dfd_client_get.params = NULL; bt_mesh_free(dst->dfd_client_get.get); @@ -628,23 +647,26 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p dst->dfd_client_get.get->dist_fw_get.fwid = bt_mesh_alloc_buf(src->dfd_client_get.get->dist_fw_get.fwid->len); if (dst->dfd_client_get.get->dist_fw_get.fwid == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_get.params); dst->dfd_client_get.params = NULL; bt_mesh_free(dst->dfd_client_get.get); dst->dfd_client_get.get = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } - net_buf_simple_add_mem( - dst->dfd_client_get.get->dist_fw_get.fwid, - src->dfd_client_get.get->dist_fw_get.fwid->data, - src->dfd_client_get.get->dist_fw_get.fwid->len); - break; + net_buf_simple_add_mem(dst->dfd_client_get.get->dist_fw_get.fwid, + src->dfd_client_get.get->dist_fw_get.fwid->data, + src->dfd_client_get.get->dist_fw_get.fwid->len); + break; default: break; } break; case BTC_BLE_MESH_ACT_DFD_CLIENT_SET: + dst->dfd_client_set.params = NULL; + dst->dfd_client_set.set = NULL; + dst->dfd_client_set.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->dfd_client_set.params == NULL) { @@ -656,9 +678,10 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p if (src->dfd_client_set.set) { dst->dfd_client_set.set = (esp_ble_mesh_dfd_client_set_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_client_set_param_t)); if (dst->dfd_client_set.set == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } memcpy(dst->dfd_client_set.set, src->dfd_client_set.set, sizeof(esp_ble_mesh_dfd_client_set_param_t)); @@ -667,52 +690,55 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD: if (src->dfd_client_set.set->receivers_add.receivers_cnt == 0) { dst->dfd_client_set.set->receivers_add.receivers = NULL; + BT_ERR("%s:%d,InvParam", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,InvParam", __func__, __LINE__); break; } dst->dfd_client_set.set->receivers_add.receivers = (esp_ble_mesh_dfd_cli_receiver_entry_t *)bt_mesh_calloc(dst->dfd_client_set.set->receivers_add.receivers_cnt * sizeof(esp_ble_mesh_dfd_cli_receiver_entry_t)); if (dst->dfd_client_set.set->receivers_add.receivers == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } memcpy(dst->dfd_client_set.set->receivers_add.receivers, src->dfd_client_set.set->receivers_add.receivers, dst->dfd_client_set.set->receivers_add.receivers_cnt * sizeof(esp_ble_mesh_dfd_cli_receiver_entry_t)); - break; + break; case ESP_BLE_MESH_DFD_OP_UPLOAD_START: if (src->dfd_client_set.set->dist_upload_start.fwid == NULL) { dst->dfd_client_set.set->dist_upload_start.fwid = NULL; + BT_ERR("%s:%d,InvParam", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,InvParam", __func__, __LINE__); break; } dst->dfd_client_set.set->dist_upload_start.fwid = bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_start.fwid->len); if (dst->dfd_client_set.set->dist_upload_start.fwid == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } - net_buf_simple_add_mem( - dst->dfd_client_set.set->dist_upload_start.fwid, - src->dfd_client_set.set->dist_upload_start.fwid->data, - src->dfd_client_set.set->dist_upload_start.fwid->len); + net_buf_simple_add_mem(dst->dfd_client_set.set->dist_upload_start.fwid, + src->dfd_client_set.set->dist_upload_start.fwid->data, + src->dfd_client_set.set->dist_upload_start.fwid->len); if (src->dfd_client_set.set->dist_upload_start.fw_metadata->len == 0) { dst->dfd_client_set.set->dist_upload_start.fw_metadata = NULL; @@ -721,86 +747,88 @@ void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p dst->dfd_client_set.set->dist_upload_start.fw_metadata = bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_start.fw_metadata->len); if (dst->dfd_client_set.set->dist_upload_start.fw_metadata == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free_buf(dst->dfd_client_set.set->dist_upload_start.fwid); + dst->dfd_client_set.set->dist_upload_start.fwid = NULL; bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - bt_mesh_free_buf(dst->dfd_client_set.set->dist_upload_start.fwid); - dst->dfd_client_set.set->dist_upload_start.fwid = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } - net_buf_simple_add_mem( - dst->dfd_client_set.set->dist_upload_start.fw_metadata, - src->dfd_client_set.set->dist_upload_start.fw_metadata->data, - src->dfd_client_set.set->dist_upload_start.fw_metadata->len); + net_buf_simple_add_mem(dst->dfd_client_set.set->dist_upload_start.fw_metadata, + src->dfd_client_set.set->dist_upload_start.fw_metadata->data, + src->dfd_client_set.set->dist_upload_start.fw_metadata->len); } - break; + break; case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB: if (src->dfd_client_set.set->dist_upload_oob_start.url == NULL || src->dfd_client_set.set->dist_upload_oob_start.fwid == NULL) { + BT_ERR("%s:%d,InvParam", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,InvParam", __func__, __LINE__); break; } dst->dfd_client_set.set->dist_upload_oob_start.url = bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_oob_start.url->len); if (dst->dfd_client_set.set->dist_upload_oob_start.url == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } dst->dfd_client_set.set->dist_upload_oob_start.fwid = bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_oob_start.fwid->len); if (dst->dfd_client_set.set->dist_upload_oob_start.fwid == NULL) { - bt_mesh_free(dst->dfd_client_set.params); - dst->dfd_client_set.params = NULL; - bt_mesh_free(dst->dfd_client_set.set); - dst->dfd_client_set.set = NULL; + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free_buf(dst->dfd_client_set.set->dist_upload_oob_start.url); dst->dfd_client_set.set->dist_upload_oob_start.url = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); - break; - } - net_buf_simple_add_mem( - dst->dfd_client_set.set->dist_upload_oob_start.url, - src->dfd_client_set.set->dist_upload_oob_start.url->data, - src->dfd_client_set.set->dist_upload_oob_start.url->len); - net_buf_simple_add_mem( - dst->dfd_client_set.set->dist_upload_oob_start.fwid, - src->dfd_client_set.set->dist_upload_oob_start.fwid->data, - src->dfd_client_set.set->dist_upload_oob_start.fwid->len); - break; - case ESP_BLE_MESH_DFD_OP_FW_DELETE: - if (src->dfd_client_set.set->dist_fw_del.fwid == NULL) { bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; + break; + } + net_buf_simple_add_mem(dst->dfd_client_set.set->dist_upload_oob_start.url, + src->dfd_client_set.set->dist_upload_oob_start.url->data, + src->dfd_client_set.set->dist_upload_oob_start.url->len); + net_buf_simple_add_mem(dst->dfd_client_set.set->dist_upload_oob_start.fwid, + src->dfd_client_set.set->dist_upload_oob_start.fwid->data, + src->dfd_client_set.set->dist_upload_oob_start.fwid->len); + break; + case ESP_BLE_MESH_DFD_OP_FW_DELETE: + if (src->dfd_client_set.set->dist_fw_del.fwid == NULL) { BT_ERR("%s:%d,InvParam", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->dfd_client_set.params); + dst->dfd_client_set.params = NULL; + bt_mesh_free(dst->dfd_client_set.set); + dst->dfd_client_set.set = NULL; break; } dst->dfd_client_set.set->dist_fw_del.fwid = bt_mesh_alloc_buf(src->dfd_client_set.set->dist_fw_del.fwid->len); if (dst->dfd_client_set.set->dist_fw_del.fwid == NULL) { + BT_ERR("%s:%d,OutMem", __func__, __LINE__); + /* Free the previously allocated resources */ bt_mesh_free(dst->dfd_client_set.params); dst->dfd_client_set.params = NULL; bt_mesh_free(dst->dfd_client_set.set); dst->dfd_client_set.set = NULL; - BT_ERR("%s:%d,OutMem", __func__, __LINE__); break; } - net_buf_simple_add_mem( - dst->dfd_client_set.set->dist_fw_del.fwid, - src->dfd_client_set.set->dist_fw_del.fwid->data, - src->dfd_client_set.set->dist_fw_del.fwid->len); - break; + net_buf_simple_add_mem(dst->dfd_client_set.set->dist_fw_del.fwid, + src->dfd_client_set.set->dist_fw_del.fwid->data, + src->dfd_client_set.set->dist_fw_del.fwid->len); + break; default: break; } @@ -923,133 +951,145 @@ void btc_ble_mesh_dfd_client_rsp_deep_copy(btc_msg_t *msg, void *p_dest, void *p } switch (msg->act) { - case ESP_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP: - switch(dst->params->opcode) { - case BLE_MESH_DFD_OP_RECEIVERS_LIST: - dst->status_cb.receiver_list.first_index = src->status_cb.receiver_list.first_index; - dst->status_cb.receiver_list.entries_cnt = src->status_cb.receiver_list.entries_cnt; - if (dst->status_cb.receiver_list.entries_cnt) { - dst->status_cb.receiver_list.entries = bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt); - if (dst->status_cb.receiver_list.entries == NULL) { - BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); - return; - } - memcpy(dst->status_cb.receiver_list.entries, src->status_cb.receiver_list.entries, - sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt); - } else { - dst->status_cb.receiver_list.entries = NULL; - } - break; - case BLE_MESH_DFD_OP_CAPABILITIES_STATUS: - dst->status_cb.dist_caps.max_receiver_list_sz = src->status_cb.dist_caps.max_receiver_list_sz; - dst->status_cb.dist_caps.max_fw_list_sz = src->status_cb.dist_caps.max_fw_list_sz; - dst->status_cb.dist_caps.max_fw_sz = src->status_cb.dist_caps.max_fw_sz; - dst->status_cb.dist_caps.max_upload_space = src->status_cb.dist_caps.max_upload_space; - dst->status_cb.dist_caps.remaining_upload_space = src->status_cb.dist_caps.remaining_upload_space; - dst->status_cb.dist_caps.oob_retrieval_supported = src->status_cb.dist_caps.oob_retrieval_supported; - if (src->status_cb.dist_caps.supported_url_scheme_names) { - dst->status_cb.dist_caps.supported_url_scheme_names = - bt_mesh_alloc_buf(src->status_cb.dist_caps.supported_url_scheme_names->len); - if (dst->status_cb.dist_caps.supported_url_scheme_names == NULL) { - BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); - return; - } - net_buf_simple_add_mem( - dst->status_cb.dist_caps.supported_url_scheme_names, - src->status_cb.dist_caps.supported_url_scheme_names->data, - src->status_cb.dist_caps.supported_url_scheme_names->len); - } else { - dst->status_cb.dist_caps.supported_url_scheme_names = NULL; - } - break; - case BLE_MESH_DFD_OP_UPLOAD_STATUS: - dst->status_cb.upload_status.status = src->status_cb.upload_status.status; - dst->status_cb.upload_status.upload_phase = src->status_cb.upload_status.upload_phase; - dst->status_cb.upload_status.upload_progress = src->status_cb.upload_status.upload_progress; - dst->status_cb.upload_status.upload_type = src->status_cb.upload_status.upload_type; - - if (dst->status_cb.upload_status.upload_progress == ESP_BLE_MESH_DFD_UPLOAD_PROGRESS_UNSET) { - dst->status_cb.upload_status.fwid = NULL; + case ESP_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP: + if (src->params) { + switch(src->params->opcode) { + case BLE_MESH_DFD_OP_RECEIVERS_LIST: + dst->status_cb.receiver_list.first_index = src->status_cb.receiver_list.first_index; + dst->status_cb.receiver_list.entries_cnt = src->status_cb.receiver_list.entries_cnt; + if (dst->status_cb.receiver_list.entries_cnt) { + dst->status_cb.receiver_list.entries = bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt); + if (dst->status_cb.receiver_list.entries == NULL) { + BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->params); + dst->params = NULL; return; } - - if (dst->status_cb.upload_status.upload_type == ESP_BLE_MESH_DFD_UPLOAD_TYPE_INBAND) { - if (src->status_cb.upload_status.fwid) { - dst->status_cb.upload_status.fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.fwid->len); - if (dst->status_cb.upload_status.fwid == NULL) { - BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); - return; - } - net_buf_simple_add_mem( - dst->status_cb.upload_status.fwid, - src->status_cb.upload_status.fwid->data, - src->status_cb.upload_status.fwid->len); - } else { - BT_ERR("%s:%d,InvParam", __func__, __LINE__); - } - } else { - if(src->status_cb.upload_status.oob_fwid) { - dst->status_cb.upload_status.oob_fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.oob_fwid->len); - if (dst->status_cb.upload_status.oob_fwid == NULL) { - BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); - return; - } - net_buf_simple_add_mem( - dst->status_cb.upload_status.oob_fwid, - src->status_cb.upload_status.oob_fwid->data, - src->status_cb.upload_status.oob_fwid->len); - } else { - BT_ERR("%s:%d,InvParam", __func__, __LINE__); - } - } + memcpy(dst->status_cb.receiver_list.entries, src->status_cb.receiver_list.entries, + sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt); + } else { + dst->status_cb.receiver_list.entries = NULL; + } break; - case BLE_MESH_DFD_OP_FW_STATUS: - dst->status_cb.firmware_status.status = src->status_cb.firmware_status.status; - dst->status_cb.firmware_status.entry_cnt = src->status_cb.firmware_status.entry_cnt; - dst->status_cb.firmware_status.fw_idx = src->status_cb.firmware_status.fw_idx; - if (src->status_cb.firmware_status.fwid) { - dst->status_cb.firmware_status.fwid = bt_mesh_alloc_buf(src->status_cb.firmware_status.fwid->len); - if (dst->status_cb.firmware_status.fwid == NULL) { + case BLE_MESH_DFD_OP_CAPABILITIES_STATUS: + dst->status_cb.dist_caps.max_receiver_list_sz = src->status_cb.dist_caps.max_receiver_list_sz; + dst->status_cb.dist_caps.max_fw_list_sz = src->status_cb.dist_caps.max_fw_list_sz; + dst->status_cb.dist_caps.max_fw_sz = src->status_cb.dist_caps.max_fw_sz; + dst->status_cb.dist_caps.max_upload_space = src->status_cb.dist_caps.max_upload_space; + dst->status_cb.dist_caps.remaining_upload_space = src->status_cb.dist_caps.remaining_upload_space; + dst->status_cb.dist_caps.oob_retrieval_supported = src->status_cb.dist_caps.oob_retrieval_supported; + if (src->status_cb.dist_caps.supported_url_scheme_names) { + dst->status_cb.dist_caps.supported_url_scheme_names = + bt_mesh_alloc_buf(src->status_cb.dist_caps.supported_url_scheme_names->len); + if (dst->status_cb.dist_caps.supported_url_scheme_names == NULL) { + BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->params); + dst->params = NULL; + return; + } + net_buf_simple_add_mem(dst->status_cb.dist_caps.supported_url_scheme_names, + src->status_cb.dist_caps.supported_url_scheme_names->data, + src->status_cb.dist_caps.supported_url_scheme_names->len); + } else { + dst->status_cb.dist_caps.supported_url_scheme_names = NULL; + } + break; + case BLE_MESH_DFD_OP_UPLOAD_STATUS: + dst->status_cb.upload_status.status = src->status_cb.upload_status.status; + dst->status_cb.upload_status.upload_phase = src->status_cb.upload_status.upload_phase; + dst->status_cb.upload_status.upload_progress = src->status_cb.upload_status.upload_progress; + dst->status_cb.upload_status.upload_type = src->status_cb.upload_status.upload_type; + + if (dst->status_cb.upload_status.upload_progress == ESP_BLE_MESH_DFD_UPLOAD_PROGRESS_UNSET) { + dst->status_cb.upload_status.fwid = NULL; + return; + } + + if (dst->status_cb.upload_status.upload_type == ESP_BLE_MESH_DFD_UPLOAD_TYPE_INBAND) { + if (src->status_cb.upload_status.fwid) { + dst->status_cb.upload_status.fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.fwid->len); + if (dst->status_cb.upload_status.fwid == NULL) { BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->params); + dst->params = NULL; return; } - net_buf_simple_add_mem( - dst->status_cb.firmware_status.fwid, - src->status_cb.firmware_status.fwid->data, - src->status_cb.firmware_status.fwid->len); + net_buf_simple_add_mem(dst->status_cb.upload_status.fwid, + src->status_cb.upload_status.fwid->data, + src->status_cb.upload_status.fwid->len); } else { - dst->status_cb.firmware_status.fwid = NULL; + BT_ERR("%s:%d,InvParam", __func__, __LINE__); } + } else { + if(src->status_cb.upload_status.oob_fwid) { + dst->status_cb.upload_status.oob_fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.oob_fwid->len); + if (dst->status_cb.upload_status.oob_fwid == NULL) { + BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->params); + dst->params = NULL; + return; + } + net_buf_simple_add_mem(dst->status_cb.upload_status.oob_fwid, + src->status_cb.upload_status.oob_fwid->data, + src->status_cb.upload_status.oob_fwid->len); + } else { + BT_ERR("%s:%d,InvParam", __func__, __LINE__); + } + } break; - case BLE_MESH_DFD_OP_RECEIVERS_STATUS: - dst->status_cb.receiver_status.status = src->status_cb.receiver_status.status; - dst->status_cb.receiver_status.receiver_list_cnt = src->status_cb.receiver_status.receiver_list_cnt; + case BLE_MESH_DFD_OP_FW_STATUS: + dst->status_cb.firmware_status.status = src->status_cb.firmware_status.status; + dst->status_cb.firmware_status.entry_cnt = src->status_cb.firmware_status.entry_cnt; + dst->status_cb.firmware_status.fw_idx = src->status_cb.firmware_status.fw_idx; + if (src->status_cb.firmware_status.fwid) { + dst->status_cb.firmware_status.fwid = bt_mesh_alloc_buf(src->status_cb.firmware_status.fwid->len); + if (dst->status_cb.firmware_status.fwid == NULL) { + BT_ERR("%s:%d,OutOfMem", __func__, __LINE__); + /* Free the previously allocated resources */ + bt_mesh_free(dst->params); + dst->params = NULL; + return; + } + net_buf_simple_add_mem(dst->status_cb.firmware_status.fwid, + src->status_cb.firmware_status.fwid->data, + src->status_cb.firmware_status.fwid->len); + } else { + dst->status_cb.firmware_status.fwid = NULL; + } break; - case BLE_MESH_DFD_OP_STATUS: - dst->status_cb.dist_status.status = src->status_cb.dist_status.status; - dst->status_cb.dist_status.dist_phase = src->status_cb.dist_status.dist_phase; - dst->status_cb.dist_status.multicast_address = src->status_cb.dist_status.multicast_address; - dst->status_cb.dist_status.appkey_idx = src->status_cb.dist_status.appkey_idx; - dst->status_cb.dist_status.ttl = src->status_cb.dist_status.ttl; - dst->status_cb.dist_status.timeout_base = src->status_cb.dist_status.timeout_base; - dst->status_cb.dist_status.trans_mode = src->status_cb.dist_status.trans_mode; - dst->status_cb.dist_status.update_policy = src->status_cb.dist_status.update_policy; - dst->status_cb.dist_status.firmware_image_index = src->status_cb.dist_status.firmware_image_index; + case BLE_MESH_DFD_OP_RECEIVERS_STATUS: + dst->status_cb.receiver_status.status = src->status_cb.receiver_status.status; + dst->status_cb.receiver_status.receiver_list_cnt = src->status_cb.receiver_status.receiver_list_cnt; break; - default: - BT_ERR("Unknown opcode %04x", dst->params->opcode); + case BLE_MESH_DFD_OP_STATUS: + dst->status_cb.dist_status.status = src->status_cb.dist_status.status; + dst->status_cb.dist_status.dist_phase = src->status_cb.dist_status.dist_phase; + dst->status_cb.dist_status.multicast_address = src->status_cb.dist_status.multicast_address; + dst->status_cb.dist_status.appkey_idx = src->status_cb.dist_status.appkey_idx; + dst->status_cb.dist_status.ttl = src->status_cb.dist_status.ttl; + dst->status_cb.dist_status.timeout_base = src->status_cb.dist_status.timeout_base; + dst->status_cb.dist_status.trans_mode = src->status_cb.dist_status.trans_mode; + dst->status_cb.dist_status.update_policy = src->status_cb.dist_status.update_policy; + dst->status_cb.dist_status.firmware_image_index = src->status_cb.dist_status.firmware_image_index; + break; + default: + BT_ERR("Unknown opcode %04x", dst->params->opcode); break; - } + } break; - case ESP_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT: + case ESP_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT: break; - case ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP: + case ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP: + break; + default: + BT_ERR("Unknown event %d", msg->act); break; - default: - BT_ERR("Unknown event %d", msg->act); } - } void btc_ble_mesh_dfd_client_rsp_deep_free(btc_msg_t *msg) diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c index 25fc238032..600ed02317 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c @@ -40,16 +40,25 @@ void btc_ble_mesh_lcd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_LCD_CLIENT_SEND: + dst->lcd_send.params = NULL; + dst->lcd_send.msg = NULL; + dst->lcd_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->lcd_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_lcd_client_msg_t)); - if (dst->lcd_send.params && dst->lcd_send.msg) { - memcpy(dst->lcd_send.params, src->lcd_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->lcd_send.msg, src->lcd_send.msg, - sizeof(esp_ble_mesh_lcd_client_msg_t)); - } else { + if (!dst->lcd_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + memcpy(dst->lcd_send.params, src->lcd_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + + dst->lcd_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_lcd_client_msg_t)); + if (!dst->lcd_send.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->lcd_send.params); + dst->lcd_send.params = NULL; + break; + } + memcpy(dst->lcd_send.msg, src->lcd_send.msg, sizeof(esp_ble_mesh_lcd_client_msg_t)); break; default: BT_DBG("%s, Unknown act %d", __func__, msg->act); @@ -115,6 +124,9 @@ static void btc_ble_mesh_lcd_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.large_comp_data_status.data = bt_mesh_alloc_buf(length); if (!p_dest_data->recv.large_comp_data_status.data) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } @@ -130,6 +142,9 @@ static void btc_ble_mesh_lcd_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.models_metadata_status.data = bt_mesh_alloc_buf(length); if (!p_dest_data->recv.models_metadata_status.data) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->params); + p_dest_data->params = NULL; return; } diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c index 52d89880a6..4f45592677 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c @@ -40,22 +40,26 @@ void btc_ble_mesh_odp_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_ODP_CLIENT_SEND: + dst->odp_send.params= NULL; + dst->odp_send.msg= NULL; + dst->odp_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - if (dst->odp_send.params) { - memcpy(dst->odp_send.params, src->odp_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - } else { + if (!dst->odp_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); break; } + memcpy(dst->odp_send.params, src->odp_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + if (src->odp_send.msg) { dst->odp_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_odp_client_msg_t)); - if (dst->odp_send.msg) { - memcpy(dst->odp_send.msg, src->odp_send.msg, - sizeof(esp_ble_mesh_odp_client_msg_t)); - } else { + if (!dst->odp_send.msg) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->odp_send.params); + dst->odp_send.params = NULL; + break; } + memcpy(dst->odp_send.msg, src->odp_send.msg, sizeof(esp_ble_mesh_odp_client_msg_t)); } break; default: diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c index 837fc79b57..48ce1cc606 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c @@ -45,22 +45,26 @@ void btc_ble_mesh_prb_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_PRB_CLIENT_SEND: - dst->prb_send.params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); - if (dst->prb_send.params) { - memcpy(dst->prb_send.params, src->prb_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - } else { + dst->prb_send.params = NULL; + dst->prb_send.msg = NULL; + + dst->prb_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); + if (!dst->prb_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); break; } + memcpy(dst->prb_send.params, src->prb_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + if (src->prb_send.msg) { - dst->prb_send.msg = bt_mesh_malloc(sizeof(esp_ble_mesh_prb_client_msg_t)); - if (dst->prb_send.msg) { - memcpy(dst->prb_send.msg, src->prb_send.msg, - sizeof(esp_ble_mesh_prb_client_msg_t)); - } else { + dst->prb_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_prb_client_msg_t)); + if (!dst->prb_send.msg) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->prb_send.params); + dst->prb_send.params = NULL; + break; } + memcpy(dst->prb_send.msg, src->prb_send.msg, sizeof(esp_ble_mesh_prb_client_msg_t)); } break; default: @@ -105,7 +109,7 @@ static void btc_ble_mesh_prb_client_copy_req_data(btc_msg_t *msg, void *p_dest, } if (p_src_data->params) { - p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t)); + p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (!p_dest_data->params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); return; diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c index e5200d7c3f..34e6929af7 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c @@ -47,17 +47,26 @@ void btc_ble_mesh_rpr_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_RPR_CLIENT_SEND: + dst->rpr_send.params = NULL; + dst->rpr_send.msg = NULL; + dst->rpr_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->rpr_send.msg = src->rpr_send.msg ? bt_mesh_calloc(sizeof(esp_ble_mesh_rpr_client_msg_t)) : NULL; - if (dst->rpr_send.params) { - memcpy(dst->rpr_send.params, src->rpr_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - if (dst->rpr_send.msg) { - memcpy(dst->rpr_send.msg, src->rpr_send.msg, - sizeof(esp_ble_mesh_rpr_client_msg_t)); - } - } else { + if (!dst->rpr_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; + } + memcpy(dst->rpr_send.params, src->rpr_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + + if (src->rpr_send.msg) { + dst->rpr_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_rpr_client_msg_t)); + if (!dst->rpr_send.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->rpr_send.params); + dst->rpr_send.params = NULL; + break; + } + memcpy(dst->rpr_send.msg, src->rpr_send.msg, sizeof(esp_ble_mesh_rpr_client_msg_t)); } break; case BTC_BLE_MESH_ACT_RPR_CLIENT_ACT: @@ -91,6 +100,9 @@ void btc_ble_mesh_rpr_client_arg_deep_free(btc_msg_t *msg) if (arg->rpr_send.params) { bt_mesh_free(arg->rpr_send.params); } + if (arg->rpr_send.msg) { + bt_mesh_free(arg->rpr_send.msg); + } break; case BTC_BLE_MESH_ACT_RPR_CLIENT_ACT: if (arg->rpr_act.param) { @@ -148,6 +160,9 @@ static void btc_ble_mesh_rpr_client_copy_req_data(btc_msg_t *msg, void *p_dest, p_dest_data->recv.val.ext_scan_report.adv_structures = bt_mesh_alloc_buf(length); if (!p_dest_data->recv.val.ext_scan_report.adv_structures) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(p_dest_data->recv.params); + p_dest_data->recv.params = NULL; return; } @@ -415,9 +430,10 @@ void btc_ble_mesh_rpr_client_call_handler(btc_msg_t *msg) btc_ble_mesh_rpr_client_cb(&cb, ESP_BLE_MESH_RPR_CLIENT_SEND_COMP_EVT); break; case BTC_BLE_MESH_ACT_RPR_CLIENT_ACT: - btc_ble_mesh_rpr_client_act(arg->rpr_act.type, - arg->rpr_act.param, &cb); - btc_ble_mesh_rpr_client_cb(&cb, ESP_BLE_MESH_RPR_CLIENT_ACT_COMP_EVT); + if (btc_ble_mesh_rpr_client_act(arg->rpr_act.type, + arg->rpr_act.param, &cb) == 0) { + btc_ble_mesh_rpr_client_cb(&cb, ESP_BLE_MESH_RPR_CLIENT_ACT_COMP_EVT); + } break; default: break; @@ -473,7 +489,6 @@ void btc_ble_mesh_rpr_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); } - bt_mesh_free(src->set_uuid_match.match_val); break; default: BT_DBG("%s, Unknown act %d", __func__, msg->act); diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c index 536d219cc0..06cdbd311f 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c @@ -42,6 +42,9 @@ void btc_ble_mesh_sar_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p switch (msg->act) { case BTC_BLE_MESH_ACT_SAR_CLIENT_SEND: + dst->sar_send.params = NULL; + dst->sar_send.msg = NULL; + dst->sar_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); if (dst->sar_send.params) { memcpy(dst->sar_send.params, src->sar_send.params, @@ -57,6 +60,9 @@ void btc_ble_mesh_sar_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p sizeof(esp_ble_mesh_sar_client_msg_t)); } else { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->sar_send.params); + dst->sar_send.params = NULL; } } break; diff --git a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c index 568c255cdb..1181311016 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c +++ b/components/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c @@ -39,16 +39,25 @@ void btc_ble_mesh_srpl_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void * switch (msg->act) { case BTC_BLE_MESH_ACT_SRPL_CLIENT_SEND: + dst->srpl_send.params = NULL; + dst->srpl_send.msg = NULL; + dst->srpl_send.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t)); - dst->srpl_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_srpl_client_msg_t)); - if (dst->srpl_send.params && dst->srpl_send.msg) { - memcpy(dst->srpl_send.params, src->srpl_send.params, - sizeof(esp_ble_mesh_client_common_param_t)); - memcpy(dst->srpl_send.msg, src->srpl_send.msg, - sizeof(esp_ble_mesh_srpl_client_msg_t)); - } else { + if (!dst->srpl_send.params) { BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + break; } + memcpy(dst->srpl_send.params, src->srpl_send.params, sizeof(esp_ble_mesh_client_common_param_t)); + + dst->srpl_send.msg = bt_mesh_calloc(sizeof(esp_ble_mesh_srpl_client_msg_t)); + if (!dst->srpl_send.msg) { + BT_ERR("%s, Out of memory, act %d", __func__, msg->act); + /* Free the previously allocated resources */ + bt_mesh_free(dst->srpl_send.params); + dst->srpl_send.params = NULL; + break; + } + memcpy(dst->srpl_send.msg, src->srpl_send.msg, sizeof(esp_ble_mesh_srpl_client_msg_t)); break; default: BT_DBG("%s, Unknown act %d", __func__, msg->act); diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfd_srv.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfd_srv.c index 955419ef1f..288741aab2 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfd_srv.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfd_srv.c @@ -172,7 +172,11 @@ static int handle_receivers_get(const struct bt_mesh_model *mod, struct bt_mesh_ net_buf_simple_add_le16(&rsp, srv->target_cnt); net_buf_simple_add_le16(&rsp, first); - cnt = MIN(cnt, srv->target_cnt - first); + if (first >= srv->target_cnt) { + cnt = 0; + } else { + cnt = MIN(cnt, srv->target_cnt - first); + } progress = bt_mesh_dfu_cli_progress(&srv->dfu) / 2; for (i = 0; i < cnt && net_buf_simple_tailroom(&rsp) >= 5 + BLE_MESH_MIC_SHORT; i++) { @@ -207,7 +211,14 @@ static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_me { size_t size = 0; +#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD + struct bt_mesh_dfd_srv *srv = mod->user_data; + assert(srv); + + BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_CAPABILITIES_GET, 17 + srv->oob_schemes.count); +#else BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_CAPABILITIES_GET, 17); +#endif bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_CAPABILITIES_GET); net_buf_simple_add_le16(&rsp, CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX); @@ -222,8 +233,6 @@ static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_me net_buf_simple_add_le32(&rsp, CONFIG_BLE_MESH_DFD_SRV_SLOT_SPACE - size); #ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD - struct bt_mesh_dfd_srv *srv = mod->user_data; - if (srv->oob_schemes.count > 0) { net_buf_simple_add_u8(&rsp, 1); net_buf_simple_add_mem(&rsp, srv->oob_schemes.schemes, @@ -522,8 +531,10 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, meta, meta_len); switch (err) { case -EFBIG: + bt_mesh_dfu_slot_release(srv->upload.slot); + srv->upload.slot = NULL; upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL); - break; + return 0; case 0: break; default: @@ -637,6 +648,8 @@ static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_me if (status != BLE_MESH_DFD_SUCCESS) { upload_status_rsp(srv, ctx, status); bt_mesh_dfu_slot_release(srv->upload.slot); + srv->upload.slot = NULL; + srv->upload.is_oob = false; } else { srv->upload.is_pending_oob_check = true; } @@ -679,7 +692,7 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv, net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_count()); net_buf_simple_add_le16(&rsp, idx); - if (fwid) { + if (fwid && fwid_len <= CONFIG_BLE_MESH_DFU_FWID_MAXLEN) { net_buf_simple_add_mem(&rsp, fwid, fwid_len); } @@ -696,6 +709,11 @@ static int handle_fw_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx int idx; fwid_len = buf->len; + if (fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) { + fw_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL, 0xffff, NULL, 0); + return 0; + } + fwid = net_buf_simple_pull_mem(buf, fwid_len); idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot); @@ -741,9 +759,11 @@ static int handle_fw_delete(const struct bt_mesh_model *mod, struct bt_mesh_msg_ fwid_len = buf->len; fwid = net_buf_simple_pull_mem(buf, fwid_len); + int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, NULL); enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_fw_delete(srv, &fwid_len, &fwid); - fw_status_rsp(srv, ctx, status, 0xffff, fwid, fwid_len); + uint16_t rsp_idx = (status == BLE_MESH_DFD_SUCCESS && idx >= 0) ? (uint16_t)idx : 0xffff; + fw_status_rsp(srv, ctx, status, rsp_idx, fwid, fwid_len); return 0; } diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c index b4d1b90c9d..04efc7ed4e 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c @@ -146,6 +146,10 @@ static struct bt_mesh_dfu_target *target_get(struct bt_mesh_dfu_cli *cli, { struct bt_mesh_dfu_target *target; + if (!cli || !cli->blob.inputs) { + return NULL; + } + TARGETS_FOR_EACH(cli, target) { if (addr == target->blob.addr) { return target; @@ -181,11 +185,14 @@ static void req_timeout_handler(struct k_work *work) req->dfu_cli->mod, &ctx, NULL, 0); } - bt_mesh_dfu_cli_rm_req_from_list(req); - if (req->params) { - bt_mesh_free(req->params); + if (req) { + bt_mesh_dfu_cli_rm_req_from_list(req); + if (req->params) { + bt_mesh_free(req->params); + } + /* Timer has already been freed */ + bt_mesh_free(req); } - req_free(req); bt_mesh_r_mutex_unlock(&dfu_req_list.op_lock); } @@ -193,7 +200,7 @@ static bt_mesh_dfu_cli_req_t* req_alloc(void) { bt_mesh_dfu_cli_req_t *req = bt_mesh_calloc(sizeof(bt_mesh_dfu_cli_req_t)); if (!req) { - BT_ERR("device firmware client allocl failed"); + BT_ERR("device firmware client alloc failed"); return NULL; } @@ -210,6 +217,9 @@ static int req_free(bt_mesh_dfu_cli_req_t *req) return -EINVAL; } + if (req->params) { + bt_mesh_free(req->params); + } k_delayed_work_free(&req->timer); bt_mesh_free(req); return 0; @@ -708,7 +718,6 @@ static void skip_targets_from_broadcast(struct bt_mesh_dfu_cli *cli, bool skip) if (bt_mesh_has_addr(target->blob.addr) || target->phase == BLE_MESH_DFU_PHASE_VERIFY) { target->blob.skip = skip; - break; } } } @@ -718,7 +727,7 @@ static bool transfer_skip(struct bt_mesh_dfu_cli *cli) struct bt_mesh_dfu_target *target; TARGETS_FOR_EACH(cli, target) { - if (!bt_mesh_has_addr(target->blob.addr) || !target->blob.skip) { + if (!bt_mesh_has_addr(target->blob.addr) && !target->blob.skip) { return false; } } @@ -883,7 +892,10 @@ static void confirmed(struct bt_mesh_blob_cli *b) struct bt_mesh_dfu_target *target; bool success = false; - cli->req->img_cb = NULL; + if (cli->req) { + cli->req->img_cb = NULL; + cli->req = NULL; + } TARGETS_FOR_EACH(cli, target) { if (target->status != BLE_MESH_DFU_SUCCESS) { @@ -994,7 +1006,6 @@ static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx bt_mesh_dfu_client_cb_evt_to_btc(req->opcode, BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP, req->dfu_cli->mod, &req->ctx, req->params, sizeof(struct bt_mesh_dfu_target_status)); - bt_mesh_free(req->params); bt_mesh_dfu_cli_rm_req_from_list(req); k_delayed_work_cancel(&req->timer); req_free(req); @@ -1194,7 +1205,7 @@ static int handle_info_status(const struct bt_mesh_model *mod, struct bt_mesh_ms } else { if (req->img_cb) { // used to notify cb function the image output finished - req->img_cb(cli, ctx, idx, img_cnt, NULL, NULL); + req->img_cb(cli, ctx, idx, img_cnt, NULL, req->params); } } @@ -1257,7 +1268,6 @@ static int handle_metadata_status(const struct bt_mesh_model *mod, struct bt_mes req->dfu_cli->mod, &req->ctx, req->params, sizeof(struct bt_mesh_dfu_metadata_status)); - bt_mesh_free(rsp); bt_mesh_dfu_cli_rm_req_from_list(req); req_free(req); @@ -1415,16 +1425,20 @@ int bt_mesh_dfu_cli_cancel(struct bt_mesh_dfu_cli *cli, cli->req = req; err = req_setup(cli, REQ_STATUS, BLE_MESH_DFU_OP_UPDATE_CANCEL, ctx, NULL); if (err) { + req_free(req); + cli->req = NULL; return err; } - bt_mesh_dfu_cli_add_req_to_list(req); + /* bt_mesh_dfu_cli_add_req_to_list(req); */ BLE_MESH_MODEL_BUF_DEFINE(buf, BLE_MESH_DFU_OP_UPDATE_CANCEL, 0); bt_mesh_model_msg_init(&buf, BLE_MESH_DFU_OP_UPDATE_CANCEL); err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); if (err) { - cli->req->type = REQ_NONE; + /* cli->req->type = REQ_NONE; */ + req_free(req); + cli->req = NULL; return err; } @@ -1455,6 +1469,7 @@ int bt_mesh_dfu_cli_apply(struct bt_mesh_dfu_cli *cli) int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli) { bt_mesh_dfu_cli_req_t *req = NULL; + int err = 0; if (cli->xfer.state != STATE_APPLIED) { return -EBUSY; @@ -1462,12 +1477,22 @@ int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli) req = req_alloc(); if (!req) { - BT_ERR("%s: alloc req failed", req); + BT_ERR("alloc req failed"); return -ENOMEM; } cli->req = req; - req_setup(cli, INTERNAL_REQ_IMG, BLE_MESH_DFU_OP_UPDATE_INFO_GET, NULL, NULL); + err = req_setup(cli, INTERNAL_REQ_IMG, BLE_MESH_DFU_OP_UPDATE_INFO_GET, NULL, NULL); + if (err) { + req_free(req); + cli->req = NULL; + return err; + } + if (!is_valid_req(req)) { + req_free(req); + cli->req = NULL; + return -EINVAL; + } bt_mesh_dfu_cli_add_req_to_list(req); cli->xfer.state = STATE_CONFIRM; @@ -1478,7 +1503,8 @@ int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli) uint8_t bt_mesh_dfu_cli_progress(struct bt_mesh_dfu_cli *cli) { - if (cli->xfer.state == STATE_TRANSFER) { + if (cli->xfer.state == STATE_TRANSFER || + cli->xfer.state == STATE_SUSPENDED) { return bt_mesh_blob_cli_xfer_progress_active_get(&cli->blob); } @@ -1555,11 +1581,15 @@ int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli, } req = req_alloc(); if (!req) { + bt_mesh_free(rsp); return -ENOMEM; } cli->req = req; err = req_setup(cli, REQ_METADATA, BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK, ctx, rsp); if (err) { + bt_mesh_free(rsp); + req_free(cli->req); + cli->req = NULL; return err; } @@ -1577,7 +1607,10 @@ int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli, err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); if (err) { - cli->req->type = REQ_NONE; + /* cli->req->type = REQ_NONE; */ + /* rsp will be freed in req_free() */ + req_free(cli->req); + cli->req = NULL; return err; } @@ -1598,11 +1631,15 @@ int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli, req = req_alloc(); if (!req) { + bt_mesh_free(rsp); return -ENOMEM; } cli->req = req; err = req_setup(cli, REQ_STATUS, BLE_MESH_DFU_OP_UPDATE_GET, ctx, rsp); if (err) { + bt_mesh_free(rsp); + req_free(cli->req); + cli->req = NULL; return err; } @@ -1611,7 +1648,10 @@ int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli, err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL); if (err) { - cli->req->type = REQ_NONE; + /* cli->req->type = REQ_NONE; */ + /* rsp will be freed in req_free() */ + req_free(cli->req); + cli->req = NULL; return err; } diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_metadata.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_metadata.c index 9c966c5e38..e43d177ee7 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_metadata.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_metadata.c @@ -9,8 +9,10 @@ #include "crypto.h" #include "access.h" +#include "transport.h" #include "mesh/byteorder.h" #include "mesh/buf.h" +#include "mesh_v1.1/utils.h" #include "mesh_v1.1/dfu/dfu_metadata.h" #if CONFIG_BLE_MESH_DFU_METADATA @@ -62,8 +64,10 @@ int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata, net_buf_simple_add_le32(buf, metadata->fw_ver.build_num); net_buf_simple_add_le24(buf, metadata->fw_size); net_buf_simple_add_u8(buf, metadata->fw_core_type); - net_buf_simple_add_le32(buf, metadata->comp_hash); - net_buf_simple_add_le16(buf, metadata->elems); + if (metadata->fw_core_type & BLE_MESH_DFU_FW_CORE_TYPE_APP) { + net_buf_simple_add_le32(buf, metadata->comp_hash); + net_buf_simple_add_le16(buf, metadata->elems); + } if (metadata->user_data_len > 0) { net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len); diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_slot.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_slot.c index 76f3a87e81..ada89913bb 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_slot.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_slot.c @@ -285,6 +285,7 @@ int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *dfu_slot) } int idx = ARRAY_INDEX(slots, slot); + ARG_UNUSED(idx); BT_DBG("%u", idx); diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c b/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c index 4e47629f85..a5d36d8fa8 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c @@ -1127,7 +1127,7 @@ static void progress_checked(struct bt_mesh_blob_cli *cli) cli->state = BT_MESH_BLOB_CLI_STATE_NONE; - if (cli->cb && cli->cb->end) { + if (cli->cb && cli->cb->xfer_progress_complete) { cli->cb->xfer_progress_complete(cli); } } @@ -1269,8 +1269,11 @@ static int handle_xfer_status(const struct bt_mesh_model *mod, struct bt_mesh_ms info.mode = status_and_mode >> 6; info.phase = net_buf_simple_pull_u8(buf); - if (buf->len) { + if (buf->len >= 8) { info.id = net_buf_simple_pull_le64(buf); + } else if (buf->len > 0) { + BT_WARN("Invalid ID field length: %u", buf->len); + return -EINVAL; } if (buf->len >= 7) { @@ -1278,6 +1281,9 @@ static int handle_xfer_status(const struct bt_mesh_model *mod, struct bt_mesh_ms info.block_size_log = net_buf_simple_pull_u8(buf); info.mtu_size = net_buf_simple_pull_le16(buf); info.missing_blocks = net_buf_simple_pull(buf, buf->len); + } else if (buf->len > 0) { + BT_WARN("Invalid extended field length: %u", buf->len); + return -EINVAL; } BT_DBG("status: %u %s phase: %u %s", info.status, @@ -1358,8 +1364,9 @@ static int handle_block_report(const struct bt_mesh_model *mod, struct bt_mesh_m int idx; idx = chunk_idx_decode(buf); - if (idx < 0) { - return idx; + if (idx < 0 || idx >= cli->block.chunk_count) { + BT_ERR("Invalid encoding"); + return -EINVAL; } blob_chunk_missing_set(status.block.missing, idx, true); @@ -1401,6 +1408,10 @@ static int handle_block_status(const struct bt_mesh_model *mod, struct bt_mesh_m status.missing = status_and_format >> 6; status.block.number = net_buf_simple_pull_le16(buf); chunk_size = net_buf_simple_pull_le16(buf); + if (chunk_size == 0) { + BT_ERR("Invalid chunk_size: 0"); + return -EINVAL; + } status.block.chunk_count = DIV_ROUND_UP(cli->block.size, chunk_size); @@ -1638,6 +1649,7 @@ int bt_mesh_blob_cli_suspend(struct bt_mesh_blob_cli *cli) return -EINVAL; } + io_close(cli); cli->state = BT_MESH_BLOB_CLI_STATE_SUSPENDED; (void)k_work_cancel_delayable(&cli->tx.retry); cli->tx.ctx.is_inited = 0; @@ -1668,8 +1680,8 @@ int bt_mesh_blob_cli_resume(struct bt_mesh_blob_cli *cli) return -ENODEV; } - block_set(cli, 0); - return xfer_start(cli); + block_start(cli); + return 0; } void bt_mesh_blob_cli_cancel(struct bt_mesh_blob_cli *cli) @@ -1683,6 +1695,9 @@ void bt_mesh_blob_cli_cancel(struct bt_mesh_blob_cli *cli) if (cli->state == BT_MESH_BLOB_CLI_STATE_CAPS_GET || cli->state == BT_MESH_BLOB_CLI_STATE_SUSPENDED) { + if (cli->state == BT_MESH_BLOB_CLI_STATE_SUSPENDED) { + io_close(cli); + } cli_state_reset(cli); return; } @@ -1715,7 +1730,7 @@ int bt_mesh_blob_cli_xfer_progress_get(struct bt_mesh_blob_cli *cli, uint8_t bt_mesh_blob_cli_xfer_progress_active_get(struct bt_mesh_blob_cli *cli) { - if (cli->state < BT_MESH_BLOB_CLI_STATE_START) { + if (cli->state < BT_MESH_BLOB_CLI_STATE_START || cli->block_count == 0) { return 0; } diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c index b0237f299f..0dca96fb9e 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c @@ -65,22 +65,26 @@ static inline uint32_t block_count_get(const struct bt_mesh_blob_srv *srv) static inline uint32_t max_chunk_size(const struct bt_mesh_blob_srv *srv) { - return MIN((srv->state.mtu_size - 2 - BLE_MESH_MODEL_OP_LEN(BT_MESH_BLOB_OP_CHUNK)), - BLOB_RX_CHUNK_SIZE); + uint8_t op_len = BLE_MESH_MODEL_OP_LEN(BT_MESH_BLOB_OP_CHUNK); + return ((srv->state.mtu_size >= 2 + op_len) ? + MIN((srv->state.mtu_size - 2 - op_len), BLOB_RX_CHUNK_SIZE) : 0); } static inline uint32_t max_chunk_count(const struct bt_mesh_blob_srv *srv) { return MIN(8 * (srv->state.mtu_size - 6), - CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX); + MAX(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX, 1U)); } static inline uint32_t missing_chunks(const struct bt_mesh_blob_block *block) { int i; uint32_t count = 0; + uint32_t size = 0; - for (i = 0; i < ARRAY_SIZE(block->missing); ++i) { + size = MIN(DIV_ROUND_UP(block->chunk_count, 8), ARRAY_SIZE(block->missing)); + + for (i = 0; i < size; ++i) { count += popcount(block->missing[i]); } @@ -117,7 +121,7 @@ static int io_open(struct bt_mesh_blob_srv *srv) static void io_close(struct bt_mesh_blob_srv *srv) { - if (!srv->io->close) { + if (!srv->io || !srv->io->close) { return; } @@ -624,8 +628,8 @@ static int handle_block_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ break; case BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START: case BT_MESH_BLOB_XFER_PHASE_INACTIVE: - status = BT_MESH_BLOB_ERR_WRONG_PHASE; - break; + xfer_status_rsp(srv, ctx, BT_MESH_BLOB_ERR_WRONG_PHASE); + return 0; default: status = BT_MESH_BLOB_ERR_INTERNAL; break; @@ -1070,6 +1074,9 @@ uint8_t bt_mesh_blob_srv_progress(const struct bt_mesh_blob_srv *srv) } total = block_count_get(srv); + if (total == 0) { + return 100U; + } received = 0; for (int i = 0; i < total; ++i) {